Browse Source

Merge branch 'master' of brain.opensimulator.org:/var/git/opensim

root 5 years ago
parent
commit
c7a02dc058
61 changed files with 2110 additions and 1112 deletions
  1. 4 1
      OpenSim/Data/MySQL/MySQLSimulationData.cs
  2. 4 1
      OpenSim/Data/PGSQL/PGSQLSimulationData.cs
  3. 4 1
      OpenSim/Data/SQLite/SQLiteSimulationData.cs
  4. 42 23
      OpenSim/Framework/ClientManager.cs
  5. 1 2
      OpenSim/Framework/IClientAPI.cs
  6. 19 13
      OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
  7. 0 1
      OpenSim/Framework/TerrainData.cs
  8. 0 28
      OpenSim/Framework/Util.cs
  9. 22 17
      OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs
  10. 16 7
      OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
  11. 687 124
      OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
  12. 39 51
      OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
  13. 163 187
      OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
  14. 0 37
      OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
  15. 279 0
      OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs
  16. 79 103
      OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
  17. 0 9
      OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
  18. 11 3
      OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
  19. 2 7
      OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
  20. 0 28
      OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
  21. 11 4
      OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
  22. 155 98
      OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
  23. 15 10
      OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
  24. 20 3
      OpenSim/Region/CoreModules/World/Estate/EstateModule.cs
  25. 1 0
      OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
  26. 4 8
      OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
  27. 3 3
      OpenSim/Region/Framework/Scenes/EventManager.cs
  28. 68 96
      OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
  29. 1 3
      OpenSim/Region/Framework/Scenes/SceneGraph.cs
  30. 1 1
      OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
  31. 19 14
      OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
  32. 4 4
      OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
  33. 34 16
      OpenSim/Region/Framework/Scenes/ScenePresence.cs
  34. 2 0
      OpenSim/Region/Framework/Scenes/TerrainCompressor.cs
  35. 2 2
      OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs
  36. 15 9
      OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs
  37. 1 1
      OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs
  38. 3 0
      OpenSim/Region/PhysicsModules/BulletS/BSParam.cs
  39. 7 2
      OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
  40. 13 53
      OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
  41. 93 33
      OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
  42. 4 9
      OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs
  43. 12 9
      OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
  44. 1 1
      OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
  45. 32 12
      OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
  46. 3 1
      OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
  47. 16 3
      OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
  48. 1 4
      OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs
  49. 4 1
      OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs
  50. 15 2
      OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs
  51. 6 6
      OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs
  52. 9 0
      OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs
  53. 9 0
      OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs
  54. 4 0
      OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs
  55. 18 0
      OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs
  56. 44 6
      OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs
  57. 8 0
      OpenSim/Services/LLLoginService/LLLoginService.cs
  58. BIN
      bin/OpenMetaverse.dll
  59. 20 21
      bin/OpenSimDefaults.ini
  60. 58 32
      bin/ScriptSyntax.xml
  61. 2 2
      bin/config-include/osslEnable.ini

+ 4 - 1
OpenSim/Data/MySQL/MySQLSimulationData.cs

@@ -1403,7 +1403,10 @@ namespace OpenSim.Data.MySQL
 
             prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString());
             prim.SoundGain = (float)(double)row["LoopedSoundGain"];
-            prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            if (prim.Sound != UUID.Zero)
+                prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            else
+                prim.SoundFlags = 0;
 
             if (!(row["TextureAnimation"] is DBNull))
                 prim.TextureAnimation = (byte[])row["TextureAnimation"];

+ 4 - 1
OpenSim/Data/PGSQL/PGSQLSimulationData.cs

@@ -1742,7 +1742,10 @@ namespace OpenSim.Data.PGSQL
 
             prim.Sound = new UUID((Guid)primRow["LoopedSound"]);
             prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]);
-            prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            if (prim.Sound != UUID.Zero)
+                prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            else
+                prim.SoundFlags = 0;
 
             if (!(primRow["TextureAnimation"] is DBNull))
                 prim.TextureAnimation = (Byte[])primRow["TextureAnimation"];

+ 4 - 1
OpenSim/Data/SQLite/SQLiteSimulationData.cs

@@ -1742,7 +1742,10 @@ namespace OpenSim.Data.SQLite
 
             prim.Sound = new UUID(row["LoopedSound"].ToString());
             prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
-            prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            if (prim.Sound != UUID.Zero)
+                prim.SoundFlags = 1; // If it's persisted at all, it's looped
+            else
+                prim.SoundFlags = 0;
 
             if (!row.IsNull("TextureAnimation"))
                 prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());

+ 42 - 23
OpenSim/Framework/ClientManager.cs

@@ -51,7 +51,14 @@ namespace OpenSim.Framework
         private object m_syncRoot = new object();
 
         /// <summary>Number of clients in the collection</summary>
-        public int Count { get { return m_dict1.Count; } }
+        public int Count
+        {
+            get
+            {
+                lock (m_syncRoot) 
+                    return m_dict1.Count;
+            }
+        }
 
         /// <summary>
         /// Default constructor
@@ -60,7 +67,7 @@ namespace OpenSim.Framework
         {
             m_dict1 = new Dictionary<UUID, IClientAPI>();
             m_dict2 = new Dictionary<IPEndPoint, IClientAPI>();
-            m_array = new IClientAPI[0];
+            m_array = null;
         }
 
         /// <summary>
@@ -74,17 +81,9 @@ namespace OpenSim.Framework
         {
             lock (m_syncRoot)
             {
-                // allow self healing
-//                if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint))
-//                    return false;
-
                 m_dict1[value.AgentId] = value;
                 m_dict2[value.RemoteEndPoint] = value;
-
-                // dict1 is the master
-                IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
-                m_dict1.Values.CopyTo(newArray, 0);
-                m_array = newArray;
+                m_array = null;
             }
 
             return true;
@@ -105,10 +104,7 @@ namespace OpenSim.Framework
                 {
                     m_dict1.Remove(key);
                     m_dict2.Remove(value.RemoteEndPoint);
-
-                    IClientAPI[] newArray = new IClientAPI[m_dict1.Count];
-                    m_dict1.Values.CopyTo(newArray, 0);
-                    m_array = newArray;
+                    m_array = null;
                     return true;
                 }
             }
@@ -124,7 +120,7 @@ namespace OpenSim.Framework
             {
                 m_dict1.Clear();
                 m_dict2.Clear();
-                m_array = new IClientAPI[0];
+                m_array = null;
             }
         }
 
@@ -135,7 +131,8 @@ namespace OpenSim.Framework
         /// <returns>True if the UUID was found in the collection, otherwise false</returns>
         public bool ContainsKey(UUID key)
         {
-            return m_dict1.ContainsKey(key);
+            lock (m_syncRoot)
+                return m_dict1.ContainsKey(key);
         }
 
         /// <summary>
@@ -145,7 +142,8 @@ namespace OpenSim.Framework
         /// <returns>True if the endpoint was found in the collection, otherwise false</returns>
         public bool ContainsKey(IPEndPoint key)
         {
-            return m_dict2.ContainsKey(key);
+            lock (m_syncRoot)
+                return m_dict2.ContainsKey(key);
         }
 
         /// <summary>
@@ -156,8 +154,12 @@ namespace OpenSim.Framework
         /// <returns>True if the lookup succeeded, otherwise false</returns>
         public bool TryGetValue(UUID key, out IClientAPI value)
         {
-            try { return m_dict1.TryGetValue(key, out value); }
-            catch (Exception)
+            try
+            {
+                lock (m_syncRoot)
+                    return m_dict1.TryGetValue(key, out value);
+            }
+            catch
             {
                 value = null;
                 return false;
@@ -172,8 +174,12 @@ namespace OpenSim.Framework
         /// <returns>True if the lookup succeeded, otherwise false</returns>
         public bool TryGetValue(IPEndPoint key, out IClientAPI value)
         {
-            try { return m_dict2.TryGetValue(key, out value); }
-            catch (Exception)
+            try
+            {
+                lock (m_syncRoot)
+                    return m_dict2.TryGetValue(key, out value);
+            }
+            catch
             {
                 value = null;
                 return false;
@@ -187,7 +193,20 @@ namespace OpenSim.Framework
         /// <param name="action">Action to perform on each element</param>
         public void ForEach(Action<IClientAPI> action)
         {
-            IClientAPI[] localArray = m_array;
+            IClientAPI[] localArray;
+            lock (m_syncRoot)
+            {
+                if (m_array == null)
+                {
+                    if (m_dict1.Count == 0)
+                        return;
+
+                    m_array = new IClientAPI[m_dict1.Count];
+                    m_dict1.Values.CopyTo(m_array, 0);
+                }
+                localArray = m_array;
+            }
+
             for (int i = 0; i < localArray.Length; i++)
                 action(localArray[i]);
         }

+ 1 - 2
OpenSim/Framework/IClientAPI.cs

@@ -390,7 +390,7 @@ namespace OpenSim.Framework
         IClientAPI remoteClient, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics);
 
     public delegate void EstateTeleportOneUserHomeRequest(
-        IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey);
+        IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey, bool kill);
 
     public delegate void EstateTeleportAllUsersHomeRequest(IClientAPI remoteClient, UUID invoice, UUID senderID);
 
@@ -671,7 +671,6 @@ namespace OpenSim.Framework
         Particles = 1 << 19,
         ExtraData = 1 << 20,
         Sound = 1 << 21,
-        Joint = 1 << 22,
 
         TerseUpdate = Position | Rotation | Velocity | Acceleration | AngularVelocity,
         FullUpdate =    0x00ffffff,

+ 19 - 13
OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs

@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) Contributors, http://opensimulator.org/
  * See CONTRIBUTORS.TXT for a full list of copyright holders.
  *
@@ -230,25 +230,25 @@ namespace OpenSim.Framework.Servers.HttpServer
             PollServiceHttpRequest req;
             while (m_running)
             {
-                req = null;
-                if(!m_requests.TryTake(out req, 4500) || req == null)
+                try
                 {
-                    Watchdog.UpdateThread();
-                    continue;
-                }
+                    req = null;
+                    if (!m_requests.TryTake(out req, 4500) || req == null)
+                    {
+                        Watchdog.UpdateThread();
+                        continue;
+                    }
 
-                Watchdog.UpdateThread();
+                    Watchdog.UpdateThread();
 
-                try
-                {
-                    if(!req.HttpContext.CanSend())
+                    if (!req.HttpContext.CanSend())
                     {
                         req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id);
                         byContextDequeue(req);
                         continue;
                     }
 
-                    if(req.HttpContext.IsSending())
+                    if (req.HttpContext.IsSending())
                     {
                         if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
                         {
@@ -256,7 +256,7 @@ namespace OpenSim.Framework.Servers.HttpServer
                             byContextDequeue(req);
                         }
                         else
-                          ReQueueEvent(req);
+                            ReQueueEvent(req);
                         continue;
                     }
 
@@ -290,7 +290,7 @@ namespace OpenSim.Framework.Servers.HttpServer
                                 {
                                     nreq.DoHTTPGruntWork(nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id));
                                 }
-                                catch (ObjectDisposedException) {}
+                                catch (ObjectDisposedException) { }
                                 finally
                                 {
                                     byContextDequeue(nreq);
@@ -305,6 +305,12 @@ namespace OpenSim.Framework.Servers.HttpServer
                         }
                     }
                 }
+                catch (ThreadAbortException)
+                {
+                    Thread.ResetAbort();
+                    // Shouldn't set this to 'false', the normal shutdown should cause things to exit
+                    // m_running = false;
+                }
                 catch (Exception e)
                 {
                     m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());

+ 0 - 1
OpenSim/Framework/TerrainData.cs

@@ -212,7 +212,6 @@ namespace OpenSim.Framework
             return heights;
         }
 
-        // TerrainData.GetDoubles
         public double[,] GetDoubles()
         {
             double[,] ret = new double[SizeX, SizeY];

+ 0 - 28
OpenSim/Framework/Util.cs

@@ -2437,34 +2437,6 @@ namespace OpenSim.Framework
 
         #region FireAndForget Threading Pattern
 
-        /// <summary>
-        /// Created to work around a limitation in Mono with nested delegates
-        /// </summary>
-        private sealed class FireAndForgetWrapper
-        {
-            private static object syncRoot = new Object();
-
-            public void FireAndForget(System.Threading.WaitCallback callback)
-            {
-                callback.BeginInvoke(null, EndFireAndForget, callback);
-            }
-
-            public void FireAndForget(System.Threading.WaitCallback callback, object obj)
-            {
-                callback.BeginInvoke(obj, EndFireAndForget, callback);
-            }
-
-            private static void EndFireAndForget(IAsyncResult ar)
-            {
-                System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
-
-                try { callback.EndInvoke(ar); }
-                catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
-
-                ar.AsyncWaitHandle.Close();
-            }
-        }
-
         public static void InitThreadPool(int minThreads, int maxThreads)
         {
             if (maxThreads < 2)

+ 22 - 17
OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs

@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.Linden
         private string m_GetTextureURL;
         private string m_GetMeshURL;
         private string m_GetMesh2URL;
-//        private string m_GetAssetURL;
+        private string m_GetAssetURL;
 
         class APollRequest
         {
@@ -87,7 +87,7 @@ namespace OpenSim.Region.ClientStack.Linden
         private Dictionary<UUID, string> m_capsDictTexture = new Dictionary<UUID, string>();
         private Dictionary<UUID, string> m_capsDictGetMesh = new Dictionary<UUID, string>();
         private Dictionary<UUID, string> m_capsDictGetMesh2 = new Dictionary<UUID, string>();
-        //private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>();
+        private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>();
 
         #region Region Module interfaceBase Members
 
@@ -113,11 +113,11 @@ namespace OpenSim.Region.ClientStack.Linden
             m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty);
             if (m_GetMesh2URL != string.Empty)
                 m_Enabled = true;
-/*
+
             m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty);
             if (m_GetAssetURL != string.Empty)
                 m_Enabled = true;
-*/
+
         }
 
         public void AddRegion(Scene pScene)
@@ -204,19 +204,26 @@ namespace OpenSim.Region.ClientStack.Linden
 
         private static void DoAssetRequests()
         {
-            while (m_NumberScenes > 0)
+            try
             {
-                APollRequest poolreq;
-                if(m_queue.TryTake(out poolreq, 4500))
+                while (m_NumberScenes > 0)
                 {
-                    if (m_NumberScenes <= 0)
-                        break;
+                    APollRequest poolreq;
+                    if (m_queue.TryTake(out poolreq, 4500))
+                    {
+                        if (m_NumberScenes <= 0)
+                            break;
+                        Watchdog.UpdateThread();
+                        if (poolreq.reqID != UUID.Zero)
+                            poolreq.thepoll.Process(poolreq);
+                        poolreq = null;
+                    }
                     Watchdog.UpdateThread();
-                    if (poolreq.reqID != UUID.Zero)
-                        poolreq.thepoll.Process(poolreq);
-                    poolreq = null;
                 }
-                Watchdog.UpdateThread();
+            }
+            catch (ThreadAbortException)
+            {
+                Thread.ResetAbort();
             }
         }
 
@@ -441,7 +448,6 @@ namespace OpenSim.Region.ClientStack.Linden
             else if (m_GetMesh2URL != string.Empty)
                 caps.RegisterHandler("GetMesh2", m_GetMesh2URL);
 
-/* we can't support this cap. Current viewers connect to the wrong regions.
             //ViewerAsset
             if (m_GetAssetURL == "localhost")
             {
@@ -459,7 +465,7 @@ namespace OpenSim.Region.ClientStack.Linden
             }
             else if (m_GetAssetURL != string.Empty)
                 caps.RegisterHandler("ViewerAsset", m_GetMesh2URL);
-*/
+
         }
 
         private void DeregisterCaps(UUID agentID, Caps caps)
@@ -480,13 +486,12 @@ namespace OpenSim.Region.ClientStack.Linden
                 MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
                 m_capsDictGetMesh2.Remove(agentID);
             }
-/*
+
             if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl))
             {
                 MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl);
                 m_capsDictGetAsset.Remove(agentID);
             }
-*/
         }
     }
 }

+ 16 - 7
OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs

@@ -395,17 +395,26 @@ namespace OpenSim.Region.ClientStack.Linden
 
         private static void DoInventoryRequests()
         {
-            while (true)
+            bool running = true;
+            while (running)
             {
-                APollRequest poolreq;
-                if (m_queue.TryTake(out poolreq, 4500))
+                try
                 {
+                    APollRequest poolreq;
+                    if (m_queue.TryTake(out poolreq, 4500))
+                    {
+                        Watchdog.UpdateThread();
+                        if (poolreq.thepoll != null)
+                            poolreq.thepoll.Process(poolreq);
+                        poolreq = null;
+                    }
                     Watchdog.UpdateThread();
-                    if (poolreq.thepoll != null)
-                        poolreq.thepoll.Process(poolreq);
-                    poolreq = null;
                 }
-                Watchdog.UpdateThread();
+                catch (ThreadAbortException)
+                {
+                    Thread.ResetAbort();
+                    running = false;
+                }
             }
         }
     }

File diff suppressed because it is too large
+ 687 - 124
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs


+ 39 - 51
OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs

@@ -120,7 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// <summary>Circuit code that this client is connected on</summary>
         public readonly uint CircuitCode;
         /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
-        public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
+        public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(256);
 
         /// <summary>Packets we have sent that need to be ACKed by the client</summary>
         public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
@@ -210,12 +210,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             }
         }
 
-        /// <summary>
-        /// This is the percentage of the udp texture queue to add to the task queue since
-        /// textures are now generally handled through http.
-        /// </summary>
-        private double m_cannibalrate = 0.0;
-
         private ClientInfo m_info = new ClientInfo();
 
         /// <summary>
@@ -257,8 +251,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             // Create an array of token buckets for this clients different throttle categories
             m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
 
-            m_cannibalrate = rates.CannibalizeTextureRate;
-
             m_burst = rates.Total * rates.BrustTime;
 
             for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
@@ -449,12 +441,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             asset = Math.Max(asset, LLUDPServer.MTU);
 */
 
-            // Since most textures are now delivered through http, make it possible
-            // to cannibalize some of the bw from the texture throttle to use for
-            // the task queue (e.g. object updates)
-            task = task + (int)(m_cannibalrate * texture);
-            texture = (int)((1 - m_cannibalrate) * texture);
-
             int total = resend + land + wind + cloud + task + texture + asset;
 
             float m_burst = total * m_burstTime;
@@ -575,22 +561,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             {
                 DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
 
-                if (m_deliverPackets == false)
+                if (forceQueue || m_deliverPackets == false)
                 {
                     queue.Enqueue(packet, highPriority);
                     return true;
                 }
 
-                TokenBucket bucket = m_throttleCategories[category];
-
-                // Don't send this packet if queue is not empty
+                // need to enqueue if queue is not empty
                 if (queue.Count > 0 || m_nextPackets[category] != null)
                 {
                     queue.Enqueue(packet, highPriority);
                     return true;
                 }
 
-                if (!forceQueue && bucket.CheckTokens(packet.Buffer.DataLength))
+                // check bandwidth
+                TokenBucket bucket = m_throttleCategories[category];
+                if (bucket.CheckTokens(packet.Buffer.DataLength))
                 {
                     // enough tokens so it can be sent imediatly by caller
                     bucket.RemoveTokens(packet.Buffer.DataLength);
@@ -608,7 +594,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 // We don't have a token bucket for this category, so it will not be queued
                 return false;
             }
-
         }
 
         /// <summary>
@@ -650,6 +635,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     // leaving a dequeued packet still waiting to be sent out. Try to
                     // send it again
                     OutgoingPacket nextPacket = m_nextPackets[i];
+                    if(nextPacket.Buffer == null)
+                    {
+                        if (m_packetOutboxes[i].Count < 5)
+                            emptyCategories |= CategoryToFlag(i);
+                        continue;
+                    }
                     if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
                     {
                         // Send the packet
@@ -681,21 +672,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                         {
                             // A packet was pulled off the queue. See if we have
                             // enough tokens in the bucket to send it out
-                            if (bucket.RemoveTokens(packet.Buffer.DataLength))
+                            if(packet.Buffer == null)
                             {
-                                // Send the packet
-                                m_udpServer.SendPacketFinal(packet);
-                                packetSent = true;
-
+                                // packet canceled elsewhere (by a ack for example)
                                 if (queue.Count < 5)
                                     emptyCategories |= CategoryToFlag(i);
                             }
                             else
                             {
-                                // Save the dequeued packet for the next iteration
-                                m_nextPackets[i] = packet;
+                                if (bucket.RemoveTokens(packet.Buffer.DataLength))
+                                {
+                                    // Send the packet
+                                    m_udpServer.SendPacketFinal(packet);
+                                    packetSent = true;
+
+                                    if (queue.Count < 5)
+                                        emptyCategories |= CategoryToFlag(i);
+                                }
+                                else
+                                {
+                                    // Save the dequeued packet for the next iteration
+                                    m_nextPackets[i] = packet;
+                                }
                             }
-
                         }
                         else
                         {
@@ -803,8 +802,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             }
         }
 
-
-
         /// <summary>
         /// Fires the OnQueueEmpty callback and sets the minimum time that it
         /// can be called again
@@ -843,6 +840,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 return 0;
         }
 
+        public void FreeUDPBuffer(UDPPacketBuffer buf)
+        {
+            m_udpServer.FreeUDPBuffer(buf);
+        }
+
         /// <summary>
         /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
         /// flag value
@@ -853,34 +855,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         {
             ThrottleOutPacketType category = (ThrottleOutPacketType)i;
 
-            /*
-             * Land = 1,
-        /// <summary>Wind data</summary>
-        Wind = 2,
-        /// <summary>Cloud data</summary>
-        Cloud = 3,
-        /// <summary>Any packets that do not fit into the other throttles</summary>
-        Task = 4,
-        /// <summary>Texture assets</summary>
-        Texture = 5,
-        /// <summary>Non-texture assets</summary>
-        Asset = 6,
-             */
-
             switch (category)
             {
                 case ThrottleOutPacketType.Land:
-                    return ThrottleOutPacketTypeFlags.Land;
+                    return ThrottleOutPacketTypeFlags.Land; // Terrain data
                 case ThrottleOutPacketType.Wind:
-                    return ThrottleOutPacketTypeFlags.Wind;
+                    return ThrottleOutPacketTypeFlags.Wind; // Wind data
                 case ThrottleOutPacketType.Cloud:
-                    return ThrottleOutPacketTypeFlags.Cloud;
+                    return ThrottleOutPacketTypeFlags.Cloud; // Cloud data
                 case ThrottleOutPacketType.Task:
-                    return ThrottleOutPacketTypeFlags.Task;
+                    return ThrottleOutPacketTypeFlags.Task; // Object updates and everything not on the other categories
                 case ThrottleOutPacketType.Texture:
-                    return ThrottleOutPacketTypeFlags.Texture;
+                    return ThrottleOutPacketTypeFlags.Texture; // Textures data (also impacts http texture and mesh by default)
                 case ThrottleOutPacketType.Asset:
-                    return ThrottleOutPacketTypeFlags.Asset;
+                    return ThrottleOutPacketTypeFlags.Asset; // Non-texture Assets data
                 default:
                     return 0;
             }

+ 163 - 187
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs

@@ -256,6 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
         /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
         public const int MTU = 1400;
+        public const int MAXPAYLOAD = 1250;
 
         /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
         public int ClientLogoutsDueToNoReceives { get; protected set; }
@@ -274,10 +275,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// <summary>The measured resolution of Environment.TickCount</summary>
         public readonly float TickCountResolution;
 
-        /// <summary>Number of prim updates to put on the queue each time the
-        /// OnQueueEmpty event is triggered for updates</summary>
-        public readonly int PrimUpdatesPerCallback;
-
         /// <summary>Number of texture packets to put on the queue each time the
         /// OnQueueEmpty event is triggered for textures</summary>
         public readonly int TextureSendLimit;
@@ -344,18 +341,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
         protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
 
-        protected Pool<IncomingPacket> m_incomingPacketPool;
-
-        /// <summary>
-        /// Stat for number of packets in the main pool awaiting use.
-        /// </summary>
-        protected Stat m_poolCountStat;
-
-        /// <summary>
-        /// Stat for number of packets in the inbound packet pool awaiting use.
-        /// </summary>
-        protected Stat m_incomingPacketPoolStat;
-
         protected int m_defaultRTO = 0;
         protected int m_maxRTO = 0;
         protected int m_ackTimeout = 0;
@@ -452,7 +437,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
                 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
 
-                PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
                 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
 
                 m_defaultRTO = config.GetInt("DefaultRTO", 0);
@@ -463,7 +447,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             }
             else
             {
-                PrimUpdatesPerCallback = 100;
                 TextureSendLimit = 20;
                 m_ackTimeout = 1000 * 60; // 1 minute
                 m_pausedAckTimeout = 1000 * 300; // 5 minutes
@@ -498,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
 //            if (usePools)
 //                EnablePools();
-            base.DisablePools();
         }
 
         public void Start()
@@ -554,83 +536,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             OqrEngine.Stop();
         }
 
-        public override bool EnablePools()
-        {
-            if (!UsePools)
-            {
-                base.EnablePools();
-
-                m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
-
-                return true;
-            }
-
-            return false;
-        }
-
-        public override bool DisablePools()
-        {
-            if (UsePools)
-            {
-                base.DisablePools();
-
-                StatsManager.DeregisterStat(m_incomingPacketPoolStat);
-
-                // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
-
-                return true;
-            }
-
-            return false;
-        }
-
-        /// <summary>
-        /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
-        /// stats.
-        /// </summary>
-        protected internal void EnablePoolStats()
-        {
-            m_poolCountStat
-                = new Stat(
-                    "UDPPacketBufferPoolCount",
-                    "Objects within the UDPPacketBuffer pool",
-                    "The number of objects currently stored within the UDPPacketBuffer pool",
-                    "",
-                    "clientstack",
-                    Scene.Name,
-                    StatType.Pull,
-                    stat => stat.Value = Pool.Count,
-                    StatVerbosity.Debug);
-
-            StatsManager.RegisterStat(m_poolCountStat);
-
-            m_incomingPacketPoolStat
-                = new Stat(
-                    "IncomingPacketPoolCount",
-                    "Objects within incoming packet pool",
-                    "The number of objects currently stored within the incoming packet pool",
-                    "",
-                    "clientstack",
-                    Scene.Name,
-                    StatType.Pull,
-                    stat => stat.Value = m_incomingPacketPool.Count,
-                    StatVerbosity.Debug);
-
-            StatsManager.RegisterStat(m_incomingPacketPoolStat);
-        }
-
-        /// <summary>
-        /// Disables pool stats.
-        /// </summary>
-        protected internal void DisablePoolStats()
-        {
-            StatsManager.DeregisterStat(m_poolCountStat);
-            m_poolCountStat = null;
-
-            StatsManager.DeregisterStat(m_incomingPacketPoolStat);
-            m_incomingPacketPoolStat = null;
-        }
-
          /// <summary>
         /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
         /// </summary>
@@ -658,8 +563,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
                     "INCOMING PACKET ASYNC HANDLING ENGINE");
 */
-            OqrEngine
-                = new JobEngine(
+            OqrEngine = new JobEngine(
                     string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
                     "OUTGOING QUEUE REFILL ENGINE");
 
@@ -769,15 +673,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     stat => stat.Value = OqrEngine.JobsWaiting,
                     StatVerbosity.Debug));
 
-            // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
-            // scene name
-            if (UsePools)
-                EnablePoolStats();
-
+            StatsManager.RegisterStat(
+                new Stat(
+                    "UDPBuffersPoolCount",
+                    "Buffers in the UDP buffers pool",
+                    "The number of buffers currently stored within the UDP buffers pool",
+                    "",
+                    "clientstack",
+                    Scene.Name,
+                    StatType.Pull,
+                    stat => stat.Value = m_udpBuffersPoolPtr + 1,
+                    StatVerbosity.Debug));
 
             LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
             commands.Register();
-
         }
 
         public bool HandlesRegion(Location x)
@@ -939,9 +848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
             // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
             // to accomodate for both common scenarios and provide ample room for ACK appending in both
-            int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
+            //int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
 
-            UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
+            //UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
+            UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
 
             // Zerocode if needed
             if (doZerocode)
@@ -971,7 +881,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             // If the packet data wasn't already copied during zerocoding, copy it now
             if (doCopy)
             {
-                if (dataLength <= buffer.Data.Length)
+                //if (dataLength <= buffer.Data.Length)
+                if (dataLength <= LLUDPServer.MTU)
                 {
                     Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
                 }
@@ -979,7 +890,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 {
                     m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
                         type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
-                    buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength);
+                    // buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength);
+                    buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
                     Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
                 }
             }
@@ -1017,6 +929,89 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             #endregion Queue or Send
         }
 
+        public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input)
+        {
+            UDPPacketBuffer zb = GetNewUDPBuffer(null);
+            int srclen = input.DataLength;
+            byte[] src = input.Data;
+            byte[] dest = zb.Data;
+
+            int zerolen = 6;
+            byte zerocount = 0;
+
+            for (int i = zerolen; i < srclen; i++)
+            {
+                if (src[i] == 0x00)
+                {
+                    zerocount++;
+                    if (zerocount == 0)
+                    {
+                        dest[zerolen++] = 0x00;
+                        dest[zerolen++] = 0xff;
+                        zerocount++;
+                    }
+                }
+                else
+                {
+                    if (zerocount != 0)
+                    {
+                        dest[zerolen++] = 0x00;
+                        dest[zerolen++] = zerocount;
+                        zerocount = 0;
+                    }
+
+                    dest[zerolen++] = src[i];
+                }
+            }
+
+            if (zerocount != 0)
+            {
+                dest[zerolen++] = 0x00;
+                dest[zerolen++] = zerocount;
+            }
+
+            if(zerolen >= srclen)
+            {
+                FreeUDPBuffer(zb);
+
+                src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED);
+                return input;
+            }
+
+            Buffer.BlockCopy(src, 0, dest, 0, 6);
+
+            zb.RemoteEndPoint = input.RemoteEndPoint;
+            zb.DataLength = zerolen;
+
+            FreeUDPBuffer(input);
+
+            return zb;
+        }
+
+        public void SendUDPPacket(
+            LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode)
+        {
+            bool highPriority = false;
+
+            if(zerocode)
+                buffer = ZeroEncode(buffer);
+
+            if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
+            {
+                category = (ThrottleOutPacketType)((int)category & 127);
+                highPriority = true;
+            }
+
+            OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
+
+            // If we were not provided a method for handling unacked, use the UDPServer default method
+            if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
+                outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
+
+            if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority))
+                SendPacketFinal(outgoingPacket);
+        }
+
         public void SendAcks(LLUDPClient udpClient)
         {
             uint ack;
@@ -1066,7 +1061,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         {
             LLUDPClient udpClient = client.UDPClient;
 
-            if (!udpClient.IsConnected)
+            if (!client.IsActive || !udpClient.IsConnected)
                 return;
 
             // Disconnect an agent if no packets are received for some time
@@ -1136,14 +1131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         internal void SendPacketFinal(OutgoingPacket outgoingPacket)
         {
             UDPPacketBuffer buffer = outgoingPacket.Buffer;
+            if(buffer == null) // canceled packet
+                return;
+            LLUDPClient udpClient = outgoingPacket.Client;
+            if (!udpClient.IsConnected)
+                return;
+
             byte flags = buffer.Data[0];
             bool isResend = (flags & Helpers.MSG_RESENT) != 0;
             bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;
             bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0;
-            LLUDPClient udpClient = outgoingPacket.Client;
-
-            if (!udpClient.IsConnected)
-                return;
 
             int dataLength = buffer.DataLength;
 
@@ -1154,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 // no more ACKs to append
                 int ackCount = 0;
                 uint ack;
-                while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack))
+                while (dataLength + 5 < MTU && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack))
                 {
                     Utils.UIntToBytesBig(ack, buffer.Data, dataLength);
                     dataLength += 4;
@@ -1168,22 +1165,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     // Set the appended ACKs flag on this packet
                     buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS);
                 }
+                buffer.DataLength = dataLength;
             }
 
-            buffer.DataLength = dataLength;
-
             if (!isResend)
             {
                 // Not a resend, assign a new sequence number
                 uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence);
                 Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1);
                 outgoingPacket.SequenceNumber = sequenceNumber;
-
-                if (isReliable)
-                {
-                    // Add this packet to the list of ACK responses we are waiting on from the server
-                    udpClient.NeedAcks.Add(outgoingPacket);
-                }
             }
             else
             {
@@ -1196,9 +1186,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             PacketsSentCount++;
 
             SyncSend(buffer);
+
             // Keep track of when this packet was sent out (right now)
             outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
 
+            if (outgoingPacket.UnackedMethod == null)
+                FreeUDPBuffer(buffer);
+            else if(!isResend)
+            {
+                // Add this packet to the list of ACK responses we are waiting on from the server
+                udpClient.NeedAcks.Add(outgoingPacket);
+            }
+
             if (udpClient.DebugDataOutLevel > 0)
                 m_log.DebugFormat(
                     "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
@@ -1240,7 +1239,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 //                    buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
 
                 RecordMalformedInboundPacket(endPoint);
-
+                FreeUDPBuffer(buffer);
                 return; // Drop undersized packet
             }
 
@@ -1260,21 +1259,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 //                    buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
 
                 RecordMalformedInboundPacket(endPoint);
-
+                FreeUDPBuffer(buffer);
                 return; // Malformed header
             }
 
             try
             {
-//                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
-//                    // Only allocate a buffer for zerodecoding if the packet is zerocoded
-//                    ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
+                // get a buffer for zero decode using the udp buffers pool
+                UDPPacketBuffer zerodecodebufferholder = null;
+                byte[] zerodecodebuffer = null;
+                // only if needed
+                if (((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0))
+                {
+                    zerodecodebufferholder = GetNewUDPBuffer(null);
+                    zerodecodebuffer = zerodecodebufferholder.Data;
+                }
+
+                packet = Packet.BuildPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
                 // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
                 // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
                 // bytes are copied out).
-                packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
-                    // Only allocate a buffer for zerodecoding if the packet is zerocoded
-                    ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
+                // packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, zerodecodebuffer);
+                if(zerodecodebufferholder != null)
+                    FreeUDPBuffer(zerodecodebufferholder);
             }
             catch (Exception e)
             {
@@ -1292,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 }
 
                 RecordMalformedInboundPacket(endPoint);
-
+                FreeUDPBuffer(buffer);
                 return;
             }
 
@@ -1311,17 +1318,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     lock (m_pendingCache)
                     {
                         if (m_pendingCache.Contains(endPoint))
+                        {
+                            FreeUDPBuffer(buffer);
                             return;
+                        }
 
                         m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
                     }
 
-                    // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
-                    // buffer.
-                    object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
-
-                    Util.FireAndForget(HandleUseCircuitCode, array);
-
+                    Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet });
+                    FreeUDPBuffer(buffer);
                     return;
                 }
             }
@@ -1336,24 +1342,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     queue.Enqueue(buffer);
                     return;
                 }
-
-/*
-                else if (packet.Type == PacketType.CompleteAgentMovement)
-                {
-                    // Send ack straight away to let the viewer know that we got it.
-                    SendAckImmediate(endPoint, packet.Header.Sequence);
-
-                    // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
-                    // buffer.
-                    object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
-
-                    Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
-
-                    return;
-                }
- */
             }
 
+            FreeUDPBuffer(buffer);
+
             // Determine which agent this packet came from
             if (client == null || !(client is LLClientView))
             {
@@ -1471,10 +1463,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
             #endregion BinaryStats
 
-
-//AgentUpdate removed from here
-
-
             #region Ping Check Handling
 
             if (packet.Type == PacketType.StartPingCheck)
@@ -1506,17 +1494,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
             IncomingPacket incomingPacket;
 
-            // Inbox insertion
-            if (UsePools)
-            {
-                incomingPacket = m_incomingPacketPool.GetObject();
-                incomingPacket.Client = (LLClientView)client;
-                incomingPacket.Packet = packet;
-            }
-            else
-            {
-                incomingPacket = new IncomingPacket((LLClientView)client, packet);
-            }
+            incomingPacket = new IncomingPacket((LLClientView)client, packet);
 
 //            if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
 //                incomingPacket.Packet.Type == PacketType.ChatFromViewer)
@@ -1525,7 +1503,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 //            else
 //                packetInbox.Enqueue(incomingPacket);
             packetInbox.Add(incomingPacket);
-
         }
 
         #region BinaryStats
@@ -1685,7 +1662,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                         {
                             m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
                             return;
-
                         }
                         m_pendingCache.Remove(endPoint);
                     }
@@ -1881,13 +1857,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             byte[] packetData = ack.ToBytes();
             int length = packetData.Length;
 
-            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
+            UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint);
             buffer.DataLength = length;
 
             Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);
 
 //            AsyncBeginSend(buffer);
             SyncSend(buffer);
+            FreeUDPBuffer(buffer);
         }
 
         protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo)
@@ -1982,21 +1959,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 Scene.ThreadAlive(1);
                 try
                 {
-                    packetInbox.TryTake(out incomingPacket, 250);
+                    packetInbox.TryTake(out incomingPacket, 4500);
 
                     if (incomingPacket != null && IsRunningInbound)
                     {
                         ProcessInPacket(incomingPacket);
-
-                        if (UsePools)
-                        {
-                            incomingPacket.Client = null;
-                            m_incomingPacketPool.ReturnObject(incomingPacket);
-                        }
                         incomingPacket = null;
                     }
                 }
-                catch(Exception ex)
+                catch (ThreadAbortException)
+                {
+                    Thread.ResetAbort();
+                }
+                catch (Exception ex)
                 {
                     m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
                 }
@@ -2025,7 +2000,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             {
                 Scene.ThreadAlive(2);
 
-
                 try
                 {
                     m_packetSent = false;
@@ -2080,7 +2054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     }
                     else if (!m_packetSent)
 //                        Thread.Sleep((int)TickCountResolution);  outch this is bad on linux
-                        Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms.
+                        Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms.
 
                     Watchdog.UpdateThread();
                 }
@@ -2104,14 +2078,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
                     if (udpClient.IsConnected)
                     {
-                        if (m_resendUnacked)
+                        if (client.IsActive && m_resendUnacked)
                             HandleUnacked(llClient);
 
-                        if (m_sendAcks)
-                            SendAcks(udpClient);
+                        if (client.IsActive)
+                        {
+                            if (m_sendAcks)
+                                SendAcks(udpClient);
 
-                        if (m_sendPing)
-                            SendPing(udpClient);
+                            if (m_sendPing)
+                                SendPing(udpClient);
+                        }
 
                         // Dequeue any outgoing packets that are within the throttle limits
                         if (udpClient.DequeueOutgoing())
@@ -2124,7 +2101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 m_log.Error(
                     string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
             }
-            client = null;
         }
 
         #region Emergency Monitoring

+ 0 - 37
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs

@@ -777,41 +777,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 m_udpServer.StopOutbound();
         }
 
-        private void HandlePoolCommand(string module, string[] args)
-        {
-            if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
-                return;
-
-            if (args.Length != 4)
-            {
-                MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
-                return;
-            }
-
-            string enabled = args[3];
-
-            if (enabled == "on")
-            {
-                if (m_udpServer.EnablePools())
-                {
-                    m_udpServer.EnablePoolStats();
-                    MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
-                }
-            }
-            else if (enabled == "off")
-            {
-                if (m_udpServer.DisablePools())
-                {
-                    m_udpServer.DisablePoolStats();
-                    MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
-                }
-            }
-            else
-            {
-                MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
-            }
-        }
-
         private void HandleAgentUpdateCommand(string module, string[] args)
         {
             if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
@@ -834,8 +799,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             MainConsole.Instance.OutputFormat(
                 "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
 
-            MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
-
             MainConsole.Instance.OutputFormat(
                 "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
         }

+ 279 - 0
OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs

@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSimulator Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using Nini.Config;
+using OpenMetaverse;
+
+namespace OpenSim.Region.ClientStack.LindenUDP
+{
+    public sealed class LLUDPZeroEncoder
+    {
+        private byte[] m_tmp = new byte[16];
+        private byte[] m_dest;
+        private int zerocount;
+        private int pos;
+
+        public LLUDPZeroEncoder()
+        {
+        }
+
+        public LLUDPZeroEncoder(byte[] data)
+        {
+            m_dest = data;
+            zerocount = 0;
+        }
+
+        public byte[] Data
+        {
+            get
+            {
+                return m_dest;
+            }
+            set
+            {
+                m_dest = value;
+            }
+        }
+
+        public int ZeroCount
+        {
+            get
+            {
+                return zerocount;
+            }
+            set
+            {
+                zerocount = value;
+            }
+        }
+
+        public int Position
+        {
+            get
+            {
+                return pos;
+            }
+            set
+            {
+                pos = value;
+            }
+        }
+
+        public unsafe void AddZeros(int len)
+        {
+            zerocount += len;
+            while (zerocount > 255)
+            {
+                m_dest[pos++] = 0x00;
+                m_dest[pos++] = 0xff;
+                zerocount -= 256;
+            }
+        }
+
+        public unsafe int Finish()
+        {
+            if(zerocount > 0)
+            {
+                m_dest[pos++] = 0x00;
+                m_dest[pos++] = (byte)zerocount;
+            }
+            return pos;
+        }
+
+        public unsafe void AddBytes(byte[] src, int srclen)
+        {
+            for (int i = 0; i < srclen; ++i)
+            {
+                if (src[i] == 0x00)
+                {
+                    zerocount++;
+                    if (zerocount == 0)
+                    {
+                        m_dest[pos++] = 0x00;
+                        m_dest[pos++] = 0xff;
+                        zerocount++;
+                    }
+                }
+                else
+                {
+                    if (zerocount != 0)
+                    {
+                        m_dest[pos++] = 0x00;
+                        m_dest[pos++] = (byte)zerocount;
+                        zerocount = 0;
+                    }
+
+                    m_dest[pos++] = src[i];
+                }
+            }
+        }
+
+        public unsafe void AddByte(byte v)
+        {
+            if (v == 0x00)
+            {
+                zerocount++;
+                if (zerocount == 0)
+                {
+                    m_dest[pos++] = 0x00;
+                    m_dest[pos++] = 0xff;
+                    zerocount++;
+                }
+            }
+            else
+            {
+                if (zerocount != 0)
+                {
+                    m_dest[pos++] = 0x00;
+                    m_dest[pos++] = (byte)zerocount;
+                    zerocount = 0;
+                }
+
+                m_dest[pos++] = v;
+            }
+        }
+
+        public void AddInt16(short v)
+        {
+            if (v == 0)
+                AddZeros(2);
+            else
+            {
+                Utils.Int16ToBytes(v, m_tmp, 0);
+                AddBytes(m_tmp, 2);
+            }
+        }
+
+        public void AddUInt16(ushort v)
+        {
+            if (v == 0)
+                AddZeros(2);
+            else
+            {
+                Utils.UInt16ToBytes(v, m_tmp, 0);
+                AddBytes(m_tmp, 2);
+            }
+        }
+
+        public void AddInt(int v)
+        {
+            if (v == 0)
+                AddZeros(4);
+            else
+            {
+                Utils.IntToBytesSafepos(v, m_tmp, 0);
+                AddBytes(m_tmp, 4);
+            }
+        }
+
+        public unsafe void AddUInt(uint v)
+        {
+            if (v == 0)
+                AddZeros(4);
+            else
+            {
+                Utils.UIntToBytesSafepos(v, m_tmp, 0);
+                AddBytes(m_tmp, 4);
+            }
+        }
+
+        public void AddFloatToUInt16(float v, float range)
+        {
+            Utils.FloatToUInt16Bytes(v, range, m_tmp, 0);
+            AddBytes(m_tmp, 2);
+        }
+
+        public void AddFloat(float v)
+        {
+            if (v == 0f)
+                AddZeros(4);
+            else
+            {
+                Utils.FloatToBytesSafepos(v, m_tmp, 0);
+                AddBytes(m_tmp, 4);
+            }
+        }
+
+        public void AddInt64(long v)
+        {
+            if (v == 0)
+                AddZeros(8);
+            else
+            {
+                Utils.Int64ToBytesSafepos(v, m_tmp, 0);
+                AddBytes(m_tmp, 8);
+            }
+        }
+
+        public void AddUInt64(ulong v)
+        {
+            if (v == 0)
+                AddZeros(8);
+            else
+            {
+                Utils.UInt64ToBytesSafepos(v, m_tmp, 0);
+                AddBytes(m_tmp, 8);
+            }
+        }
+
+        public void AddVector3(Vector3 v)
+        {
+            if (v == Vector3.Zero)
+                AddZeros(12);
+            else
+            {
+                v.ToBytes(m_tmp, 0);
+                AddBytes(m_tmp, 12);
+            }
+        }
+
+        public void AddVector4(Vector4 v)
+        {
+            if (v == Vector4.Zero)
+                AddZeros(16);
+            else
+            {
+                v.ToBytes(m_tmp, 0);
+                AddBytes(m_tmp, 16);
+            }
+        }
+
+        public void AddNormQuat(Quaternion v)
+        {
+            v.ToBytes(m_tmp, 0);
+            AddBytes(m_tmp, 12);
+        }
+
+        public void AddUUID(UUID v)
+        {
+            v.ToBytes(m_tmp, 0);
+            AddBytes(m_tmp, 16);
+        }
+    }
+}

+ 79 - 103
OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs

@@ -26,6 +26,7 @@
  */
 
 using System;
+using System.Collections.Concurrent;
 using System.Net;
 using System.Net.Sockets;
 using System.Threading;
@@ -57,15 +58,9 @@ namespace OpenMetaverse
         /// <summary>UDP socket, used in either client or server mode</summary>
         private Socket m_udpSocket;
 
-        /// <summary>
-        /// Are we to use object pool(s) to reduce memory churn when receiving data?
-        /// </summary>
-        public bool UsePools { get; protected set; }
-
-        /// <summary>
-        /// Pool to use for handling data.  May be null if UsePools = false;
-        /// </summary>
-        protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
+        public static Object m_udpBuffersPoolLock = new Object();
+        public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000];
+        public static int m_udpBuffersPoolPtr = -1;
 
         /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
         public bool IsRunningInbound { get; private set; }
@@ -186,6 +181,37 @@ namespace OpenMetaverse
             if(m_udpSocket !=null)
                 try { m_udpSocket.Close(); } catch { }
         }
+
+        public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint)
+        {
+            lock (m_udpBuffersPoolLock)
+            {
+                if (m_udpBuffersPoolPtr >= 0)
+                {
+                    UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr];
+                    m_udpBuffersPool[m_udpBuffersPoolPtr] = null;
+                    m_udpBuffersPoolPtr--;
+                    buf.RemoteEndPoint = remoteEndpoint;
+                    return buf;
+                }
+            }
+            return new UDPPacketBuffer(remoteEndpoint);
+        }
+
+        public void FreeUDPBuffer(UDPPacketBuffer buf)
+        {
+            lock (m_udpBuffersPoolLock)
+            {
+                if (m_udpBuffersPoolPtr < 999)
+                {
+                    buf.RemoteEndPoint = null;
+                    buf.DataLength = 0;
+                    m_udpBuffersPoolPtr++;
+                    m_udpBuffersPool[m_udpBuffersPoolPtr] = buf;
+                }
+            }
+        }
+
         /// <summary>
         /// Start inbound UDP packet handling.
         /// </summary>
@@ -202,6 +228,7 @@ namespace OpenMetaverse
         /// manner (not throwing an exception when the remote side resets the
         /// connection). This call is ignored on Mono where the flag is not
         /// necessary</remarks>
+
         public virtual void StartInbound(int recvBufferSize)
         {
             if (!IsRunningInbound)
@@ -306,102 +333,56 @@ namespace OpenMetaverse
             IsRunningOutbound = false;
         }
 
-        public virtual bool EnablePools()
+        private void AsyncBeginReceive()
         {
-            if (!UsePools)
-            {
-                Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
-
-                UsePools = true;
-
-                return true;
-            }
-
-            return false;
-        }
+            if (!IsRunningInbound)
+                return;
 
-        public virtual bool DisablePools()
-        {
-            if (UsePools)
+            UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least
+            try
             {
-                UsePools = false;
-
-                // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
-
-                return true;
+                // kick off an async read
+                m_udpSocket.BeginReceiveFrom(
+                    buf.Data,
+                    0,
+                    buf.Data.Length,
+                    SocketFlags.None,
+                    ref buf.RemoteEndPoint,
+                    AsyncEndReceive,
+                    buf);
             }
-
-            return false;
-        }
-
-        private void AsyncBeginReceive()
-        {
-            UDPPacketBuffer buf;
-
-            // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other
-            // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux.
-            // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads.  Requires more investigation.
-//            if (UsePools)
-//                buf = Pool.GetObject();
-//            else
-                buf = new UDPPacketBuffer();
-
-            if (IsRunningInbound)
+            catch (SocketException e)
             {
-                try
-                {
-                    // kick off an async read
-                    m_udpSocket.BeginReceiveFrom(
-                        //wrappedBuffer.Instance.Data,
-                        buf.Data,
-                        0,
-                        UDPPacketBuffer.BUFFER_SIZE,
-                        SocketFlags.None,
-                        ref buf.RemoteEndPoint,
-                        AsyncEndReceive,
-                        //wrappedBuffer);
-                        buf);
-                }
-                catch (SocketException e)
+                if (e.SocketErrorCode == SocketError.ConnectionReset)
                 {
-                    if (e.SocketErrorCode == SocketError.ConnectionReset)
+                    m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
+                    bool salvaged = false;
+                    while (!salvaged)
                     {
-                        m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
-                        bool salvaged = false;
-                        while (!salvaged)
+                        try
                         {
-                            try
-                            {
-                                m_udpSocket.BeginReceiveFrom(
-                                    //wrappedBuffer.Instance.Data,
-                                    buf.Data,
-                                    0,
-                                    UDPPacketBuffer.BUFFER_SIZE,
-                                    SocketFlags.None,
-                                    ref buf.RemoteEndPoint,
-                                    AsyncEndReceive,
-                                    //wrappedBuffer);
-                                    buf);
-                                salvaged = true;
-                            }
-                            catch (SocketException) { }
-                            catch (ObjectDisposedException) { return; }
+                            m_udpSocket.BeginReceiveFrom(
+                                buf.Data,
+                                0,
+                                buf.Data.Length,
+                                SocketFlags.None,
+                                ref buf.RemoteEndPoint,
+                                AsyncEndReceive,
+                                buf);
+                            salvaged = true;
                         }
-
-                        m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
+                        catch (SocketException) { }
+                        catch (ObjectDisposedException) { return; }
                     }
-                }
-                catch (ObjectDisposedException e)
-                {
-                    m_log.Error(
-                        string.Format("[UDPBASE]: Error processing UDP begin receive {0}.  Exception  ", UdpReceives), e);
-                }
-                catch (Exception e)
-                {
-                    m_log.Error(
-                        string.Format("[UDPBASE]: Error processing UDP begin receive {0}.  Exception  ", UdpReceives), e);
+
+                    m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
                 }
             }
+            catch (Exception e)
+            {
+                m_log.Error(
+                    string.Format("[UDPBASE]: Error processing UDP begin receive {0}.  Exception  ", UdpReceives), e);
+            }
         }
 
         private void AsyncEndReceive(IAsyncResult iar)
@@ -453,11 +434,6 @@ namespace OpenMetaverse
                             UdpReceives, se.ErrorCode),
                         se);
                 }
-                catch (ObjectDisposedException e)
-                {
-                    m_log.Error(
-                        string.Format("[UDPBASE]: Error processing UDP end receive {0}.  Exception  ", UdpReceives), e);
-                }
                 catch (Exception e)
                 {
                     m_log.Error(
@@ -465,14 +441,12 @@ namespace OpenMetaverse
                 }
                 finally
                 {
-//                    if (UsePools)
-//                        Pool.ReturnObject(buffer);
-
                     AsyncBeginReceive();
                 }
             }
         }
 
+/* not in use
         public void AsyncBeginSend(UDPPacketBuffer buf)
         {
 //            if (IsRunningOutbound)
@@ -511,9 +485,11 @@ namespace OpenMetaverse
             catch (SocketException) { }
             catch (ObjectDisposedException) { }
         }
-
+*/
         public void SyncSend(UDPPacketBuffer buf)
         {
+            if(buf.RemoteEndPoint == null)
+                return; // already expired
             try
             {
                 m_udpSocket.SendTo(
@@ -527,7 +503,7 @@ namespace OpenMetaverse
             }
             catch (SocketException e)
             {
-                m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message);
+                m_log.WarnFormat("[UDPBASE]: sync send SocketException {0} {1}", buf.RemoteEndPoint, e.Message);
             }
             catch (ObjectDisposedException) { }
         }

+ 0 - 9
OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs

@@ -66,9 +66,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// </summary>
         public Int64 MinimumAdaptiveThrottleRate;
 
-        /// <summary>Amount of the texture throttle to steal for the task throttle</summary>
-        public double CannibalizeTextureRate;
-
         public int ClientMaxRate;
         public float BrustTime;
 
@@ -104,12 +101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 //                AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
                 AdaptiveThrottlesEnabled = false;
                 MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000);
-
-                // http textures do use udp bandwidth setting
-//                CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
-//                CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9);
-                CannibalizeTextureRate = 0f;
-
             }
             catch (Exception) { }
         }

+ 11 - 3
OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs

@@ -189,8 +189,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             // Process all the pending adds
             OutgoingPacket pendingAdd;
             while (m_pendingAdds.TryDequeue(out pendingAdd))
+            {
                 if (pendingAdd != null)
                     m_packets[pendingAdd.SequenceNumber] = pendingAdd;
+            }
 
             // Process all the pending removes, including updating statistics and round-trip times
             PendingAck pendingAcknowledgement;
@@ -204,13 +206,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     {
                         m_packets.Remove(pendingAcknowledgement.SequenceNumber);
 
+                        // Update stats
+                        Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
+
+                        ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer);
+                        ackedPacket.Buffer = null;
+
                         // As with other network applications, assume that an acknowledged packet is an
                         // indication that the network can handle a little more load, speed up the transmission
                         ackedPacket.Client.FlowThrottle.AcknowledgePackets(1);
 
-                        // Update stats
-                        Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
-
                         if (!pendingAcknowledgement.FromResend)
                         {
                             // Calculate the round-trip time for this packet and its ACK
@@ -244,6 +249,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
                         // Update stats
                         Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
+
+                        removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer);
+                        removedPacket.Buffer = null;
                     }
                 }
             }

+ 2 - 7
OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs

@@ -953,13 +953,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
                 return;
             }
 
-            // Saving attachments for NPCs messes them up for the real owner!
-            INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
-            if (module != null)
-            {
-                if (module.IsNPC(sp.UUID, m_scene))
-                    return;
-            }
+            if(sp.IsNPC)
+                return;
 
             if (grp.HasGroupChanged)
             {

+ 0 - 28
OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs

@@ -77,7 +77,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
             }
 
             scene.EventManager.OnAvatarKilled += KillAvatar;
-            scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
         }
 
         public void RemoveRegion(Scene scene)
@@ -86,7 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
                 m_scenel.Remove(scene.RegionInfo.RegionHandle);
 
             scene.EventManager.OnAvatarKilled -= KillAvatar;
-            scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
         }
 
         public void RegionLoaded(Scene scene)
@@ -177,31 +175,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
             deadAvatar.setHealthWithUpdate(100.0f);
             deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
         }
-
-        private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
-        {
-            try
-            {
-                ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
-                if (obj == null)
-                    return;
-                if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
-                    || avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
-                {
-                    avatar.Invulnerable = false;
-                }
-                else
-                {
-                    avatar.Invulnerable = true;
-                    if (avatar.Health < 100.0f)
-                    {
-                        avatar.setHealthWithUpdate(100.0f);
-                    }
-                }
-            }
-            catch (Exception)
-            {
-            }
-        }
     }
 }

+ 11 - 4
OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs

@@ -526,16 +526,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
             item.AssetType = (int)AssetType.Object;
             item.AssetID = asset.FullID;
 
-            if (DeRezAction.SaveToExistingUserInventoryItem == action)
+            if (action == DeRezAction.SaveToExistingUserInventoryItem)
             {
                 m_Scene.InventoryService.UpdateItem(item);
             }
             else
             {
-                AddPermissions(item, objlist[0], objlist, remoteClient);
+                bool isowner = remoteClient != null && item.Owner == remoteClient.AgentId;
+                if(action == DeRezAction.Return)
+                    AddPermissions(item, objlist[0], objlist, null);
+                else if(action == DeRezAction.Delete && !isowner)
+                    AddPermissions(item, objlist[0], objlist, null);
+                else
+                   AddPermissions(item, objlist[0], objlist, remoteClient);
+
                 m_Scene.AddInventoryItem(item);
 
-                if (remoteClient != null && item.Owner == remoteClient.AgentId)
+                if (isowner)
                 {
                     remoteClient.SendInventoryItemCreateUpdate(item, 0);
                 }
@@ -1010,7 +1017,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
                     group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
                     rootPart.ParentGroup.ResumeScripts();
 
-                    group.ScheduleGroupForFullUpdate();
+                    group.ScheduleGroupForFullAnimUpdate();
                 }
                 else
                     m_Scene.AddNewSceneObject(group, true, false);

+ 155 - 98
OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs

@@ -27,6 +27,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Collections.Concurrent;
 using System.IO;
 using System.Net;
 using System.Net.Mail;
@@ -94,18 +95,31 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
     {
 //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
-        private object HttpListLock = new object();
-        private int httpTimeout = 30000;
+        private object m_httpListLock = new object();
+        private int m_httpTimeout = 30000;
         private string m_name = "HttpScriptRequests";
 
         private OutboundUrlFilter m_outboundUrlFilter;
         private string m_proxyurl = "";
         private string m_proxyexcepts = "";
 
+        private float m_primPerSec = 1.0f;
+        private float m_primBurst = 3.0f;
+        private float m_primOwnerPerSec = 25.0f;
+        private float m_primOwnerBurst = 5.0f;
+
+        private struct ThrottleData
+        {
+            public double lastTime;
+            public float count;
+        }
+
         // <request id, HttpRequestClass>
         private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
-        private Scene m_scene;
-        // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
+        private ConcurrentQueue<HttpRequestClass> m_CompletedRequests;
+        private ConcurrentDictionary<uint, ThrottleData> m_RequestsThrottle;
+        private ConcurrentDictionary<UUID, ThrottleData> m_OwnerRequestsThrottle;
+
         public static SmartThreadPool ThreadPool = null;
 
         public HttpRequestModule()
@@ -119,10 +133,77 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
             return UUID.Zero;
         }
 
+        public bool CheckThrottle(uint localID, UUID ownerID)
+        {
+            ThrottleData th;
+            double now = Util.GetTimeStamp();
+            bool ret;
+
+            if (m_RequestsThrottle.TryGetValue(localID, out th))
+            {
+                double delta = now - th.lastTime;
+                th.lastTime = now;
+
+                float add = (float)(m_primPerSec * delta);
+                th.count += add;
+                if (th.count > m_primBurst)
+                    th.count = m_primBurst;
+
+                ret = th.count > 0;
+                if (ret)
+                    th.count--;
+            }
+            else
+            {
+                th = new ThrottleData()
+                {
+                    lastTime = now,
+                    count = m_primBurst - 1
+                };
+                ret = true;
+            }
+            m_RequestsThrottle[localID] = th;
+
+            if(!ret)
+                return false;
+
+            if (m_OwnerRequestsThrottle.TryGetValue(ownerID, out th))
+            {
+                double delta = now - th.lastTime;
+                th.lastTime = now;
+
+                float add = (float)(m_primOwnerPerSec * delta);
+                th.count += add;
+                if (th.count > m_primOwnerBurst)
+                    th.count = m_primOwnerBurst;
+
+                ret = th.count > 0;
+                if (ret)
+                    th.count--;
+            }
+            else
+            {
+                th = new ThrottleData()
+                {
+                    lastTime = now,
+                    count = m_primOwnerBurst - 1
+                };
+            }
+            m_OwnerRequestsThrottle[ownerID] = th;
+
+            return ret;
+        }
+
         public UUID StartHttpRequest(
             uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body,
             out HttpInitialRequestStatus status)
         {
+            if (!CheckAllowed(new Uri(url)))
+            {
+                status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER;
+                return UUID.Zero;
+            }
+
             UUID reqID = UUID.Random();
             HttpRequestClass htc = new HttpRequestClass();
 
@@ -207,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
             htc.ItemID = itemID;
             htc.Url = url;
             htc.ReqID = reqID;
-            htc.HttpTimeout = httpTimeout;
+            htc.HttpTimeout = m_httpTimeout;
             htc.OutboundBody = body;
             htc.ResponseHeaders = headers;
             htc.proxyurl = m_proxyurl;
@@ -216,16 +297,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
             // Same number as default HttpWebRequest.MaximumAutomaticRedirections
             htc.MaxRedirects = 50;
 
-            if (StartHttpRequest(htc))
-            {
-                status = HttpInitialRequestStatus.OK;
-                return htc.ReqID;
-            }
-            else
-            {
-                status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER;
-                return UUID.Zero;
-            }
+            lock (m_httpListLock)
+                m_pendingRequests.Add(reqID, htc);
+
+            htc.Process();
+            status = HttpInitialRequestStatus.OK;
+            return reqID;
         }
 
         /// <summary>
@@ -237,34 +314,21 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
             return m_outboundUrlFilter.CheckAllowed(url);
         }
 
-        public bool StartHttpRequest(HttpRequestClass req)
-        {
-            if (!CheckAllowed(new Uri(req.Url)))
-                return false;
-
-            lock (HttpListLock)
-            {
-                m_pendingRequests.Add(req.ReqID, req);
-            }
-
-            req.Process();
-
-            return true;
-        }
-
         public void StopHttpRequest(uint m_localID, UUID m_itemID)
         {
-            if (m_pendingRequests != null)
+            List<UUID> toremove = new List<UUID>();
+            lock (m_httpListLock)
             {
-                lock (HttpListLock)
+                foreach (HttpRequestClass tmpReq in m_pendingRequests.Values)
                 {
-                    HttpRequestClass tmpReq;
-                    if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
+                    if(tmpReq.ItemID == m_itemID)
                     {
                         tmpReq.Stop();
-                        m_pendingRequests.Remove(m_itemID);
+                        toremove.Add(tmpReq.ReqID);
                     }
                 }
+                foreach(UUID id in toremove)
+                    m_pendingRequests.Remove(id);
             }
         }
 
@@ -276,37 +340,35 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
         * finished.  I thought about setting up a queue for this, but
         * it will need some refactoring and this works 'enough' right now
         */
+        public void GotCompletedRequest(HttpRequestClass req)
+        {
+            lock (m_httpListLock)
+            {
+                if (req.Removed)
+                    return;
+                m_pendingRequests.Remove(req.ReqID);
+                m_CompletedRequests.Enqueue(req);
+            }
+        }
 
         public IServiceRequest GetNextCompletedRequest()
         {
-            lock (HttpListLock)
-            {
-                foreach (UUID luid in m_pendingRequests.Keys)
-                {
-                    HttpRequestClass tmpReq;
+            HttpRequestClass req;
+            if(m_CompletedRequests.TryDequeue(out req))
+                return req;
 
-                    if (m_pendingRequests.TryGetValue(luid, out tmpReq))
-                    {
-                        if (tmpReq.Finished)
-                        {
-                            return tmpReq;
-                        }
-                    }
-                }
-            }
             return null;
         }
 
-        public void RemoveCompletedRequest(UUID id)
+        public void RemoveCompletedRequest(UUID reqId)
         {
-            lock (HttpListLock)
+            lock (m_httpListLock)
             {
                 HttpRequestClass tmpReq;
-                if (m_pendingRequests.TryGetValue(id, out tmpReq))
+                if (m_pendingRequests.TryGetValue(reqId, out tmpReq))
                 {
                     tmpReq.Stop();
-                    tmpReq = null;
-                    m_pendingRequests.Remove(id);
+                    m_pendingRequests.Remove(reqId);
                 }
             }
         }
@@ -322,17 +384,28 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 
             HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384);
 
-
             m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config);
-            int maxThreads = 15;
 
-            IConfig httpConfig = config.Configs["HttpRequestModule"];
+            int maxThreads = 8;
+            IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"];
             if (httpConfig != null)
             {
                 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
+                m_primBurst = httpConfig.GetFloat("PrimRequestsBurst", m_primBurst);
+                m_primPerSec = httpConfig.GetFloat("PrimRequestsPerSec", m_primPerSec);
+                m_primOwnerBurst = httpConfig.GetFloat("PrimOwnerRequestsBurst", m_primOwnerBurst);
+                m_primOwnerPerSec = httpConfig.GetFloat("PrimOwnerRequestsPerSec", m_primOwnerPerSec);
+                m_httpTimeout = httpConfig.GetInt("RequestsTimeOut", m_httpTimeout);
+                if(m_httpTimeout > 60000)
+                    m_httpTimeout = 60000;
+                else if(m_httpTimeout < 200)
+                    m_httpTimeout = 200;
             }
 
             m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
+            m_CompletedRequests = new ConcurrentQueue<HttpRequestClass>();
+            m_RequestsThrottle = new ConcurrentDictionary<uint, ThrottleData>();
+            m_OwnerRequestsThrottle = new ConcurrentDictionary<UUID, ThrottleData>();
 
             // First instance sets this up for all sims
             if (ThreadPool == null)
@@ -352,16 +425,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 
         public void AddRegion(Scene scene)
         {
-            m_scene = scene;
-
-            m_scene.RegisterModuleInterface<IHttpRequestModule>(this);
+            scene.RegisterModuleInterface<IHttpRequestModule>(this);
         }
 
         public void RemoveRegion(Scene scene)
         {
             scene.UnregisterModuleInterface<IHttpRequestModule>(this);
-            if (scene == m_scene)
-                m_scene = null;
         }
 
         public void PostInitialise()
@@ -406,11 +475,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
         /// </summary>
         public HttpRequestModule RequestModule { get; set; }
 
-        private bool _finished;
-        public bool Finished
-        {
-            get { return _finished; }
-        }
+        public bool Finished { get; private set;}
+        public bool Removed{ get; set;}
 
         public static int HttpBodyMaxLenMAX = 16384;
 
@@ -427,19 +493,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
         public bool HttpPragmaNoCache = true;
 
         // Request info
-        private UUID _itemID;
-        public UUID ItemID
-        {
-            get { return _itemID; }
-            set { _itemID = value; }
-        }
-        private uint _localID;
-        public uint LocalID
-        {
-            get { return _localID; }
-            set { _localID = value; }
-        }
-        public DateTime Next;
+        public UUID ReqID { get; set; }
+        public UUID ItemID {  get; set;}
+        public uint LocalID { get; set;}
+
         public string proxyurl;
         public string proxyexcepts;
 
@@ -454,12 +511,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
         public int MaxRedirects { get; set; }
 
         public string OutboundBody;
-        private UUID _reqID;
-        public UUID ReqID
-        {
-            get { return _reqID; }
-            set { _reqID = value; }
-        }
+
         public HttpWebRequest Request;
         public string ResponseBody;
         public List<string> ResponseMetadata;
@@ -469,10 +521,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 
         public void Process()
         {
-            _finished = false;
-
-            lock (HttpRequestModule.ThreadPool)
-                WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
+            WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
         }
 
         private object StpSendWrapper(object o)
@@ -521,6 +570,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 
         public void SendRequest()
         {
+            if(Removed)
+                 return;
+
             HttpWebResponse response = null;
             Stream resStream = null;
             byte[] buf = new byte[HttpBodyMaxLenMAX + 16];
@@ -534,6 +586,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
 
                 Request.AllowAutoRedirect = false;
                 Request.KeepAlive = false;
+                Request.Timeout = HttpTimeout;
 
                 //This works around some buggy HTTP Servers like Lighttpd
                 Request.ServicePoint.Expect100Continue = false;
@@ -593,7 +646,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
                         bstream.Write(data, 0, data.Length);
                 }
 
-                Request.Timeout = HttpTimeout;
                 try
                 {
                     // execute the request
@@ -672,7 +724,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
                 if (response != null)
                     response.Close();
 
-
                 // We need to resubmit
                 if (
                     (Status == (int)HttpStatusCode.MovedPermanently
@@ -684,7 +735,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
                     {
                         Status = (int)OSHttpStatusCode.ClientErrorJoker;
                         ResponseBody = "Number of redirects exceeded max redirects";
-                        _finished = true;
+                        WorkItem = null;
+                        RequestModule.GotCompletedRequest(this);
                     }
                     else
                     {
@@ -694,13 +746,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
                         {
                             Status = (int)OSHttpStatusCode.ClientErrorJoker;
                             ResponseBody = "HTTP redirect code but no location header";
-                            _finished = true;
+                            WorkItem = null;
+                            RequestModule.GotCompletedRequest(this);
                         }
                         else if (!RequestModule.CheckAllowed(new Uri(location)))
                         {
                             Status = (int)OSHttpStatusCode.ClientErrorJoker;
                             ResponseBody = "URL from HTTP redirect blocked: " + location;
-                            _finished = true;
+                            WorkItem = null;
+                            RequestModule.GotCompletedRequest(this);
                         }
                         else
                         {
@@ -717,9 +771,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
                 }
                 else
                 {
-                    _finished = true;
+                    WorkItem = null;
                     if (ResponseBody == null)
                         ResponseBody = String.Empty;
+                    RequestModule.GotCompletedRequest(this);
                 }
             }
         }
@@ -728,10 +783,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
         {
             try
             {
+                Removed = true;
+                if(WorkItem == null)
+                    return;
+
                 if (!WorkItem.Cancel())
-                {
                     WorkItem.Cancel(true);
-                }
             }
             catch (Exception)
             {

+ 15 - 10
OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs

@@ -1204,28 +1204,33 @@ namespace OpenSim.Region.CoreModules.World.Estate
             }
         }
 
-        private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
+        private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey, bool kick)
         {
+            if (prey == UUID.Zero)
+                return;
+
              EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest;
              if(evOverride != null)
              {
-                evOverride(remover_client, invoice, senderID, prey);
+                evOverride(remover_client, invoice, senderID, prey, kick);
                 return;
              }
 
             if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false))
                 return;
 
-            if (prey != UUID.Zero)
+            ScenePresence s = Scene.GetScenePresence(prey);
+            if (s != null && !s.IsDeleted && !s.IsInTransit)
             {
-                ScenePresence s = Scene.GetScenePresence(prey);
-                if (s != null && !s.IsDeleted && !s.IsInTransit)
+                if (kick)
                 {
-                    if (!Scene.TeleportClientHome(prey, s.ControllingClient))
-                    {
-                        s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
-                        Scene.CloseAgent(s.UUID, false);
-                    }
+                    s.ControllingClient.Kick("You have been kicked");
+                    Scene.CloseAgent(s.UUID, false);
+                }
+                else if (!Scene.TeleportClientHome(prey, s.ControllingClient))
+                {
+                    s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed ");
+                    Scene.CloseAgent(s.UUID, false);
                 }
             }
         }

+ 20 - 3
OpenSim/Region/CoreModules/World/Estate/EstateModule.cs

@@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
                 m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message);
         }
 
-        private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey)
+        private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey, bool kick)
         {
             if (prey == UUID.Zero)
                 return;
@@ -227,8 +227,20 @@ namespace OpenSim.Region.CoreModules.World.Estate
                 ScenePresence p = scene.GetScenePresence(prey);
                 if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit)
                 {
-                    p.ControllingClient.SendTeleportStart(16);
-                    scene.TeleportClientHome(prey, client);
+                    if (kick)
+                    {
+                        p.ControllingClient.Kick("You have been kicked out");
+                        s.CloseAgent(p.UUID, false);
+                    }
+                    else
+                    {
+                        p.ControllingClient.SendTeleportStart(16);
+                        if (!s.TeleportClientHome(prey, client))
+                        {
+                            p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed");
+                            s.CloseAgent(p.UUID, false);
+                        }
+                    }
                     return;
                 }
             }
@@ -259,6 +271,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
                         {
                             p.ControllingClient.SendTeleportStart(16);
                             scene.TeleportClientHome(p.ControllingClient.AgentId, client);
+                            if (!s.TeleportClientHome(p.ControllingClient.AgentId, client))
+                            {
+                                p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
+                                s.CloseAgent(p.UUID, false);
+                            }
                         }
                     });
             }

+ 1 - 0
OpenSim/Region/Framework/Interfaces/IHttpRequests.cs

@@ -87,5 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces
         void StopHttpRequest(uint m_localID, UUID m_itemID);
         IServiceRequest GetNextCompletedRequest();
         void RemoveCompletedRequest(UUID id);
+        bool CheckThrottle(uint localID, UUID onerID);
     }
 }

+ 4 - 8
OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs

@@ -94,19 +94,15 @@ namespace OpenSim.Region.Framework.Scenes
                 m_inventoryDeletes.Enqueue(dtis);
             }
 
-            if (Enabled)
-                lock (m_inventoryTicker)
-                    m_inventoryTicker.Start();
-
-            // Visually remove it, even if it isnt really gone yet.  This means that if we crash before the object
-            // has gone to inventory, it will reappear in the region again on restart instead of being lost.
-            // This is not ideal since the object will still be available for manipulation when it should be, but it's
-            // better than losing the object for now.
             if (permissionToDelete)
             {
                 foreach (SceneObjectGroup g in objectGroups)
                     g.DeleteGroupFromScene(false);
             }
+
+            if (Enabled)
+                lock (m_inventoryTicker)
+                    m_inventoryTicker.Start();
         }
 
         private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)

+ 3 - 3
OpenSim/Region/Framework/Scenes/EventManager.cs

@@ -539,7 +539,7 @@ namespace OpenSim.Region.Framework.Scenes
         /// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/>
         /// </remarks>
         public event ScriptChangedEvent OnScriptChangedEvent;
-        public delegate void ScriptChangedEvent(uint localID, uint change);
+        public delegate void ScriptChangedEvent(uint localID, uint change, object data);
 
         public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed);
 
@@ -1185,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
             }
         }
 
-        public void TriggerOnScriptChangedEvent(uint localID, uint change)
+        public void TriggerOnScriptChangedEvent(uint localID, uint change, object parameter = null)
         {
             ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent;
             if (handlerScriptChangedEvent != null)
@@ -1194,7 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes
                 {
                     try
                     {
-                        d(localID, change);
+                        d(localID, change, parameter);
                     }
                     catch (Exception e)
                     {

+ 68 - 96
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs

@@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes
             // build a list of eligible objects
             List<uint> deleteIDs = new List<uint>();
             List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>();
-            List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>();
+            List<SceneObjectGroup> takeCopyGroups = new List<SceneObjectGroup>();
             List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>();
 
             ScenePresence sp = null;
@@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes
             else if(action != DeRezAction.Return)
                 return; // only Return can be called without a client
 
-            // Start with true for both, then remove the flags if objects
-            // that we can't derez are part of the selection
-            bool permissionToTake = true;
-            bool permissionToTakeCopy = true;
-            bool permissionToDelete = true;
+            // this is not as 0.8x code
+            // 0.8x did refuse all operation is not allowed on all objects
+            // this will do it on allowed objects
+            // current viewers only ask if all allowed
 
             foreach (uint localID in localIDs)
             {
@@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes
                     continue;
                 }
 
-                // Already deleted by someone else
-                if (part.ParentGroup.IsDeleted)
+                SceneObjectGroup grp = part.ParentGroup;
+                if (grp == null || grp.IsDeleted)
                 {
                     //Client still thinks the object exists, kill it
                     deleteIDs.Add(localID);
@@ -2145,132 +2144,105 @@ namespace OpenSim.Region.Framework.Scenes
                 }
 
                 // Can't delete child prims
-                if (part != part.ParentGroup.RootPart)
+                if (part != grp.RootPart)
                     continue;
 
-                SceneObjectGroup grp = part.ParentGroup;
                 if (grp.IsAttachment)
-                    continue;
+                {
+                    if(!sp.IsGod || action != DeRezAction.Return || action != DeRezAction.Delete)
+                        continue;
+                    // this may break the attachment, but its a security action
+                    // viewers don't allow it anyways
+                }
 
                 // If child prims have invalid perms, fix them
                 grp.AdjustChildPrimPermissions(false);
 
-                if (remoteClient == null)
+                switch (action)
                 {
-                    // Autoreturn has a null client. Nothing else does. So
-                    // allow only returns
-                    if (action != DeRezAction.Return)
+                    case DeRezAction.SaveToExistingUserInventoryItem:
                     {
-                        m_log.WarnFormat(
-                            "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client",
-                            action, grp.Name, grp.UUID);
-                        return;
+                        if (Permissions.CanTakeCopyObject(grp, sp))
+                            takeCopyGroups.Add(grp);
+                        break;
                     }
 
-                    permissionToTakeCopy = false;
-                }
-                else
-                {
-                    if (action == DeRezAction.TakeCopy)
+                    case DeRezAction.TakeCopy:
                     {
-                        if (!Permissions.CanTakeCopyObject(grp, sp))
-                            permissionToTakeCopy = false;
+                        if (Permissions.CanTakeCopyObject(grp, sp))
+                            takeCopyGroups.Add(grp);
+                        break;
                     }
-                    else
+
+                    case DeRezAction.Take:
                     {
-                        permissionToTakeCopy = false;
+                        if (Permissions.CanTakeObject(grp, sp))
+                            takeDeleteGroups.Add(grp);
+                        break;
                     }
-                    if (!Permissions.CanTakeObject(grp, sp))
-                        permissionToTake = false;
-
-                    if (!Permissions.CanDeleteObject(grp, remoteClient))
-                        permissionToDelete = false;
-                }
-
-                // Handle god perms
-                if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
-                {
-                    permissionToTake = true;
-                    permissionToTakeCopy = true;
-                    permissionToDelete = true;
-                }
-
-                // If we're re-saving, we don't even want to delete
-                if (action == DeRezAction.SaveToExistingUserInventoryItem)
-                    permissionToDelete = false;
 
-                // if we want to take a copy, we also don't want to delete
-                // Note: after this point, the permissionToTakeCopy flag
-                // becomes irrelevant. It already includes the permissionToTake
-                // permission and after excluding no copy items here, we can
-                // just use that.
-                if (action == DeRezAction.TakeCopy)
-                {
-                    // If we don't have permission, stop right here
-                    if (!permissionToTakeCopy)
+                    case DeRezAction.GodTakeCopy:
                     {
-                        remoteClient.SendAlertMessage("You don't have permission to take the object");
-                        return;
+                        if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId))
+                            takeCopyGroups.Add(grp);
+                        break;
                     }
 
-                    permissionToTake = true;
-                    // Don't delete
-                    permissionToDelete = false;
-                }
-
-                if (action == DeRezAction.Return)
-                {
-                    if (remoteClient != null)
+                    case DeRezAction.Delete:
                     {
-                        if (Permissions.CanReturnObjects(
-                                        null,
-                                        remoteClient,
-                                        new List<SceneObjectGroup>() {grp}))
+                        if (Permissions.CanDeleteObject(grp, remoteClient))
                         {
-                            permissionToTake = true;
-                            permissionToDelete = true;
-                            if(AddToReturns)
-                                AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
-                                        "parcel owner return");
+                            if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID))
+                                takeDeleteGroups.Add(grp);
+                            else
+                                deleteGroups.Add(grp);
                         }
+                        break;
                     }
-                    else // Auto return passes through here with null agent
+
+                    case DeRezAction.Return:
                     {
-                        permissionToTake = true;
-                        permissionToDelete = true;
+                        if (remoteClient != null)
+                        {
+                            if (Permissions.CanReturnObjects( null, remoteClient, new List<SceneObjectGroup>() {grp}))
+                            {
+                                takeDeleteGroups.Add(grp);
+                                if (AddToReturns)
+                                    AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition,
+                                            "parcel owner return");
+                            }
+                        }
+                        else // Auto return passes through here with null agent
+                        {
+                            takeDeleteGroups.Add(grp);
+                        }
+                        break;
                     }
-                }
 
-                if (permissionToDelete)
-                {
-                    if (permissionToTake)
-                        takeDeleteGroups.Add(grp);
-                    else
-                        deleteGroups.Add(grp);
-                    deleteIDs.Add(grp.LocalId);
+                    default:
+                        break;
                 }
-                else if(permissionToTake)
-                    takeGroups.Add(grp);
             }
 
-             SendKillObject(deleteIDs);
+            if(deleteIDs.Count > 0)
+                SendKillObject(deleteIDs);
 
             if (takeDeleteGroups.Count > 0)
             {
-                m_asyncSceneObjectDeleter.DeleteToInventory(
-                        action, destinationID, takeDeleteGroups, remoteClient,
-                        true);
+                m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups,
+                        remoteClient, true);
             }
-            if (takeGroups.Count > 0)
+
+            if (takeCopyGroups.Count > 0)
             {
-                m_asyncSceneObjectDeleter.DeleteToInventory(
-                        action, destinationID, takeGroups, remoteClient,
-                        false);
+                m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups,
+                        remoteClient, false);
             }
+
             if (deleteGroups.Count > 0)
             {
                 foreach (SceneObjectGroup g in deleteGroups)
-                    DeleteSceneObject(g, true);
+                    DeleteSceneObject(g, false);
             }
         }
 

+ 1 - 3
OpenSim/Region/Framework/Scenes/SceneGraph.cs

@@ -1913,9 +1913,8 @@ namespace OpenSim.Region.Framework.Scenes
                 {
                     if (parentGroup.OwnerID == child.OwnerID)
                     {
-                        parentGroup.LinkToGroup(child);
-
                         child.DetachFromBackup();
+                        parentGroup.LinkToGroup(child);
 
                         // this is here so physics gets updated!
                         // Don't remove!  Bad juju!  Stay away! or fix physics!
@@ -1943,7 +1942,6 @@ namespace OpenSim.Region.Framework.Scenes
 */
                 parentGroup.AdjustChildPrimPermissions(false);
                 parentGroup.HasGroupChanged = true;
-                parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
                 parentGroup.ScheduleGroupForFullAnimUpdate();
                 Monitor.Exit(m_linkLock);
             }

+ 1 - 1
OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs

@@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes
                 // We're adding this to a prim we don't own. Force
                 // owner change
                 taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
-
+                taskItem.LastOwnerID = item.Owner;
             }
             else
             {

+ 19 - 14
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs

@@ -3242,8 +3242,6 @@ namespace OpenSim.Region.Framework.Scenes
             if (ParentGroup.Scene.GetNumberOfClients() == 0)
                 return;
 
-            ParentGroup.QueueForUpdateCheck();
-
             bool isfull = false;
             if (ParentGroup.IsAttachment)
             {
@@ -3254,6 +3252,8 @@ namespace OpenSim.Region.Framework.Scenes
             lock (UpdateFlagLock)
                 UpdateFlag |= update;
 
+            ParentGroup.QueueForUpdateCheck();
+
             ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull);
         }
 
@@ -4439,10 +4439,10 @@ namespace OpenSim.Region.Framework.Scenes
             SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary<string, object>());
         }
 
-        public void TriggerScriptChangedEvent(Changed val)
+        public void TriggerScriptChangedEvent(Changed val, object data = null)
         {
             if (ParentGroup != null && ParentGroup.Scene != null)
-                ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val);
+                ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val, data);
         }
 
         public void TrimPermissions()
@@ -5130,11 +5130,10 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (changeFlags == 0)
                 return;
-            m_shape.TextureEntry = newTex.GetBytes();
+            m_shape.TextureEntry = newTex.GetBytes(9);
             TriggerScriptChangedEvent(changeFlags);
             ParentGroup.HasGroupChanged = true;
-            ScheduleFullUpdate();
-
+            ScheduleUpdate(PrimUpdateFlags.Textures);
         }
 
         /// <summary>
@@ -5160,10 +5159,10 @@ namespace OpenSim.Region.Framework.Scenes
             if (changeFlags == 0)
                 return;
 
-            m_shape.TextureEntry = newTex.GetBytes();
+            m_shape.TextureEntry = newTex.GetBytes(9);
             TriggerScriptChangedEvent(changeFlags);
             ParentGroup.HasGroupChanged = true;
-            ScheduleFullUpdate();
+            ScheduleUpdate(PrimUpdateFlags.Textures);
         }
 
         internal void UpdatePhysicsSubscribedEvents()
@@ -5575,20 +5574,26 @@ namespace OpenSim.Region.Framework.Scenes
         // handle osVolumeDetect
         public void ScriptSetVolumeDetect(bool makeVolumeDetect)
         {
+            if(ParentGroup.IsDeleted)
+                return;
+
             if(_parentID == 0)
             {
-                // if root prim do it via SOG
+                // if root prim do it is like llVolumeDetect
                 ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect);
                 return;
             }
 
-            bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
-            bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
-            bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0);
+            if(ParentGroup.IsVolumeDetect)
+                return; // entire linkset is phantom already
+
+            bool wasUsingPhysics = ParentGroup.UsesPhysics;
+            bool wasTemporary = ParentGroup.IsTemporary;
+            bool wasPhantom = ParentGroup.IsPhantom;
 
             if(PhysActor != null)
                 PhysActor.Building = true;
-            UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false);
+            UpdatePrimFlags(wasUsingPhysics, wasTemporary, wasPhantom, makeVolumeDetect, false);
         }
 
         protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL);

+ 4 - 4
OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs

@@ -815,10 +815,10 @@ namespace OpenSim.Region.Framework.Scenes
             m_items.LockItemsForWrite(true);
             m_items.Add(item.ItemID, item);
             m_items.LockItemsForWrite(false);
-                if (allowedDrop)
-                    m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
-                else
-                    m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
+            if (allowedDrop)
+                m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP, item.ItemID);
+            else
+                m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
 
             m_part.AggregateInnerPerms();
             m_inventorySerial++;

+ 34 - 16
OpenSim/Region/Framework/Scenes/ScenePresence.cs

@@ -507,7 +507,19 @@ namespace OpenSim.Region.Framework.Scenes
         /// <summary>
         /// Physical scene representation of this Avatar.
         /// </summary>
-        public PhysicsActor PhysicsActor { get; private set; }
+        
+        PhysicsActor m_physActor;
+        public PhysicsActor PhysicsActor
+        {
+            get
+            {
+                return m_physActor;
+            }
+            private set
+            {
+                m_physActor = value;
+            }
+        }
 
         /// <summary>
         /// Record user movement inputs.
@@ -523,7 +535,12 @@ namespace OpenSim.Region.Framework.Scenes
 
         public bool Invulnerable
         {
-            set { m_invulnerable = value; }
+            set
+            {
+                m_invulnerable = value;
+                if(value && Health != 100.0f)
+                    Health = 100.0f;
+            }
             get { return m_invulnerable; }
         }
 
@@ -1636,15 +1653,15 @@ namespace OpenSim.Region.Framework.Scenes
         /// </summary>
         public void RemoveFromPhysicalScene()
         {
-            if (PhysicsActor != null)
+            PhysicsActor pa = Interlocked.Exchange(ref m_physActor, null);
+            if (pa != null)
             {
 //                PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
 
-                PhysicsActor.OnOutOfBounds -= OutOfBoundsCall;
-                PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate;
-                PhysicsActor.UnSubscribeEvents();
-                m_scene.PhysicsScene.RemoveAvatar(PhysicsActor);
-                PhysicsActor = null;
+                pa.OnOutOfBounds -= OutOfBoundsCall;
+                pa.OnCollisionUpdate -= PhysicsCollisionUpdate;
+                pa.UnSubscribeEvents();
+                m_scene.PhysicsScene.RemoveAvatar(pa);
             }
 //            else
 //            {
@@ -2537,7 +2554,7 @@ namespace OpenSim.Region.Framework.Scenes
                     m_pos.X = 127f;
                     m_pos.Y = 127f;
                     m_pos.Z = 127f;
-                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
+                    m_log.Error("[AVATAR]: NonFinite Avatar on lastFiniteposition also. Reset Position. Mantis this please. Error #9999903");
                 }
 
                 if(isphysical)
@@ -5007,16 +5024,17 @@ namespace OpenSim.Region.Framework.Scenes
             PhysicsScene scene = m_scene.PhysicsScene;
             Vector3 pVec = AbsolutePosition;
 
-            PhysicsActor = scene.AddAvatar(
+            PhysicsActor pa = scene.AddAvatar(
                 LocalId, Firstname + "." + Lastname, pVec,
                 Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
-            PhysicsActor.Orientation = m_bodyRot;
+            pa.Orientation = m_bodyRot;
             //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
-            PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
-            PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
-            PhysicsActor.SubscribeEvents(100);
-            PhysicsActor.LocalID = LocalId;
-            PhysicsActor.SetAlwaysRun = m_setAlwaysRun;
+            pa.OnCollisionUpdate += PhysicsCollisionUpdate;
+            pa.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
+            pa.SubscribeEvents(100);
+            pa.LocalID = LocalId;
+            pa.SetAlwaysRun = m_setAlwaysRun;
+            PhysicsActor = pa;
         }
 
         private void OutOfBoundsCall(Vector3 pos)

+ 2 - 0
OpenSim/Region/Framework/Scenes/TerrainCompressor.cs

@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             return iout;
         }
 
+/*
         // new using terrain data and patchs indexes
         public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] map)
         {
@@ -213,6 +214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 
             return ret;
         }
+*/
 
         public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY)
         {

+ 2 - 2
OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs

@@ -323,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Materials
             }
 
             if(facechanged)
-                part.Shape.TextureEntry = te.GetBytes();
+                part.Shape.TextureEntry = te.GetBytes(9);
 
             if(facechanged || partchanged)
             {
@@ -632,7 +632,7 @@ namespace OpenSim.Region.OptionalModules.Materials
                                             faceEntry.MaterialID = id;
                                             //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id);
                                             // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually
-                                            sop.Shape.TextureEntry = te.GetBytes();
+                                            sop.Shape.TextureEntry = te.GetBytes(9);
                                         }
 
                                         if(oldid != UUID.Zero)

+ 15 - 9
OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs

@@ -47,9 +47,9 @@ public class BSActorAvatarMove : BSActor
     // The amount the step up is applying. Used to smooth stair walking.
     float m_lastStepUp;
 
-    // There are times the velocity is set but we don't want to inforce stationary until the
-    //    real velocity drops.
-    bool m_waitingForLowVelocityForStationary = false;
+    // There are times the velocity or force is set but we don't want to inforce
+    //    stationary until some tick in the future and the real velocity drops.
+    int m_waitingForLowVelocityForStationary = 0;
 
     public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
         : base(physicsScene, pObj, actorName)
@@ -114,14 +114,18 @@ public class BSActorAvatarMove : BSActor
                 m_velocityMotor.Enabled = true;
                 m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
                             m_controllingPrim.LocalID, vel, targ);
-                m_waitingForLowVelocityForStationary = false;
+                m_waitingForLowVelocityForStationary = 0;
             }
         });
     }
 
     public void SuppressStationayCheckUntilLowVelocity()
     {
-        m_waitingForLowVelocityForStationary = true;
+        m_waitingForLowVelocityForStationary = 1;
+    }
+    public void SuppressStationayCheckUntilLowVelocity(int waitTicks)
+    {
+        m_waitingForLowVelocityForStationary = waitTicks;
     }
 
     // If a movement motor has not been created, create one and start the movement
@@ -143,7 +147,7 @@ public class BSActorAvatarMove : BSActor
             m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty;
 
             m_walkingUpStairs = 0;
-            m_waitingForLowVelocityForStationary = false;
+            m_waitingForLowVelocityForStationary = 0;
         }
     }
 
@@ -194,15 +198,17 @@ public class BSActorAvatarMove : BSActor
                 // if colliding with something stationary and we're not doing volume detect .
                 if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
                 {
-                    if (m_waitingForLowVelocityForStationary)
+                    if (m_waitingForLowVelocityForStationary-- <= 0)
                     {
                         // if waiting for velocity to drop and it has finally dropped, we can be stationary
+                        // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVelocity {1}",
+                        //             m_controllingPrim.LocalID, m_waitingForLowVelocityForStationary);
                         if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared)
                         {
-                            m_waitingForLowVelocityForStationary = false;
+                            m_waitingForLowVelocityForStationary = 0;
                         }
                     }
-                    if (!m_waitingForLowVelocityForStationary)
+                    if (m_waitingForLowVelocityForStationary <= 0)
                     {
                         m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
                         m_controllingPrim.IsStationary = true;

+ 1 - 1
OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs

@@ -701,7 +701,7 @@ public sealed class BSCharacter : BSPhysObject
                 }
                 if (m_moveActor != null)
                 {
-                    m_moveActor.SuppressStationayCheckUntilLowVelocity();
+                    m_moveActor.SuppressStationayCheckUntilLowVelocity(BSParam.AvatarAddForceFrames);
                 }
             });
         }

+ 3 - 0
OpenSim/Region/PhysicsModules/BulletS/BSParam.cs

@@ -149,6 +149,7 @@ public static class BSParam
     public static float AvatarHeightHighFudge { get; private set; }
     public static float AvatarFlyingGroundMargin { get; private set; }
     public static float AvatarFlyingGroundUpForce { get; private set; }
+    public static int AvatarAddForceFrames { get; private set; }
     public static float AvatarTerminalVelocity { get; private set; }
     public static float AvatarContactProcessingThreshold { get; private set; }
     public static float AvatarAddForcePushFactor { get; private set; }
@@ -634,6 +635,8 @@ public static class BSParam
             5f ),
         new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin",
             2.0f ),
+        new ParameterDefn<int>("AvatarAddForceFrames", "Frames to allow AddForce to apply before checking for stationary",
+            10 ),
         new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar",
             -54.0f ),
         new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",

+ 7 - 2
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs

@@ -221,7 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         /// </summary>
         private static void CmdHandlerThreadLoop()
         {
-            while (true)
+            bool running = true;
+            while (running)
             {
                 try
                 {
@@ -230,7 +231,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                     DoOneCmdHandlerPass();
                     Watchdog.UpdateThread();
                 }
-                catch ( System.Threading.ThreadAbortException) { }
+                catch ( System.Threading.ThreadAbortException)
+                {
+                    Thread.ResetAbort();
+                    running = false;
+                }
                 catch (Exception e)
                 {
                     m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);

+ 13 - 53
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs

@@ -1936,45 +1936,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
                 return;
 
-            Primitive.TextureEntry tex = part.Shape.Textures;
-            int nsides = GetNumberOfSides(part);
-            Color4 texcolor;
-
-            if (face >= 0 && face < nsides)
-            {
-                texcolor = tex.CreateFace((uint)face).RGBA;
-                texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
-                texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
-                texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
-                tex.FaceTextures[face].RGBA = texcolor;
-                part.UpdateTextureEntry(tex);
-                return;
-            }
-            else if (face == ScriptBaseClass.ALL_SIDES)
-            {              
-                for (uint i = 0; i < nsides; i++)
-                {
-                    if (tex.FaceTextures[i] != null)
-                    {
-                        texcolor = tex.FaceTextures[i].RGBA;
-                        texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
-                        texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
-                        texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
-                        tex.FaceTextures[i].RGBA = texcolor;
-                    }
-                    texcolor = tex.DefaultTexture.RGBA;
-                    texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
-                    texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
-                    texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
-                    tex.DefaultTexture.RGBA = texcolor;
-                }
-                part.UpdateTextureEntry(tex);
-                return;
-            }
-
-            if (face == ScriptBaseClass.ALL_SIDES)
-                face = SceneObjectPart.ALL_SIDES;
-
             m_host.SetFaceColorAlpha(face, color, null);
         }
 
@@ -3577,7 +3538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
         {
             m_host.AddScriptLPS(1);
-            if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
+            if (string.IsNullOrEmpty(inventory) || Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
                 return;
 
             float dist = (float)llVecDist(llGetPos(), pos);
@@ -10653,7 +10614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 return false;
 
             texface.MaterialID = id;
-            part.Shape.TextureEntry = tex.GetBytes();
+            part.Shape.TextureEntry = tex.GetBytes(9);
             m_materialsModule.RemoveMaterial(oldid);
             return true;
         }
@@ -10710,7 +10671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 return false;
 
             texface.MaterialID = id;
-            part.Shape.TextureEntry = tex.GetBytes();
+            part.Shape.TextureEntry = tex.GetBytes(9);
             m_materialsModule.RemoveMaterial(oldid);
             return true;
         }
@@ -10777,7 +10738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 return false;
 
             texface.MaterialID = id;
-            part.Shape.TextureEntry = tex.GetBytes();
+            part.Shape.TextureEntry = tex.GetBytes(9);
             m_materialsModule.RemoveMaterial(oldid);
             return true;
         }
@@ -13945,14 +13906,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
         public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body)
         {
-            // Partial implementation: support for parameter flags needed
-            //   see http://wiki.secondlife.com/wiki/LlHTTPRequest
-            // parameter flags support are implemented in ScriptsHttpRequests.cs
-            //   in StartHttpRequest
-
             m_host.AddScriptLPS(1);
-            IHttpRequestModule httpScriptMod =
-                m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
+            IHttpRequestModule httpScriptMod = m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
+            if(httpScriptMod == null)
+                return "";
+
+            if(!httpScriptMod.CheckThrottle(m_host.LocalId, m_host.OwnerID))
+                return UUID.Zero.ToString();
+
             List<string> param = new List<string>();
             bool  ok;
             Int32 flag;
@@ -14123,8 +14084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             }
 
             HttpInitialRequestStatus status;
-            UUID reqID
-                = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status);
+            UUID reqID = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status);
 
             if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER)
                 Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url));
@@ -14132,7 +14092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             if (reqID != UUID.Zero)
                 return reqID.ToString();
             else
-                return null;
+                return "";
         }
 
 

+ 93 - 33
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs

@@ -3629,7 +3629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
 
-            World.ForEachRootScenePresence(delegate(ScenePresence sp)
+            World.ForEachRootScenePresence(delegate (ScenePresence sp)
             {
                 if (sp.Firstname == FirstName && sp.Lastname == SurName)
                 {
@@ -3643,18 +3643,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             });
         }
 
-        public LSL_Float osGetHealth(string avatar)
+        public void osKickAvatar(LSL_Key agentKey, string alert)
+        {
+            CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
+
+            UUID id;
+            if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero)
+                return;
+
+            ScenePresence sp = World.GetScenePresence(id);
+            if(sp == null)
+                return;
+
+            // kick client...
+            if (alert != null)
+                sp.ControllingClient.Kick(alert);
+
+            // ...and close on our side
+            sp.Scene.CloseAgent(id, false);
+        }
+
+        public LSL_Float osGetHealth(LSL_Key agentKey)
         {
             CheckThreatLevel(ThreatLevel.None, "osGetHealth");
 
             LSL_Float health = new LSL_Float(-1);
-            ScenePresence presence = World.GetScenePresence(new UUID(avatar));
+
+            UUID id;
+            if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero)
+                return health;
+
+            ScenePresence presence = World.GetScenePresence(id);
             if (presence != null)
                 health = presence.Health;
             return health;
         }
 
-        public void osCauseDamage(string avatar, double damage)
+        public void osCauseDamage(LSL_Key avatar, LSL_Float damage)
         {
             CheckThreatLevel(ThreatLevel.High, "osCauseDamage");
 
@@ -3683,7 +3708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             }
         }
 
-        public void osCauseHealing(string avatar, double healing)
+        public void osCauseHealing(LSL_Key avatar, LSL_Float healing)
         {
             CheckThreatLevel(ThreatLevel.High, "osCauseHealing");
 
@@ -3704,7 +3729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             presence.setHealthWithUpdate(health);
         }
 
-        public void osSetHealth(string avatar, double health)
+        public void osSetHealth(LSL_Key avatar, LSL_Float health)
         {
             CheckThreatLevel(ThreatLevel.High, "osSetHealth");
 
@@ -3722,7 +3747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             }
         }
 
-        public void osSetHealRate(string avatar, double healrate)
+        public void osSetHealRate(LSL_Key avatar, LSL_Float healrate)
         {
             CheckThreatLevel(ThreatLevel.High, "osSetHealRate");
 
@@ -3737,7 +3762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             presence.HealRate = (float)healrate;
         }
 
-        public LSL_Float osGetHealRate(string avatar)
+        public LSL_Float osGetHealRate(LSL_Key avatar)
         {
             CheckThreatLevel(ThreatLevel.None, "osGetHealRate");
 
@@ -3864,29 +3889,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
         }
 
-        /// <summary>
-        /// Get the description from an inventory item
-        /// </summary>
-        /// <param name="inventoryName"></param>
-        /// <returns>Item description</returns>
-        public LSL_String osGetInventoryDesc(string item)
-        {
-            CheckThreatLevel();
-
-            lock (m_host.TaskInventory)
-            {
-                foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
-                {
-                    if (inv.Value.Name == item)
-                    {
-                        return inv.Value.Description.ToString();
-                    }
-                }
-            }
-
-            return String.Empty;
-        }
-
         /// <summary>
         /// Invite user to the group this object is set to
         /// </summary>
@@ -4849,8 +4851,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             return Math.Atan2(mcross, dot);
         }
 
-
-//******* link sound
        public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume)
         {
             m_host.AddScriptLPS(1);
@@ -5381,5 +5381,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             return 1;
         }
 
+        public LSL_Key osGetInventoryLastOwner(LSL_String itemNameorid)
+        {
+            m_host.AddScriptLPS(1);
+
+            TaskInventoryItem item = null;
+            UUID itemID;
+            if (UUID.TryParse(itemNameorid, out itemID))
+                item = m_host.Inventory.GetInventoryItem(itemID);
+            else
+                item = m_host.Inventory.GetInventoryItem(itemNameorid);
+
+            if (item == null)
+                return UUID.Zero.ToString();
+
+            UUID id = item.LastOwnerID;
+            if(id == UUID.Zero)
+                id= item.OwnerID;
+            return id.ToString();
+        }
+
+        public LSL_String osGetInventoryName(LSL_Key itemId)
+        {
+            m_host.AddScriptLPS(1);
+
+            TaskInventoryItem item = null;
+            UUID itemID;
+            if (UUID.TryParse(itemId, out itemID))
+                item = m_host.Inventory.GetInventoryItem(itemID);
+
+            if (item == null)
+                return String.Empty;
+
+            return item.Name;
+        }
+
+        public LSL_String osGetInventoryDesc(LSL_String itemNameorid)
+        {
+            m_host.AddScriptLPS(1);
+
+            TaskInventoryItem item = null;
+            UUID itemID;
+            if (UUID.TryParse(itemNameorid, out itemID))
+                item = m_host.Inventory.GetInventoryItem(itemID);
+            else
+                item = m_host.Inventory.GetInventoryItem(itemNameorid);
+
+            if (item == null)
+                return String.Empty;
+
+            return item.Description;
+        }
+
+        public LSL_Key osGetLastChangedEventKey()
+        {
+            m_host.AddScriptLPS(1);
+            DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
+            if (detectedParams == null)
+                return String.Empty;
+            return detectedParams.Key.ToString();
+        }
     }
 }

+ 4 - 9
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs

@@ -48,14 +48,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             if (m_CmdManager.m_ScriptEngine.World == null)
                 return;
 
-            IHttpRequestModule iHttpReq =
-                m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
-
-            HttpRequestClass httpInfo = null;
-
-            if (iHttpReq != null)
-                httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest();
+            IHttpRequestModule iHttpReq = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
+            if(iHttpReq == null)
+                return;
 
+            HttpRequestClass httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest();
             while (httpInfo != null)
             {
                 //m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
@@ -67,8 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
                 // implemented here yet anyway.  Should be fixed if/when maxsize
                 // is supported
 
-                iHttpReq.RemoveCompletedRequest(httpInfo.ReqID);
-
                 object[] resobj = new object[]
                 {
                     new LSL_Types.LSLString(httpInfo.ReqID.ToString()),

+ 12 - 9
OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs

@@ -379,15 +379,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
 
         int osGetSimulatorMemory();
         int osGetSimulatorMemoryKB();
-        void osKickAvatar(string FirstName,string SurName,string alert);
+        void osKickAvatar(string FirstName, string SurName, string alert);
+        void osKickAvatar(LSL_Key agentId, string alert);
         void osSetSpeed(string UUID, LSL_Float SpeedModifier);
         void osSetOwnerSpeed(LSL_Float SpeedModifier);
-        LSL_Float osGetHealth(string avatar);
-        void osCauseHealing(string avatar, double healing);
-        void osSetHealth(string avatar, double health);
-        void osSetHealRate(string avatar, double health);
-        LSL_Float osGetHealRate(string avatar);
-        void osCauseDamage(string avatar, double damage);
+        LSL_Float osGetHealth(key agentId);
+        void osCauseHealing(key agentId, LSL_Float healing);
+        void osSetHealth(key agentId, LSL_Float health);
+        void osSetHealRate(key agentId, LSL_Float health);
+        LSL_Float osGetHealRate(key agentId);
+        void osCauseDamage(key avatar, LSL_Float damage);
         void osForceOtherSit(string avatar);
         void osForceOtherSit(string avatar, string target);
         LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
@@ -400,8 +401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
 
         LSL_String osUnixTimeToTimestamp(LSL_Integer time);
 
-        LSL_String osGetInventoryDesc(string item);
-
         LSL_Integer osInviteToGroup(LSL_Key agentId);
         LSL_Integer osEjectFromGroup(LSL_Key agentId);
 
@@ -546,5 +545,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
         LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin);
         LSL_Integer osApproxEquals(rotation ra, rotation rb);
         LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin);
+        LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId);
+        LSL_String osGetInventoryName(LSL_Key itemId);
+        LSL_String osGetInventoryDesc(LSL_String itemNameOrId);
+        LSL_Key osGetLastChangedEventKey();
     }
 }

+ 1 - 1
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs

@@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
     public partial class ScriptBaseClass
     {
         // SCRIPTS CONSTANTS
-        public static readonly LSLInteger OS_APIVERSION = 2;
+        public static readonly LSLInteger OS_APIVERSION = 3;
 
         public static readonly LSLInteger TRUE = 1;
         public static readonly LSLInteger FALSE = 0;

+ 32 - 12
OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs

@@ -965,11 +965,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             return m_OSSL_Functions.osGetSimulatorMemoryKB();
         }
 
-        public void osKickAvatar(string FirstName,string SurName,string alert)
+        public void osKickAvatar(string FirstName, string SurName, string alert)
         {
             m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
         }
 
+        public void osKickAvatar(LSL_Key agentId, string alert)
+        {
+            m_OSSL_Functions.osKickAvatar(agentId, alert);
+        }
+
         public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
         {
             m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
@@ -980,32 +985,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier);
         }
 
-        public LSL_Float osGetHealth(string avatar)
+        public LSL_Float osGetHealth(key avatar)
         {
             return m_OSSL_Functions.osGetHealth(avatar);
         }
 
-        public void osCauseDamage(string avatar, double damage)
+        public void osCauseDamage(key avatar, LSL_Float damage)
         {
             m_OSSL_Functions.osCauseDamage(avatar, damage);
         }
 
-        public void osCauseHealing(string avatar, double healing)
+        public void osCauseHealing(key avatar, LSL_Float healing)
         {
             m_OSSL_Functions.osCauseHealing(avatar, healing);
         }
 
-        public void osSetHealth(string avatar, double health)
+        public void osSetHealth(key avatar, LSL_Float health)
         {
             m_OSSL_Functions.osSetHealth(avatar, health);
         }
 
-        public void osSetHealRate(string avatar, double health)
+        public void osSetHealRate(key avatar, LSL_Float health)
         {
             m_OSSL_Functions.osSetHealRate(avatar, health);
         }
 
-        public LSL_Float osGetHealRate(string avatar)
+        public LSL_Float osGetHealRate(key avatar)
         {
             return m_OSSL_Functions.osGetHealRate(avatar);
         }
@@ -1055,11 +1060,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             return m_OSSL_Functions.osUnixTimeToTimestamp(time);
         }
 
-        public LSL_String osGetInventoryDesc(string item)
-        {
-            return m_OSSL_Functions.osGetInventoryDesc(item);
-        }
-
         public LSL_Integer osInviteToGroup(LSL_Key agentId)
         {
             return m_OSSL_Functions.osInviteToGroup(agentId);
@@ -1361,5 +1361,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
         {
             return m_OSSL_Functions.osApproxEquals(ra, rb, margin);
         }
+
+        public LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId)
+        {
+            return m_OSSL_Functions.osGetInventoryLastOwner(itemNameOrId);
+        }
+
+        public LSL_String osGetInventoryName(LSL_Key itemId)
+        {
+            return m_OSSL_Functions.osGetInventoryName(itemId);
+        }
+
+        public LSL_String osGetInventoryDesc(LSL_String itemNameOrId)
+        {
+            return m_OSSL_Functions.osGetInventoryDesc(itemNameOrId);
+        }
+
+        public LSL_Key osGetLastChangedEventKey()
+        {
+            return m_OSSL_Functions.osGetLastChangedEventKey();
+        }
     }
 }

+ 3 - 1
OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs

@@ -699,7 +699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
             // If min event delay is set then ignore any events untill the time has expired
             // This currently only allows 1 event of any type in the given time period.
             // This may need extending to allow for a time for each individual event type.
-            if (m_eventDelayTicks != 0)
+            if (m_eventDelayTicks != 0 && 
+                    data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit"
+                    && data.EventName != "run_time_permissions" && data.EventName != "http_request" && data.EventName != "link_message")
             {
                 if (DateTime.Now.Ticks < m_nextEventTimeTicks)
                     return;

+ 16 - 3
OpenSim/Region/ScriptEngine/XEngine/EventManager.cs

@@ -215,12 +215,25 @@ namespace OpenSim.Region.ScriptEngine.XEngine
                     det));
         }
 
-        public void changed(uint localID, uint change)
+        public void changed(uint localID, uint change, object parameter)
         {
             // Add to queue for all scripts in localID, Object pass change.
-            myScriptEngine.PostObjectEvent(localID, new EventParams(
-                    "changed",new object[] { new LSL_Types.LSLInteger(change) },
+            if(parameter == null)
+            {
+                myScriptEngine.PostObjectEvent(localID, new EventParams(
+                    "changed", new object[] { new LSL_Types.LSLInteger(change) },
                     new DetectParams[0]));
+                return;
+            }
+            if (parameter is UUID)
+            {
+                DetectParams det = new DetectParams();
+                det.Key = (UUID)parameter;
+                myScriptEngine.PostObjectEvent(localID, new EventParams(
+                    "changed", new object[] { new LSL_Types.LSLInteger(change) },
+                    new DetectParams[] { det }));
+                return;
+            }
         }
 
         // state_entry: not processed here

+ 1 - 4
OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs

@@ -88,10 +88,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
 
         path_update = 40,
 
-        // XMRE specific
-        region_cross = 63,
-
         // marks highest numbered event, ie, number of columns in seht.
-        Size = 64
+        Size = 41
     }
 }

+ 4 - 1
OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs

@@ -930,12 +930,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
 
         public void SetMinEventDelay(UUID itemID, double delay)
         {
+            XMRInstance instance = GetInstance(itemID);
+            if (instance != null)
+                instance.MinEventDelay = delay;
         }
 
         public int GetStartParameter(UUID itemID)
         {
             XMRInstance instance = GetInstance(itemID);
-            if(instance == null)
+            if (instance == null)
                 return 0;
             return instance.StartParam;
         }

+ 15 - 2
OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs

@@ -182,13 +182,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                     new DetectParams[] { det }));
         }
 
-        public void changed(uint localID, uint change)
+        public void changed(uint localID, uint change, object parameter)
         {
             int ch = (int)change;
             // Add to queue for all scripts in localID, Object pass change.
-            this.PostObjectEvent(localID, new EventParams(
+            if(parameter == null)
+            {
+                PostObjectEvent(localID, new EventParams(
                     "changed", new object[] { ch },
                     zeroDetectParams));
+                return;
+            }
+            if ( parameter is UUID)
+            {
+                DetectParams det = new DetectParams();
+                det.Key = (UUID)parameter;
+                PostObjectEvent(localID, new EventParams(
+                    "changed", new object[] { ch },
+                    new DetectParams[] { det }));
+                return;
+            }
         }
 
         // state_entry: not processed here

+ 6 - 6
OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs

@@ -422,9 +422,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                 object[] saveEHArgs = this.ehArgs;
                 ScriptEventCode saveEventCode = this.eventCode;
 
-                this.m_DetectParams = evt.DetectParams;
-                this.ehArgs = evt.Params;
-                this.eventCode = evc;
+                m_DetectParams = evt.DetectParams;
+                ehArgs = evt.Params;
+                eventCode = evc;
 
                 try
                 {
@@ -432,9 +432,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                 }
                 finally
                 {
-                    this.m_DetectParams = saveDetParams;
-                    this.ehArgs = saveEHArgs;
-                    this.eventCode = saveEventCode;
+                    m_DetectParams = saveDetParams;
+                    ehArgs = saveEHArgs;
+                    eventCode = saveEventCode;
                 }
 
                  // Keep waiting until we find a returnable event or timeout.

+ 9 - 0
OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs

@@ -115,6 +115,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                 m_RunOnePhase = "GetExecutionState D";
                 CheckRunLockInvariants(true);
 
+                if (m_minEventDelay != 0.0)
+                {
+                    XmlElement minEventDelayN = doc.CreateElement("", "mEvtDly", "");
+                    minEventDelayN.AppendChild(doc.CreateTextNode(m_minEventDelay.ToString()));
+                    scriptStateN.AppendChild(minEventDelayN);
+                    m_RunOnePhase = "GetExecutionState D";
+                    CheckRunLockInvariants(true);
+                }
+
                 // More misc data.
                 XmlNode permissionsN = doc.CreateElement("", "Permissions", "");
                 scriptStateN.AppendChild(permissionsN);

+ 9 - 0
OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs

@@ -527,6 +527,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
             XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit");
             doGblInit = bool.Parse(doGblInitN.InnerText);
 
+            double minEventDelay = 0.0;
+            XmlElement minEventDelayN = (XmlElement)scriptStateN.SelectSingleNode("mEvtDly");
+            if(minEventDelayN != null)
+                minEventDelay = Double.Parse(minEventDelayN.InnerText);
+
             // get values used by stuff like llDetectedGrab, etc.
             DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray"));
 
@@ -576,6 +581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
             AsyncCommandManager.CreateFromData(m_Engine,
                     m_LocalID, m_ItemID, m_Part.UUID,
                     pluginData);
+
+            MinEventDelay = minEventDelay;
         }
 
         private void processXstate(XmlDocument doc)
@@ -919,6 +926,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
 
             AsyncCommandManager.CreateFromData(m_Engine,
                      m_LocalID, m_ItemID, m_Part.UUID, pluginData);
+
+            MinEventDelay = minEventDelay;
         }
 
         private static void getvarNames(Dictionary<int, string> s, Dictionary<string, int> d)

+ 4 - 0
OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs

@@ -215,5 +215,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
         // It's born ready, but will be reset when the detach is posted.
         // It will then be set again on suspend/completion
         private ManualResetEvent m_DetachReady = new ManualResetEvent(true);
+
+        // llmineventdelay support
+        double m_minEventDelay = 0.0;
+        double m_nextEventTime = 0.0;
     }
 }

+ 18 - 0
OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs

@@ -298,6 +298,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine
             }
         }
 
+        public double MinEventDelay
+        {
+            get
+            {
+                return m_minEventDelay;
+            }
+            set
+            {
+                if (value > 0.001)
+                    m_minEventDelay = value;
+                else
+                    m_minEventDelay = 0.0;
+
+                m_nextEventTime = 0.0; // reset it
+            }
+        }
+
+
         public SceneObjectPart SceneObject
         {
             get

+ 44 - 6
OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs

@@ -63,8 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
          */
         public void PostEvent(EventParams evt)
         {
-            ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
-                                                                 evt.EventName);
+            ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
 
              // Put event on end of event queue.
             bool startIt = false;
@@ -86,6 +85,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                 if(!m_Running && !construct)
                     return;
 
+                if(m_minEventDelay != 0)
+                {
+                    switch (evc)
+                    {
+                        // ignore some events by time set by llMinEventDelay
+                        case ScriptEventCode.collision:
+                        case ScriptEventCode.land_collision:
+                        case ScriptEventCode.listen:
+                        case ScriptEventCode.not_at_target:
+                        case ScriptEventCode.not_at_rot_target:
+                        case ScriptEventCode.no_sensor:
+                        case ScriptEventCode.sensor:
+                        case ScriptEventCode.timer:
+                        case ScriptEventCode.touch:
+                        {
+                            double now = Util.GetTimeStamp();
+                            if (now < m_nextEventTime)
+                                return;
+                            m_nextEventTime = now + m_minEventDelay;
+                            break;
+                        }
+                        case ScriptEventCode.changed:
+                        {
+                            const int canignore = ~(CHANGED_SCALE | CHANGED_POSITION);
+                            int change = (int)evt.Params[0];
+                            if(change == 0) // what?
+                                return;
+                            if((change & canignore) == 0)
+                            {
+                                double now = Util.GetTimeStamp();
+                                if (now < m_nextEventTime)
+                                    return;
+                                m_nextEventTime = now + m_minEventDelay;
+                            }
+                            break;
+                        }
+                        default:
+                            break;
+                    }
+                }
+
                  // Only so many of each event type allowed to queue.
                 if((uint)evc < (uint)m_EventCounts.Length)
                 {
@@ -124,10 +164,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
                             for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
                             {
                                 EventParams evt2 = lln2.Value;
-                                ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
-                                                                         evt2.EventName);
-                                if((evc2 != ScriptEventCode.state_entry) &&
-                                        (evc2 != ScriptEventCode.attach))
+                                ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt2.EventName);
+                                if((evc2 != ScriptEventCode.state_entry) && (evc2 != ScriptEventCode.attach))
                                     break;
                             }
                             if(lln2 == null)

+ 8 - 0
OpenSim/Services/LLLoginService/LLLoginService.cs

@@ -757,6 +757,14 @@ namespace OpenSim.Services.LLLoginService
                                     }
                                 }
                             }
+
+                            //find a exact match
+                            foreach(GridRegion r in regions)
+                            {
+                                if(string.Equals(regionName, r.RegionName, StringComparison.InvariantCultureIgnoreCase))
+                                    return r;
+                            }
+                            // else, whatever
                             return regions[0];
                         }
                         else

BIN
bin/OpenMetaverse.dll


+ 20 - 21
bin/OpenSimDefaults.ini

@@ -661,6 +661,25 @@
     ; many simultaneous requests, default is 30 and is currently applied only to assets
     ;MaxRequestConcurrency = 30
 
+[ScriptsHttpRequestModule]
+	; options for llHttpRequest
+	
+	; max number of concurrent connections per instance (all scenes), default 8
+	; MaxPoolThreads = 8
+	
+    ; max requests per second for all scripts on a prim, default 1
+    ;PrimRequestsPerSec = 1.0
+	; initial unthrottled burst for all scripts on a prim, default 3
+    ;PrimRequestsBurst = 3.0
+
+    ; max requests per second for the objects owner (per instance), default 25
+    ;PrimOwnerRequestsPerSec = 25.0
+	; initial unthrottled burst for the objects owner (per instance), default 5
+    ;PrimOwnerRequestsBurst = 5.0
+	
+	; requests timeout in miliseconds, range 200 to 60000, default 30000
+    ;RequestsTimeOut = 30000
+	
 [AccessControl]
 	; Viewer-based access control. |-separated list of allowed viewers.
     ; AllowedClients = ""
@@ -728,17 +747,6 @@
     ;texture_default = 18500
     ;asset_default = 10500
 
-    ; Configures how ObjectUpdates are aggregated. These numbers
-    ; do not literally mean how many updates will be put in each
-    ; packet that goes over the wire, as packets are
-    ; automatically split on a 1400 byte boundary. These control
-    ; the balance between responsiveness of interest list updates
-    ; and total throughput. Higher numbers will ensure more full-
-    ; sized packets and faster sending of data, but more delay in
-    ; updating interest lists
-    ;
-    ;PrimUpdatesPerCallback = 100
-
     ; TextureSendLimit determines how many packets will be put on
     ; the outgoing queue each cycle. Like the settings above, this
     ; is a balance between responsiveness to priority updates and
@@ -748,16 +756,6 @@
     ;
     ;TextureSendLimit = 20
 
-    ; CannibalizeTextureRate allows bandwidth to be moved from the
-    ; UDP texture throttle to the task throttle. Since most viewers
-    ; use HTTP textures, this provides a means of using what is largely
-    ; unused bandwidth in the total throttle. The value is the proportion
-    ; of the texture rate to move to the task queue. It must be between
-    ; 0.0 (none of the bandwidth is cannibalized) and 0.9 (90% of the
-    ; bandwidth is grabbed)
-    ;
-    ; CannibalizeTextureRate = 0.5
-
     ; Quash and remove any light properties from attachments not on the
     ; hands. This allows flashlights and lanterns to function, but kills
     ; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps
@@ -802,6 +800,7 @@
     Cap_GetTexture = "localhost"
     Cap_GetMesh = "localhost"
     Cap_GetMesh2 = "localhost"
+    ; Cap_GetAsset = "localhost"  DO not ucoment this line. Some popular viewers still dont do it right for opensim. Here to easy testing
     Cap_GetObjectCost = ""
     Cap_GetObjectPhysicsData = ""
     Cap_GroupProposalBallot = ""

+ 58 - 32
bin/ScriptSyntax.xml

@@ -1,4 +1,4 @@
-a0b4b514-3c14-6b98-ca98-e18a79e9792f
+20392e48-fad2-094e-bc5b-cda003a1e940
 <llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer>
 <key>controls</key>
 <map>
@@ -1513,7 +1513,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  </map>
  <key>OS_APIVERSION</key><map>
   <key>type</key><string>integer</string>
-  <key>value</key><string>2</string>
+  <key>value</key><string>3</string>
  </map>
  <key>OS_ATTACH_MSG_ALL</key><map>
   <key>type</key><string>integer</string>
@@ -6114,34 +6114,34 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
-   <map><key>va</key><map><key>type</key><string>vector</string></map></map>
-   <map><key>vb</key><map><key>type</key><string>vector</string></map></map>
-   <map><key>margin</key><map><key>type</key><string>float</string></map></map>
+   <map><key>a</key><map><key>type</key><string>float</string></map></map>
+   <map><key>b</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
  <key>osApproxEquals</key>
  <map>
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
-   <map><key>va</key><map><key>type</key><string>vector</string></map></map>
-   <map><key>vb</key><map><key>type</key><string>vector</string></map></map>
+   <map><key>a</key><map><key>type</key><string>float</string></map></map>
+   <map><key>b</key><map><key>type</key><string>float</string></map></map>
+   <map><key>margin</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
  <key>osApproxEquals</key>
  <map>
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
-   <map><key>a</key><map><key>type</key><string>float</string></map></map>
-   <map><key>b</key><map><key>type</key><string>float</string></map></map>
-   <map><key>margin</key><map><key>type</key><string>float</string></map></map>
+   <map><key>ra</key><map><key>type</key><string>rotation</string></map></map>
+   <map><key>rb</key><map><key>type</key><string>rotation</string></map></map>
   </array>
  </map>
  <key>osApproxEquals</key>
  <map>
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
-   <map><key>a</key><map><key>type</key><string>float</string></map></map>
-   <map><key>b</key><map><key>type</key><string>float</string></map></map>
+   <map><key>va</key><map><key>type</key><string>vector</string></map></map>
+   <map><key>vb</key><map><key>type</key><string>vector</string></map></map>
+   <map><key>margin</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
  <key>osApproxEquals</key>
@@ -6157,8 +6157,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
-   <map><key>ra</key><map><key>type</key><string>rotation</string></map></map>
-   <map><key>rb</key><map><key>type</key><string>rotation</string></map></map>
+   <map><key>va</key><map><key>type</key><string>vector</string></map></map>
+   <map><key>vb</key><map><key>type</key><string>vector</string></map></map>
   </array>
  </map>
  <key>osAvatarName2Key</key>
@@ -6186,14 +6186,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <key>osCauseDamage</key>
  <map>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>avatar</key><map><key>type</key><string>key</string></map></map>
    <map><key>damage</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
  <key>osCauseHealing</key>
  <map>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
    <map><key>healing</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
@@ -6284,8 +6284,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>return</key><string>string</string>
   <key>arguments</key><array>
    <map><key>drawList</key><map><key>type</key><string>string</string></map></map>
-   <map><key>startX</key><map><key>type</key><string>integer</string></map></map>
-   <map><key>startY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>endX</key><map><key>type</key><string>integer</string></map></map>
    <map><key>endY</key><map><key>type</key><string>integer</string></map></map>
   </array>
@@ -6295,6 +6293,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>return</key><string>string</string>
   <key>arguments</key><array>
    <map><key>drawList</key><map><key>type</key><string>string</string></map></map>
+   <map><key>startX</key><map><key>type</key><string>integer</string></map></map>
+   <map><key>startY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>endX</key><map><key>type</key><string>integer</string></map></map>
    <map><key>endY</key><map><key>type</key><string>integer</string></map></map>
   </array>
@@ -6539,14 +6539,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>return</key><string>float</string>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
   </array>
  </map>
  <key>osGetHealth</key>
  <map>
   <key>return</key><string>float</string>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
   </array>
  </map>
  <key>osGetInertiaData</key>
@@ -6558,9 +6558,28 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>return</key><string>string</string>
   <key>arguments</key><array>
-   <map><key>item</key><map><key>type</key><string>string</string></map></map>
+   <map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map>
+  </array>
+ </map>
+ <key>osGetInventoryLastOwner</key>
+ <map>
+  <key>return</key><string>key</string>
+  <key>arguments</key><array>
+   <map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map>
   </array>
  </map>
+ <key>osGetInventoryName</key>
+ <map>
+  <key>return</key><string>string</string>
+  <key>arguments</key><array>
+   <map><key>itemId</key><map><key>type</key><string>key</string></map></map>
+  </array>
+ </map>
+ <key>osGetLastChangedEventKey</key>
+ <map>
+  <key>return</key><string>key</string>
+  <key>arguments</key><undef/>
+ </map>
  <key>osGetLinkNumber</key>
  <map>
   <key>return</key><string>integer</string>
@@ -6735,6 +6754,13 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
    <map><key>alert</key><map><key>type</key><string>string</string></map></map>
   </array>
  </map>
+ <key>osKickAvatar</key>
+ <map>
+  <key>arguments</key><array>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
+   <map><key>alert</key><map><key>type</key><string>string</string></map></map>
+  </array>
+ </map>
  <key>osLoadedCreationDate</key>
  <map>
   <key>return</key><string>string</string>
@@ -6839,7 +6865,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
    <map><key>name</key><map><key>type</key><string>string</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>notecard</key><map><key>type</key><string>string</string></map></map>
-   <map><key>options</key><map><key>type</key><string>integer</string></map></map>
   </array>
  </map>
  <key>osNpcCreate</key>
@@ -6850,6 +6875,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
    <map><key>name</key><map><key>type</key><string>string</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>notecard</key><map><key>type</key><string>string</string></map></map>
+   <map><key>options</key><map><key>type</key><string>integer</string></map></map>
   </array>
  </map>
  <key>osNpcGetOwner</key>
@@ -7089,7 +7115,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
    <map><key>seconds</key><map><key>type</key><string>float</string></map></map>
-   <map><key>msg</key><map><key>type</key><string>string</string></map></map>
   </array>
  </map>
  <key>osRegionRestart</key>
@@ -7097,6 +7122,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>return</key><string>integer</string>
   <key>arguments</key><array>
    <map><key>seconds</key><map><key>type</key><string>float</string></map></map>
+   <map><key>msg</key><map><key>type</key><string>string</string></map></map>
   </array>
  </map>
  <key>osReplaceString</key>
@@ -7199,14 +7225,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <key>osSetHealRate</key>
  <map>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
    <map><key>health</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
  <key>osSetHealth</key>
  <map>
   <key>arguments</key><array>
-   <map><key>avatar</key><map><key>type</key><string>string</string></map></map>
+   <map><key>agentId</key><map><key>type</key><string>key</string></map></map>
    <map><key>health</key><map><key>type</key><string>float</string></map></map>
   </array>
  </map>
@@ -7432,6 +7458,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>arguments</key><array>
    <map><key>src</key><map><key>type</key><string>string</string></map></map>
    <map><key>value</key><map><key>type</key><string>string</string></map></map>
+   <map><key>start</key><map><key>type</key><string>integer</string></map></map>
+   <map><key>count</key><map><key>type</key><string>integer</string></map></map>
    <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
   </array>
  </map>
@@ -7441,8 +7469,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
   <key>arguments</key><array>
    <map><key>src</key><map><key>type</key><string>string</string></map></map>
    <map><key>value</key><map><key>type</key><string>string</string></map></map>
-   <map><key>start</key><map><key>type</key><string>integer</string></map></map>
-   <map><key>count</key><map><key>type</key><string>integer</string></map></map>
    <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map>
   </array>
  </map>
@@ -7528,7 +7554,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>arguments</key><array>
    <map><key>agent</key><map><key>type</key><string>string</string></map></map>
-   <map><key>regionName</key><map><key>type</key><string>string</string></map></map>
+   <map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
+   <map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
   </array>
@@ -7537,8 +7564,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>arguments</key><array>
    <map><key>agent</key><map><key>type</key><string>string</string></map></map>
-   <map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
-   <map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
   </array>
@@ -7547,6 +7572,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <map>
   <key>arguments</key><array>
    <map><key>agent</key><map><key>type</key><string>string</string></map></map>
+   <map><key>regionName</key><map><key>type</key><string>string</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
   </array>
@@ -7564,8 +7590,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <key>osTeleportOwner</key>
  <map>
   <key>arguments</key><array>
-   <map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
-   <map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
   </array>
@@ -7581,6 +7605,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f
  <key>osTeleportOwner</key>
  <map>
   <key>arguments</key><array>
+   <map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
+   <map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
    <map><key>position</key><map><key>type</key><string>vector</string></map></map>
    <map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
   </array>

+ 2 - 2
bin/config-include/osslEnable.ini

@@ -155,7 +155,6 @@
   Allow_osForceDropAttachmentAt =   ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
   Allow_osGetLinkPrimitiveParams =  ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
   Allow_osGetPhysicsEngineType =    true
-  Allow_osGetPrimitiveParams =      ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
   Allow_osGetRegionMapTexture =     ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER
   Allow_osGetScriptEngineName =     true
   Allow_osGetSimulatorVersion =     true
@@ -185,7 +184,6 @@
   Allow_osParcelSubdivide =         ESTATE_MANAGER,ESTATE_OWNER
   Allow_osRegionRestart =           ESTATE_MANAGER,ESTATE_OWNER
   Allow_osRegionNotice =            ESTATE_MANAGER,ESTATE_OWNER
-  Allow_osSetPrimitiveParams =      false
   Allow_osSetProjectionParams =     ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER
   Allow_osSetRegionWaterHeight =    ESTATE_MANAGER,ESTATE_OWNER
   Allow_osSetStateEvents =          false   ; deprecated
@@ -250,6 +248,7 @@
 ;  Allow_osGetLinkNumber =           true
 ;  Allow_osGetMapTexture =           true
 ;  Allow_osGetPhysicsEngineName =    true
+;  Allow_osGetPrimitiveParams =      true
 ;  Allow_osGetRegionSize =           true
 ;  Allow_osGetSunParam =             true
 ;  Allow_osGetTerrainHeight =        true
@@ -275,6 +274,7 @@
 ;  Allow_osSetPenCap =               true
 ;  Allow_osSetPenColor =             true
 ;  Allow_osSetPenSize =              true
+;  Allow_osSetPrimitiveParams =      true
 ;  Allow_osSetSoundRadius =          true
 ;  Allow_osStopSound =               true
 ;  Allow_osStringSubString =         true

Some files were not shown because too many files changed in this diff