diff options
61 files changed, 2419 insertions, 1150 deletions
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index c5d7c47..3db30d8 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs | |||
@@ -1403,7 +1403,10 @@ namespace OpenSim.Data.MySQL | |||
1403 | 1403 | ||
1404 | prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString()); | 1404 | prim.Sound = DBGuid.FromDB(row["LoopedSound"].ToString()); |
1405 | prim.SoundGain = (float)(double)row["LoopedSoundGain"]; | 1405 | prim.SoundGain = (float)(double)row["LoopedSoundGain"]; |
1406 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | 1406 | if (prim.Sound != UUID.Zero) |
1407 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1408 | else | ||
1409 | prim.SoundFlags = 0; | ||
1407 | 1410 | ||
1408 | if (!(row["TextureAnimation"] is DBNull)) | 1411 | if (!(row["TextureAnimation"] is DBNull)) |
1409 | prim.TextureAnimation = (byte[])row["TextureAnimation"]; | 1412 | prim.TextureAnimation = (byte[])row["TextureAnimation"]; |
diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 569cc80..99ceb91 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs | |||
@@ -1742,7 +1742,10 @@ namespace OpenSim.Data.PGSQL | |||
1742 | 1742 | ||
1743 | prim.Sound = new UUID((Guid)primRow["LoopedSound"]); | 1743 | prim.Sound = new UUID((Guid)primRow["LoopedSound"]); |
1744 | prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); | 1744 | prim.SoundGain = Convert.ToSingle(primRow["LoopedSoundGain"]); |
1745 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | 1745 | if (prim.Sound != UUID.Zero) |
1746 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1747 | else | ||
1748 | prim.SoundFlags = 0; | ||
1746 | 1749 | ||
1747 | if (!(primRow["TextureAnimation"] is DBNull)) | 1750 | if (!(primRow["TextureAnimation"] is DBNull)) |
1748 | prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; | 1751 | prim.TextureAnimation = (Byte[])primRow["TextureAnimation"]; |
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index e02ac7d..1403a8f 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs | |||
@@ -1742,7 +1742,10 @@ namespace OpenSim.Data.SQLite | |||
1742 | 1742 | ||
1743 | prim.Sound = new UUID(row["LoopedSound"].ToString()); | 1743 | prim.Sound = new UUID(row["LoopedSound"].ToString()); |
1744 | prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); | 1744 | prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); |
1745 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | 1745 | if (prim.Sound != UUID.Zero) |
1746 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1747 | else | ||
1748 | prim.SoundFlags = 0; | ||
1746 | 1749 | ||
1747 | if (!row.IsNull("TextureAnimation")) | 1750 | if (!row.IsNull("TextureAnimation")) |
1748 | prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString()); | 1751 | prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString()); |
diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs index 45c54e4..1508c7f 100644 --- a/OpenSim/Framework/ClientManager.cs +++ b/OpenSim/Framework/ClientManager.cs | |||
@@ -51,7 +51,14 @@ namespace OpenSim.Framework | |||
51 | private object m_syncRoot = new object(); | 51 | private object m_syncRoot = new object(); |
52 | 52 | ||
53 | /// <summary>Number of clients in the collection</summary> | 53 | /// <summary>Number of clients in the collection</summary> |
54 | public int Count { get { return m_dict1.Count; } } | 54 | public int Count |
55 | { | ||
56 | get | ||
57 | { | ||
58 | lock (m_syncRoot) | ||
59 | return m_dict1.Count; | ||
60 | } | ||
61 | } | ||
55 | 62 | ||
56 | /// <summary> | 63 | /// <summary> |
57 | /// Default constructor | 64 | /// Default constructor |
@@ -60,7 +67,7 @@ namespace OpenSim.Framework | |||
60 | { | 67 | { |
61 | m_dict1 = new Dictionary<UUID, IClientAPI>(); | 68 | m_dict1 = new Dictionary<UUID, IClientAPI>(); |
62 | m_dict2 = new Dictionary<IPEndPoint, IClientAPI>(); | 69 | m_dict2 = new Dictionary<IPEndPoint, IClientAPI>(); |
63 | m_array = new IClientAPI[0]; | 70 | m_array = null; |
64 | } | 71 | } |
65 | 72 | ||
66 | /// <summary> | 73 | /// <summary> |
@@ -74,17 +81,9 @@ namespace OpenSim.Framework | |||
74 | { | 81 | { |
75 | lock (m_syncRoot) | 82 | lock (m_syncRoot) |
76 | { | 83 | { |
77 | // allow self healing | ||
78 | // if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) | ||
79 | // return false; | ||
80 | |||
81 | m_dict1[value.AgentId] = value; | 84 | m_dict1[value.AgentId] = value; |
82 | m_dict2[value.RemoteEndPoint] = value; | 85 | m_dict2[value.RemoteEndPoint] = value; |
83 | 86 | m_array = null; | |
84 | // dict1 is the master | ||
85 | IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; | ||
86 | m_dict1.Values.CopyTo(newArray, 0); | ||
87 | m_array = newArray; | ||
88 | } | 87 | } |
89 | 88 | ||
90 | return true; | 89 | return true; |
@@ -105,10 +104,7 @@ namespace OpenSim.Framework | |||
105 | { | 104 | { |
106 | m_dict1.Remove(key); | 105 | m_dict1.Remove(key); |
107 | m_dict2.Remove(value.RemoteEndPoint); | 106 | m_dict2.Remove(value.RemoteEndPoint); |
108 | 107 | m_array = null; | |
109 | IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; | ||
110 | m_dict1.Values.CopyTo(newArray, 0); | ||
111 | m_array = newArray; | ||
112 | return true; | 108 | return true; |
113 | } | 109 | } |
114 | } | 110 | } |
@@ -124,7 +120,7 @@ namespace OpenSim.Framework | |||
124 | { | 120 | { |
125 | m_dict1.Clear(); | 121 | m_dict1.Clear(); |
126 | m_dict2.Clear(); | 122 | m_dict2.Clear(); |
127 | m_array = new IClientAPI[0]; | 123 | m_array = null; |
128 | } | 124 | } |
129 | } | 125 | } |
130 | 126 | ||
@@ -135,7 +131,8 @@ namespace OpenSim.Framework | |||
135 | /// <returns>True if the UUID was found in the collection, otherwise false</returns> | 131 | /// <returns>True if the UUID was found in the collection, otherwise false</returns> |
136 | public bool ContainsKey(UUID key) | 132 | public bool ContainsKey(UUID key) |
137 | { | 133 | { |
138 | return m_dict1.ContainsKey(key); | 134 | lock (m_syncRoot) |
135 | return m_dict1.ContainsKey(key); | ||
139 | } | 136 | } |
140 | 137 | ||
141 | /// <summary> | 138 | /// <summary> |
@@ -145,7 +142,8 @@ namespace OpenSim.Framework | |||
145 | /// <returns>True if the endpoint was found in the collection, otherwise false</returns> | 142 | /// <returns>True if the endpoint was found in the collection, otherwise false</returns> |
146 | public bool ContainsKey(IPEndPoint key) | 143 | public bool ContainsKey(IPEndPoint key) |
147 | { | 144 | { |
148 | return m_dict2.ContainsKey(key); | 145 | lock (m_syncRoot) |
146 | return m_dict2.ContainsKey(key); | ||
149 | } | 147 | } |
150 | 148 | ||
151 | /// <summary> | 149 | /// <summary> |
@@ -156,8 +154,12 @@ namespace OpenSim.Framework | |||
156 | /// <returns>True if the lookup succeeded, otherwise false</returns> | 154 | /// <returns>True if the lookup succeeded, otherwise false</returns> |
157 | public bool TryGetValue(UUID key, out IClientAPI value) | 155 | public bool TryGetValue(UUID key, out IClientAPI value) |
158 | { | 156 | { |
159 | try { return m_dict1.TryGetValue(key, out value); } | 157 | try |
160 | catch (Exception) | 158 | { |
159 | lock (m_syncRoot) | ||
160 | return m_dict1.TryGetValue(key, out value); | ||
161 | } | ||
162 | catch | ||
161 | { | 163 | { |
162 | value = null; | 164 | value = null; |
163 | return false; | 165 | return false; |
@@ -172,8 +174,12 @@ namespace OpenSim.Framework | |||
172 | /// <returns>True if the lookup succeeded, otherwise false</returns> | 174 | /// <returns>True if the lookup succeeded, otherwise false</returns> |
173 | public bool TryGetValue(IPEndPoint key, out IClientAPI value) | 175 | public bool TryGetValue(IPEndPoint key, out IClientAPI value) |
174 | { | 176 | { |
175 | try { return m_dict2.TryGetValue(key, out value); } | 177 | try |
176 | catch (Exception) | 178 | { |
179 | lock (m_syncRoot) | ||
180 | return m_dict2.TryGetValue(key, out value); | ||
181 | } | ||
182 | catch | ||
177 | { | 183 | { |
178 | value = null; | 184 | value = null; |
179 | return false; | 185 | return false; |
@@ -187,7 +193,20 @@ namespace OpenSim.Framework | |||
187 | /// <param name="action">Action to perform on each element</param> | 193 | /// <param name="action">Action to perform on each element</param> |
188 | public void ForEach(Action<IClientAPI> action) | 194 | public void ForEach(Action<IClientAPI> action) |
189 | { | 195 | { |
190 | IClientAPI[] localArray = m_array; | 196 | IClientAPI[] localArray; |
197 | lock (m_syncRoot) | ||
198 | { | ||
199 | if (m_array == null) | ||
200 | { | ||
201 | if (m_dict1.Count == 0) | ||
202 | return; | ||
203 | |||
204 | m_array = new IClientAPI[m_dict1.Count]; | ||
205 | m_dict1.Values.CopyTo(m_array, 0); | ||
206 | } | ||
207 | localArray = m_array; | ||
208 | } | ||
209 | |||
191 | for (int i = 0; i < localArray.Length; i++) | 210 | for (int i = 0; i < localArray.Length; i++) |
192 | action(localArray[i]); | 211 | action(localArray[i]); |
193 | } | 212 | } |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 307dbf3..d63136e 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -390,7 +390,7 @@ namespace OpenSim.Framework | |||
390 | IClientAPI remoteClient, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics); | 390 | IClientAPI remoteClient, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics); |
391 | 391 | ||
392 | public delegate void EstateTeleportOneUserHomeRequest( | 392 | public delegate void EstateTeleportOneUserHomeRequest( |
393 | IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey); | 393 | IClientAPI remoteClient, UUID invoice, UUID senderID, UUID prey, bool kill); |
394 | 394 | ||
395 | public delegate void EstateTeleportAllUsersHomeRequest(IClientAPI remoteClient, UUID invoice, UUID senderID); | 395 | public delegate void EstateTeleportAllUsersHomeRequest(IClientAPI remoteClient, UUID invoice, UUID senderID); |
396 | 396 | ||
@@ -671,7 +671,6 @@ namespace OpenSim.Framework | |||
671 | Particles = 1 << 19, | 671 | Particles = 1 << 19, |
672 | ExtraData = 1 << 20, | 672 | ExtraData = 1 << 20, |
673 | Sound = 1 << 21, | 673 | Sound = 1 << 21, |
674 | Joint = 1 << 22, | ||
675 | 674 | ||
676 | TerseUpdate = Position | Rotation | Velocity | Acceleration | AngularVelocity, | 675 | TerseUpdate = Position | Rotation | Velocity | Acceleration | AngularVelocity, |
677 | FullUpdate = 0x00ffffff, | 676 | FullUpdate = 0x00ffffff, |
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index b9ac155..14e21a2 100644..100755 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -230,25 +230,25 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
230 | PollServiceHttpRequest req; | 230 | PollServiceHttpRequest req; |
231 | while (m_running) | 231 | while (m_running) |
232 | { | 232 | { |
233 | req = null; | 233 | try |
234 | if(!m_requests.TryTake(out req, 4500) || req == null) | ||
235 | { | 234 | { |
236 | Watchdog.UpdateThread(); | 235 | req = null; |
237 | continue; | 236 | if (!m_requests.TryTake(out req, 4500) || req == null) |
238 | } | 237 | { |
238 | Watchdog.UpdateThread(); | ||
239 | continue; | ||
240 | } | ||
239 | 241 | ||
240 | Watchdog.UpdateThread(); | 242 | Watchdog.UpdateThread(); |
241 | 243 | ||
242 | try | 244 | if (!req.HttpContext.CanSend()) |
243 | { | ||
244 | if(!req.HttpContext.CanSend()) | ||
245 | { | 245 | { |
246 | req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); | 246 | req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); |
247 | byContextDequeue(req); | 247 | byContextDequeue(req); |
248 | continue; | 248 | continue; |
249 | } | 249 | } |
250 | 250 | ||
251 | if(req.HttpContext.IsSending()) | 251 | if (req.HttpContext.IsSending()) |
252 | { | 252 | { |
253 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) | 253 | if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) |
254 | { | 254 | { |
@@ -256,7 +256,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
256 | byContextDequeue(req); | 256 | byContextDequeue(req); |
257 | } | 257 | } |
258 | else | 258 | else |
259 | ReQueueEvent(req); | 259 | ReQueueEvent(req); |
260 | continue; | 260 | continue; |
261 | } | 261 | } |
262 | 262 | ||
@@ -290,7 +290,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
290 | { | 290 | { |
291 | nreq.DoHTTPGruntWork(nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id)); | 291 | nreq.DoHTTPGruntWork(nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id)); |
292 | } | 292 | } |
293 | catch (ObjectDisposedException) {} | 293 | catch (ObjectDisposedException) { } |
294 | finally | 294 | finally |
295 | { | 295 | { |
296 | byContextDequeue(nreq); | 296 | byContextDequeue(nreq); |
@@ -305,6 +305,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | } | 307 | } |
308 | catch (ThreadAbortException) | ||
309 | { | ||
310 | Thread.ResetAbort(); | ||
311 | // Shouldn't set this to 'false', the normal shutdown should cause things to exit | ||
312 | // m_running = false; | ||
313 | } | ||
308 | catch (Exception e) | 314 | catch (Exception e) |
309 | { | 315 | { |
310 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); | 316 | m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); |
diff --git a/OpenSim/Framework/TerrainData.cs b/OpenSim/Framework/TerrainData.cs index 5604628..1a2d5d1 100644 --- a/OpenSim/Framework/TerrainData.cs +++ b/OpenSim/Framework/TerrainData.cs | |||
@@ -212,7 +212,6 @@ namespace OpenSim.Framework | |||
212 | return heights; | 212 | return heights; |
213 | } | 213 | } |
214 | 214 | ||
215 | // TerrainData.GetDoubles | ||
216 | public double[,] GetDoubles() | 215 | public double[,] GetDoubles() |
217 | { | 216 | { |
218 | double[,] ret = new double[SizeX, SizeY]; | 217 | double[,] ret = new double[SizeX, SizeY]; |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 52f9aea..f66a987 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -2437,34 +2437,6 @@ namespace OpenSim.Framework | |||
2437 | 2437 | ||
2438 | #region FireAndForget Threading Pattern | 2438 | #region FireAndForget Threading Pattern |
2439 | 2439 | ||
2440 | /// <summary> | ||
2441 | /// Created to work around a limitation in Mono with nested delegates | ||
2442 | /// </summary> | ||
2443 | private sealed class FireAndForgetWrapper | ||
2444 | { | ||
2445 | private static object syncRoot = new Object(); | ||
2446 | |||
2447 | public void FireAndForget(System.Threading.WaitCallback callback) | ||
2448 | { | ||
2449 | callback.BeginInvoke(null, EndFireAndForget, callback); | ||
2450 | } | ||
2451 | |||
2452 | public void FireAndForget(System.Threading.WaitCallback callback, object obj) | ||
2453 | { | ||
2454 | callback.BeginInvoke(obj, EndFireAndForget, callback); | ||
2455 | } | ||
2456 | |||
2457 | private static void EndFireAndForget(IAsyncResult ar) | ||
2458 | { | ||
2459 | System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; | ||
2460 | |||
2461 | try { callback.EndInvoke(ar); } | ||
2462 | catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } | ||
2463 | |||
2464 | ar.AsyncWaitHandle.Close(); | ||
2465 | } | ||
2466 | } | ||
2467 | |||
2468 | public static void InitThreadPool(int minThreads, int maxThreads) | 2440 | public static void InitThreadPool(int minThreads, int maxThreads) |
2469 | { | 2441 | { |
2470 | if (maxThreads < 2) | 2442 | if (maxThreads < 2) |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs index 9187979..c071bd1 100644..100755 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetAssetsModule.cs | |||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
59 | private string m_GetTextureURL; | 59 | private string m_GetTextureURL; |
60 | private string m_GetMeshURL; | 60 | private string m_GetMeshURL; |
61 | private string m_GetMesh2URL; | 61 | private string m_GetMesh2URL; |
62 | // private string m_GetAssetURL; | 62 | private string m_GetAssetURL; |
63 | 63 | ||
64 | class APollRequest | 64 | class APollRequest |
65 | { | 65 | { |
@@ -87,7 +87,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
87 | private Dictionary<UUID, string> m_capsDictTexture = new Dictionary<UUID, string>(); | 87 | private Dictionary<UUID, string> m_capsDictTexture = new Dictionary<UUID, string>(); |
88 | private Dictionary<UUID, string> m_capsDictGetMesh = new Dictionary<UUID, string>(); | 88 | private Dictionary<UUID, string> m_capsDictGetMesh = new Dictionary<UUID, string>(); |
89 | private Dictionary<UUID, string> m_capsDictGetMesh2 = new Dictionary<UUID, string>(); | 89 | private Dictionary<UUID, string> m_capsDictGetMesh2 = new Dictionary<UUID, string>(); |
90 | //private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>(); | 90 | private Dictionary<UUID, string> m_capsDictGetAsset = new Dictionary<UUID, string>(); |
91 | 91 | ||
92 | #region Region Module interfaceBase Members | 92 | #region Region Module interfaceBase Members |
93 | 93 | ||
@@ -113,11 +113,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
113 | m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty); | 113 | m_GetMesh2URL = config.GetString("Cap_GetMesh2", string.Empty); |
114 | if (m_GetMesh2URL != string.Empty) | 114 | if (m_GetMesh2URL != string.Empty) |
115 | m_Enabled = true; | 115 | m_Enabled = true; |
116 | /* | 116 | |
117 | m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty); | 117 | m_GetAssetURL = config.GetString("Cap_GetAsset", string.Empty); |
118 | if (m_GetAssetURL != string.Empty) | 118 | if (m_GetAssetURL != string.Empty) |
119 | m_Enabled = true; | 119 | m_Enabled = true; |
120 | */ | 120 | |
121 | } | 121 | } |
122 | 122 | ||
123 | public void AddRegion(Scene pScene) | 123 | public void AddRegion(Scene pScene) |
@@ -204,19 +204,26 @@ namespace OpenSim.Region.ClientStack.Linden | |||
204 | 204 | ||
205 | private static void DoAssetRequests() | 205 | private static void DoAssetRequests() |
206 | { | 206 | { |
207 | while (m_NumberScenes > 0) | 207 | try |
208 | { | 208 | { |
209 | APollRequest poolreq; | 209 | while (m_NumberScenes > 0) |
210 | if(m_queue.TryTake(out poolreq, 4500)) | ||
211 | { | 210 | { |
212 | if (m_NumberScenes <= 0) | 211 | APollRequest poolreq; |
213 | break; | 212 | if (m_queue.TryTake(out poolreq, 4500)) |
213 | { | ||
214 | if (m_NumberScenes <= 0) | ||
215 | break; | ||
216 | Watchdog.UpdateThread(); | ||
217 | if (poolreq.reqID != UUID.Zero) | ||
218 | poolreq.thepoll.Process(poolreq); | ||
219 | poolreq = null; | ||
220 | } | ||
214 | Watchdog.UpdateThread(); | 221 | Watchdog.UpdateThread(); |
215 | if (poolreq.reqID != UUID.Zero) | ||
216 | poolreq.thepoll.Process(poolreq); | ||
217 | poolreq = null; | ||
218 | } | 222 | } |
219 | Watchdog.UpdateThread(); | 223 | } |
224 | catch (ThreadAbortException) | ||
225 | { | ||
226 | Thread.ResetAbort(); | ||
220 | } | 227 | } |
221 | } | 228 | } |
222 | 229 | ||
@@ -441,7 +448,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
441 | else if (m_GetMesh2URL != string.Empty) | 448 | else if (m_GetMesh2URL != string.Empty) |
442 | caps.RegisterHandler("GetMesh2", m_GetMesh2URL); | 449 | caps.RegisterHandler("GetMesh2", m_GetMesh2URL); |
443 | 450 | ||
444 | /* we can't support this cap. Current viewers connect to the wrong regions. | ||
445 | //ViewerAsset | 451 | //ViewerAsset |
446 | if (m_GetAssetURL == "localhost") | 452 | if (m_GetAssetURL == "localhost") |
447 | { | 453 | { |
@@ -459,7 +465,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
459 | } | 465 | } |
460 | else if (m_GetAssetURL != string.Empty) | 466 | else if (m_GetAssetURL != string.Empty) |
461 | caps.RegisterHandler("ViewerAsset", m_GetMesh2URL); | 467 | caps.RegisterHandler("ViewerAsset", m_GetMesh2URL); |
462 | */ | 468 | |
463 | } | 469 | } |
464 | 470 | ||
465 | private void DeregisterCaps(UUID agentID, Caps caps) | 471 | private void DeregisterCaps(UUID agentID, Caps caps) |
@@ -480,13 +486,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
480 | MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); | 486 | MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); |
481 | m_capsDictGetMesh2.Remove(agentID); | 487 | m_capsDictGetMesh2.Remove(agentID); |
482 | } | 488 | } |
483 | /* | 489 | |
484 | if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl)) | 490 | if (m_capsDictGetAsset.TryGetValue(agentID, out capUrl)) |
485 | { | 491 | { |
486 | MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); | 492 | MainServer.Instance.RemovePollServiceHTTPHandler("", capUrl); |
487 | m_capsDictGetAsset.Remove(agentID); | 493 | m_capsDictGetAsset.Remove(agentID); |
488 | } | 494 | } |
489 | */ | ||
490 | } | 495 | } |
491 | } | 496 | } |
492 | } | 497 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 41d70a3..9a01567 100644..100755 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -395,17 +395,26 @@ namespace OpenSim.Region.ClientStack.Linden | |||
395 | 395 | ||
396 | private static void DoInventoryRequests() | 396 | private static void DoInventoryRequests() |
397 | { | 397 | { |
398 | while (true) | 398 | bool running = true; |
399 | while (running) | ||
399 | { | 400 | { |
400 | APollRequest poolreq; | 401 | try |
401 | if (m_queue.TryTake(out poolreq, 4500)) | ||
402 | { | 402 | { |
403 | APollRequest poolreq; | ||
404 | if (m_queue.TryTake(out poolreq, 4500)) | ||
405 | { | ||
406 | Watchdog.UpdateThread(); | ||
407 | if (poolreq.thepoll != null) | ||
408 | poolreq.thepoll.Process(poolreq); | ||
409 | poolreq = null; | ||
410 | } | ||
403 | Watchdog.UpdateThread(); | 411 | Watchdog.UpdateThread(); |
404 | if (poolreq.thepoll != null) | ||
405 | poolreq.thepoll.Process(poolreq); | ||
406 | poolreq = null; | ||
407 | } | 412 | } |
408 | Watchdog.UpdateThread(); | 413 | catch (ThreadAbortException) |
414 | { | ||
415 | Thread.ResetAbort(); | ||
416 | running = false; | ||
417 | } | ||
409 | } | 418 | } |
410 | } | 419 | } |
411 | } | 420 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index b7d5a80..ac041f5 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -1257,6 +1257,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1257 | SendLayerTopRight(x1 + 1, y1, x2, y2 - 1); | 1257 | SendLayerTopRight(x1 + 1, y1, x2, y2 - 1); |
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | static private readonly byte[] TerrainPacketHeader = new byte[] { | ||
1261 | Helpers.MSG_RELIABLE, // zero code is not as spec | ||
1262 | 0, 0, 0, 0, // sequence number | ||
1263 | 0, // extra | ||
1264 | 11, // ID (high frequency) | ||
1265 | }; | ||
1266 | |||
1267 | private const int END_OF_PATCHES = 97; | ||
1268 | private const int STRIDE = 264; | ||
1269 | |||
1260 | public void SendLayerData(int[] map) | 1270 | public void SendLayerData(int[] map) |
1261 | { | 1271 | { |
1262 | if(map == null) | 1272 | if(map == null) |
@@ -1264,9 +1274,75 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1264 | 1274 | ||
1265 | try | 1275 | try |
1266 | { | 1276 | { |
1267 | List<LayerDataPacket> packets = OpenSimTerrainCompressor.CreateLayerDataPackets(m_scene.Heightmap.GetTerrainData(), map); | 1277 | TerrainData terrData = m_scene.Heightmap.GetTerrainData(); |
1268 | foreach (LayerDataPacket pkt in packets) | 1278 | byte landPacketType = (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) ? |
1269 | OutPacket(pkt, ThrottleOutPacketType.Land); | 1279 | (byte)TerrainPatch.LayerType.LandExtended : (byte)TerrainPatch.LayerType.Land; |
1280 | |||
1281 | int numberPatchs = map.Length / 2; | ||
1282 | |||
1283 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
1284 | byte[] data = buf.Data; | ||
1285 | |||
1286 | Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); | ||
1287 | |||
1288 | data[7] = landPacketType; | ||
1289 | //data[8] and data[9] == datablock size to fill later | ||
1290 | |||
1291 | data[10] = 0; // BitPack needs this on reused packets | ||
1292 | |||
1293 | // start data | ||
1294 | BitPack bitpack = new BitPack(data, 10); | ||
1295 | bitpack.PackBits(STRIDE, 16); | ||
1296 | bitpack.PackBitsFromByte(16); | ||
1297 | bitpack.PackBitsFromByte(landPacketType); | ||
1298 | |||
1299 | int s; | ||
1300 | int datasize = 0; | ||
1301 | for (int i = 0; i < numberPatchs; i++) | ||
1302 | { | ||
1303 | s = 2 * i; | ||
1304 | OpenSimTerrainCompressor.CreatePatchFromTerrainData(bitpack, terrData, map[s], map[s + 1]); | ||
1305 | if (bitpack.BytePos > 950 && i != numberPatchs - 1) | ||
1306 | { | ||
1307 | //finish this packet | ||
1308 | bitpack.PackBitsFromByte(END_OF_PATCHES); | ||
1309 | |||
1310 | // fix the datablock lenght | ||
1311 | datasize = bitpack.BytePos - 9; | ||
1312 | data[8] = (byte)datasize; | ||
1313 | data[9] = (byte)(datasize >> 8); | ||
1314 | |||
1315 | buf.DataLength = bitpack.BytePos + 1; | ||
1316 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); | ||
1317 | |||
1318 | // start another | ||
1319 | buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
1320 | data = buf.Data; | ||
1321 | |||
1322 | Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7); | ||
1323 | |||
1324 | data[7] = landPacketType; | ||
1325 | //data[8] and data[9] == datablock size to fill later | ||
1326 | |||
1327 | data[10] = 0; // BitPack needs this | ||
1328 | // start data | ||
1329 | bitpack = new BitPack(data, 10); | ||
1330 | |||
1331 | bitpack.PackBits(STRIDE, 16); | ||
1332 | bitpack.PackBitsFromByte(16); | ||
1333 | bitpack.PackBitsFromByte(landPacketType); | ||
1334 | } | ||
1335 | } | ||
1336 | |||
1337 | bitpack.PackBitsFromByte(END_OF_PATCHES); | ||
1338 | |||
1339 | datasize = bitpack.BytePos - 9; | ||
1340 | data[8] = (byte)datasize; | ||
1341 | data[9] = (byte)(datasize >> 8); | ||
1342 | |||
1343 | buf.DataLength = bitpack.BytePos + 1; | ||
1344 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land, null, false, false); | ||
1345 | |||
1270 | } | 1346 | } |
1271 | catch (Exception e) | 1347 | catch (Exception e) |
1272 | { | 1348 | { |
@@ -1677,8 +1753,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1677 | 1753 | ||
1678 | public void SendKillObject(List<uint> localIDs) | 1754 | public void SendKillObject(List<uint> localIDs) |
1679 | { | 1755 | { |
1680 | // foreach (uint id in localIDs) | 1756 | // foreach (uint id in localIDs) |
1681 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); | 1757 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); |
1682 | 1758 | ||
1683 | // remove pending entities to reduce looping chances. | 1759 | // remove pending entities to reduce looping chances. |
1684 | lock (m_entityProps.SyncRoot) | 1760 | lock (m_entityProps.SyncRoot) |
@@ -1702,10 +1778,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1702 | 1778 | ||
1703 | if(++nsent >= 200) | 1779 | if(++nsent >= 200) |
1704 | { | 1780 | { |
1705 | kill.Header.Reliable = true; | ||
1706 | kill.Header.Zerocoded = true; | ||
1707 | OutPacket(kill, ThrottleOutPacketType.Task); | 1781 | OutPacket(kill, ThrottleOutPacketType.Task); |
1708 | |||
1709 | perpacket = localIDs.Count - i - 1; | 1782 | perpacket = localIDs.Count - i - 1; |
1710 | if(perpacket == 0) | 1783 | if(perpacket == 0) |
1711 | break; | 1784 | break; |
@@ -1720,8 +1793,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1720 | 1793 | ||
1721 | if(nsent != 0) | 1794 | if(nsent != 0) |
1722 | { | 1795 | { |
1723 | kill.Header.Reliable = true; | ||
1724 | kill.Header.Zerocoded = true; | ||
1725 | OutPacket(kill, ThrottleOutPacketType.Task); | 1796 | OutPacket(kill, ThrottleOutPacketType.Task); |
1726 | } | 1797 | } |
1727 | } | 1798 | } |
@@ -3832,32 +3903,136 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3832 | OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | 3903 | OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); |
3833 | } | 3904 | } |
3834 | 3905 | ||
3906 | /* | ||
3835 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | 3907 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) |
3836 | { | 3908 | { |
3837 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name); | 3909 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name); |
3838 | 3910 | ||
3839 | AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation); | 3911 | AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation); |
3840 | // TODO: don't create new blocks if recycling an old packet | 3912 | // TODO: don't create new blocks if recycling an old packet |
3841 | ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[animations.Length]; | ||
3842 | ani.Sender = new AvatarAnimationPacket.SenderBlock(); | 3913 | ani.Sender = new AvatarAnimationPacket.SenderBlock(); |
3843 | ani.Sender.ID = sourceAgentId; | 3914 | ani.Sender.ID = sourceAgentId; |
3844 | ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[animations.Length]; | 3915 | ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[animations.Length]; |
3845 | ani.PhysicalAvatarEventList = new AvatarAnimationPacket.PhysicalAvatarEventListBlock[0]; | 3916 | ani.PhysicalAvatarEventList = new AvatarAnimationPacket.PhysicalAvatarEventListBlock[0]; |
3846 | 3917 | ||
3847 | for (int i = 0; i < animations.Length; ++i) | 3918 | //self animations |
3919 | if (sourceAgentId == AgentId) | ||
3848 | { | 3920 | { |
3849 | ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock(); | 3921 | List<int> withobjects = new List<int>(animations.Length); |
3850 | ani.AnimationList[i].AnimID = animations[i]; | 3922 | List<int> noobjects = new List<int>(animations.Length); |
3851 | ani.AnimationList[i].AnimSequenceID = seqs[i]; | 3923 | for(int i = 0; i < animations.Length; ++i) |
3924 | { | ||
3925 | if(objectIDs[i] == sourceAgentId || objectIDs[i] == UUID.Zero) | ||
3926 | noobjects.Add(i); | ||
3927 | else | ||
3928 | withobjects.Add(i); | ||
3929 | } | ||
3852 | 3930 | ||
3853 | ani.AnimationSourceList[i] = new AvatarAnimationPacket.AnimationSourceListBlock(); | 3931 | ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[withobjects.Count]; |
3854 | if (objectIDs[i].Equals(sourceAgentId)) | 3932 | int k = 0; |
3855 | ani.AnimationSourceList[i].ObjectID = UUID.Zero; | 3933 | foreach (int i in withobjects) |
3856 | else | 3934 | { |
3857 | ani.AnimationSourceList[i].ObjectID = objectIDs[i]; | 3935 | ani.AnimationList[k] = new AvatarAnimationPacket.AnimationListBlock(); |
3936 | ani.AnimationList[k].AnimID = animations[i]; | ||
3937 | ani.AnimationList[k].AnimSequenceID = seqs[i]; | ||
3938 | ani.AnimationSourceList[k] = new AvatarAnimationPacket.AnimationSourceListBlock(); | ||
3939 | ani.AnimationSourceList[k].ObjectID = objectIDs[i]; | ||
3940 | k++; | ||
3941 | } | ||
3942 | foreach (int i in noobjects) | ||
3943 | { | ||
3944 | ani.AnimationList[k] = new AvatarAnimationPacket.AnimationListBlock(); | ||
3945 | ani.AnimationList[k].AnimID = animations[i]; | ||
3946 | ani.AnimationList[k].AnimSequenceID = seqs[i]; | ||
3947 | k++; | ||
3948 | } | ||
3949 | } | ||
3950 | else | ||
3951 | { | ||
3952 | ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[0]; | ||
3953 | for (int i = 0; i < animations.Length; ++i) | ||
3954 | { | ||
3955 | ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock(); | ||
3956 | ani.AnimationList[i].AnimID = animations[i]; | ||
3957 | ani.AnimationList[i].AnimSequenceID = seqs[i]; | ||
3958 | } | ||
3858 | } | 3959 | } |
3960 | |||
3859 | OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | 3961 | OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); |
3860 | } | 3962 | } |
3963 | */ | ||
3964 | |||
3965 | static private readonly byte[] AvatarAnimationHeader = new byte[] { | ||
3966 | Helpers.MSG_RELIABLE, | ||
3967 | 0, 0, 0, 0, // sequence number | ||
3968 | 0, // extra | ||
3969 | 20 // ID (high frequency) | ||
3970 | }; | ||
3971 | |||
3972 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | ||
3973 | { | ||
3974 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name); | ||
3975 | |||
3976 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
3977 | byte[] data = buf.Data; | ||
3978 | //setup header | ||
3979 | Buffer.BlockCopy(AvatarAnimationHeader, 0, data, 0, 7); | ||
3980 | //agent block | ||
3981 | sourceAgentId.ToBytes(data, 7); | ||
3982 | |||
3983 | // animations count | ||
3984 | data[23] = (byte)animations.Length; | ||
3985 | |||
3986 | int pos = 24; | ||
3987 | |||
3988 | //self animations | ||
3989 | if (sourceAgentId == AgentId) | ||
3990 | { | ||
3991 | List<int> withobjects = new List<int>(animations.Length); | ||
3992 | List<int> noobjects = new List<int>(animations.Length); | ||
3993 | for (int i = 0; i < animations.Length; ++i) | ||
3994 | { | ||
3995 | if (objectIDs[i] == sourceAgentId || objectIDs[i] == UUID.Zero) | ||
3996 | noobjects.Add(i); | ||
3997 | else | ||
3998 | withobjects.Add(i); | ||
3999 | } | ||
4000 | |||
4001 | // first the ones with corresponding objects | ||
4002 | foreach (int i in withobjects) | ||
4003 | { | ||
4004 | animations[i].ToBytes(data, pos); pos += 16; | ||
4005 | Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; | ||
4006 | } | ||
4007 | // then the rest | ||
4008 | foreach (int i in noobjects) | ||
4009 | { | ||
4010 | animations[i].ToBytes(data, pos); pos += 16; | ||
4011 | Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; | ||
4012 | } | ||
4013 | // object ids block | ||
4014 | data[pos++] = (byte)withobjects.Count; | ||
4015 | foreach (int i in withobjects) | ||
4016 | { | ||
4017 | objectIDs[i].ToBytes(data, pos); pos += 16; | ||
4018 | } | ||
4019 | } | ||
4020 | else | ||
4021 | { | ||
4022 | for(int i = 0; i < animations.Length; ++i) | ||
4023 | { | ||
4024 | animations[i].ToBytes(data, pos); pos += 16; | ||
4025 | Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4; | ||
4026 | } | ||
4027 | data[pos++] = 0; // no object ids | ||
4028 | } | ||
4029 | |||
4030 | data[pos++] = 0; // no physical avatar events | ||
4031 | |||
4032 | buf.DataLength = pos; | ||
4033 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, | ||
4034 | null, false, false); | ||
4035 | } | ||
3861 | 4036 | ||
3862 | public void SendObjectAnimations(UUID[] animations, int[] seqs, UUID senderId) | 4037 | public void SendObjectAnimations(UUID[] animations, int[] seqs, UUID senderId) |
3863 | { | 4038 | { |
@@ -3889,36 +4064,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3889 | /// </summary> | 4064 | /// </summary> |
3890 | public void SendEntityFullUpdateImmediate(ISceneEntity ent) | 4065 | public void SendEntityFullUpdateImmediate(ISceneEntity ent) |
3891 | { | 4066 | { |
3892 | // m_log.DebugFormat( | 4067 | if (ent == null || (!(ent is ScenePresence) && !(ent is SceneObjectPart))) |
3893 | // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", | ||
3894 | // avatar.Name, avatar.UUID, Name, AgentId); | ||
3895 | |||
3896 | if (ent == null) | ||
3897 | return; | 4068 | return; |
3898 | 4069 | ||
3899 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 4070 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
3900 | objupdate.Header.Zerocoded = true; | 4071 | Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); |
3901 | 4072 | ||
3902 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | 4073 | LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); |
3903 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 4074 | zc.Position = 7; |
3904 | 4075 | ||
3905 | if(ent is ScenePresence) | 4076 | zc.AddUInt64(m_scene.RegionInfo.RegionHandle); |
3906 | { | 4077 | zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); |
3907 | ScenePresence presence = ent as ScenePresence; | 4078 | |
3908 | objupdate.RegionData.RegionHandle = presence.RegionHandle; | 4079 | zc.AddByte(1); // block count |
3909 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); | 4080 | |
3910 | } | 4081 | ThrottleOutPacketType ptype = ThrottleOutPacketType.Task; |
3911 | else if(ent is SceneObjectPart) | 4082 | if (ent is ScenePresence) |
3912 | { | 4083 | { |
3913 | SceneObjectPart part = ent as SceneObjectPart; | 4084 | CreateAvatarUpdateBlock(ent as ScenePresence, zc); |
3914 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4085 | ptype |= ThrottleOutPacketType.HighPriority; |
3915 | objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); | ||
3916 | } | 4086 | } |
4087 | else | ||
4088 | CreatePrimUpdateBlock(ent as SceneObjectPart, (ScenePresence)SceneAgent, zc); | ||
3917 | 4089 | ||
3918 | OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); | 4090 | buf.DataLength = zc.Finish(); |
3919 | 4091 | m_udpServer.SendUDPPacket(m_udpClient, buf, ptype , null, false, false); | |
3920 | // We need to record the avatar local id since the root prim of an attachment points to this. | ||
3921 | // m_attachmentsSent.Add(avatar.LocalId); | ||
3922 | } | 4092 | } |
3923 | 4093 | ||
3924 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) | 4094 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) |
@@ -4089,6 +4259,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4089 | ResendPrimUpdate(update); | 4259 | ResendPrimUpdate(update); |
4090 | } | 4260 | } |
4091 | 4261 | ||
4262 | static private readonly byte[] objectUpdateHeader = new byte[] { | ||
4263 | Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, | ||
4264 | 0, 0, 0, 0, // sequence number | ||
4265 | 0, // extra | ||
4266 | 12 // ID (high frequency) | ||
4267 | }; | ||
4268 | |||
4269 | static private readonly byte[] terseUpdateHeader = new byte[] { | ||
4270 | Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec | ||
4271 | 0, 0, 0, 0, // sequence number | ||
4272 | 0, // extra | ||
4273 | 15 // ID (high frequency) | ||
4274 | }; | ||
4275 | |||
4092 | private void ProcessEntityUpdates(int maxUpdatesBytes) | 4276 | private void ProcessEntityUpdates(int maxUpdatesBytes) |
4093 | { | 4277 | { |
4094 | if (!IsActive) | 4278 | if (!IsActive) |
@@ -4098,14 +4282,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4098 | if (mysp == null) | 4282 | if (mysp == null) |
4099 | return; | 4283 | return; |
4100 | 4284 | ||
4101 | List<ObjectUpdatePacket.ObjectDataBlock> objectUpdateBlocks = null; | 4285 | // List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = null; |
4102 | List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = null; | ||
4103 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseUpdateBlocks = null; | ||
4104 | List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseAgentUpdateBlocks = null; | ||
4105 | List<EntityUpdate> objectUpdates = null; | 4286 | List<EntityUpdate> objectUpdates = null; |
4106 | List<EntityUpdate> compressedUpdates = null; | 4287 | // List<EntityUpdate> compressedUpdates = null; |
4107 | List<EntityUpdate> terseUpdates = null; | 4288 | List<EntityUpdate> terseUpdates = null; |
4108 | List<EntityUpdate> terseAgentUpdates = null; | ||
4109 | List<SceneObjectPart> ObjectAnimationUpdates = null; | 4289 | List<SceneObjectPart> ObjectAnimationUpdates = null; |
4110 | 4290 | ||
4111 | // Check to see if this is a flush | 4291 | // Check to see if this is a flush |
@@ -4120,10 +4300,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4120 | float cullingrange = 64.0f; | 4300 | float cullingrange = 64.0f; |
4121 | Vector3 mypos = Vector3.Zero; | 4301 | Vector3 mypos = Vector3.Zero; |
4122 | 4302 | ||
4123 | bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; | 4303 | //bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; |
4304 | bool orderedDequeue = false; // temporary off | ||
4124 | 4305 | ||
4125 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); | 4306 | HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); |
4126 | 4307 | ||
4308 | |||
4127 | if (doCulling) | 4309 | if (doCulling) |
4128 | { | 4310 | { |
4129 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; | 4311 | cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f; |
@@ -4179,7 +4361,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4179 | } | 4361 | } |
4180 | 4362 | ||
4181 | if (grp.IsAttachment) | 4363 | if (grp.IsAttachment) |
4182 | { // Someone else's HUD, why are we getting these? | 4364 | { |
4365 | // animated attachments are nasty if not supported by viewer | ||
4366 | if(!m_SupportObjectAnimations && grp.RootPart.Shape.MeshFlagEntry) | ||
4367 | continue; | ||
4368 | |||
4369 | // Someone else's HUD, why are we getting these? | ||
4183 | if (grp.OwnerID != AgentId && grp.HasPrivateAttachmentPoint) | 4370 | if (grp.OwnerID != AgentId && grp.HasPrivateAttachmentPoint) |
4184 | continue; | 4371 | continue; |
4185 | 4372 | ||
@@ -4273,7 +4460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4273 | if(ObjectAnimationUpdates == null) | 4460 | if(ObjectAnimationUpdates == null) |
4274 | ObjectAnimationUpdates = new List<SceneObjectPart>(); | 4461 | ObjectAnimationUpdates = new List<SceneObjectPart>(); |
4275 | ObjectAnimationUpdates.Add(sop); | 4462 | ObjectAnimationUpdates.Add(sop); |
4276 | maxUpdatesBytes -= 32 * sop.Animations.Count + 16; | 4463 | maxUpdatesBytes -= 20 * sop.Animations.Count + 24; |
4277 | } | 4464 | } |
4278 | } | 4465 | } |
4279 | } | 4466 | } |
@@ -4304,7 +4491,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4304 | PrimUpdateFlags.Velocity | | 4491 | PrimUpdateFlags.Velocity | |
4305 | PrimUpdateFlags.Acceleration | | 4492 | PrimUpdateFlags.Acceleration | |
4306 | PrimUpdateFlags.AngularVelocity | | 4493 | PrimUpdateFlags.AngularVelocity | |
4307 | PrimUpdateFlags.CollisionPlane | 4494 | PrimUpdateFlags.CollisionPlane | |
4495 | PrimUpdateFlags.Textures | ||
4308 | ); | 4496 | ); |
4309 | 4497 | ||
4310 | #endregion UpdateFlags to packet type conversion | 4498 | #endregion UpdateFlags to packet type conversion |
@@ -4326,48 +4514,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4326 | 4514 | ||
4327 | if ((updateFlags & canNotUseImprovedMask) == 0) | 4515 | if ((updateFlags & canNotUseImprovedMask) == 0) |
4328 | { | 4516 | { |
4329 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock ablock = | 4517 | if (terseUpdates == null) |
4330 | CreateImprovedTerseBlock(update.Entity); | ||
4331 | |||
4332 | if (update.Entity is ScenePresence) | ||
4333 | { | 4518 | { |
4334 | // ALL presence updates go into a special list | 4519 | terseUpdates = new List<EntityUpdate>(); |
4335 | if (terseAgentUpdateBlocks == null) | 4520 | maxUpdatesBytes -= 18; |
4336 | { | ||
4337 | terseAgentUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
4338 | terseAgentUpdates = new List<EntityUpdate>(); | ||
4339 | } | ||
4340 | terseAgentUpdateBlocks.Add(ablock); | ||
4341 | terseAgentUpdates.Add(update); | ||
4342 | } | 4521 | } |
4522 | terseUpdates.Add(update); | ||
4523 | |||
4524 | if (update.Entity is ScenePresence) | ||
4525 | maxUpdatesBytes -= 63; // no texture entry | ||
4343 | else | 4526 | else |
4344 | { | 4527 | { |
4345 | // Everything else goes here | 4528 | if ((updateFlags & PrimUpdateFlags.Textures) == 0) |
4346 | if (terseUpdateBlocks == null) | 4529 | maxUpdatesBytes -= 47; |
4347 | { | 4530 | else |
4348 | terseUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 4531 | maxUpdatesBytes -= 150; // aprox |
4349 | terseUpdates = new List<EntityUpdate>(); | ||
4350 | } | ||
4351 | terseUpdateBlocks.Add(ablock); | ||
4352 | terseUpdates.Add(update); | ||
4353 | } | 4532 | } |
4354 | maxUpdatesBytes -= ablock.Length; | ||
4355 | } | 4533 | } |
4356 | else | 4534 | else |
4357 | { | 4535 | { |
4358 | ObjectUpdatePacket.ObjectDataBlock ablock; | ||
4359 | if (update.Entity is ScenePresence) | 4536 | if (update.Entity is ScenePresence) |
4360 | ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); | 4537 | maxUpdatesBytes -= 150; // crude estimation |
4361 | else | 4538 | else |
4362 | ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp); | 4539 | maxUpdatesBytes -= 300; |
4363 | if(objectUpdateBlocks == null) | 4540 | |
4541 | if(objectUpdates == null) | ||
4364 | { | 4542 | { |
4365 | objectUpdateBlocks = new List<ObjectUpdatePacket.ObjectDataBlock>(); | ||
4366 | objectUpdates = new List<EntityUpdate>(); | 4543 | objectUpdates = new List<EntityUpdate>(); |
4544 | maxUpdatesBytes -= 18; | ||
4367 | } | 4545 | } |
4368 | objectUpdateBlocks.Add(ablock); | ||
4369 | objectUpdates.Add(update); | 4546 | objectUpdates.Add(update); |
4370 | maxUpdatesBytes -= ablock.Length; | ||
4371 | } | 4547 | } |
4372 | 4548 | ||
4373 | #endregion Block Construction | 4549 | #endregion Block Construction |
@@ -4382,29 +4558,87 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4382 | 4558 | ||
4383 | timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | 4559 | timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); |
4384 | 4560 | ||
4385 | if (terseAgentUpdateBlocks != null) | 4561 | if(objectUpdates != null) |
4386 | { | 4562 | { |
4387 | ImprovedTerseObjectUpdatePacket packet | 4563 | int blocks = objectUpdates.Count; |
4388 | = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | 4564 | List<EntityUpdate> tau = new List<EntityUpdate>(30); |
4389 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
4390 | packet.RegionData.TimeDilation = timeDilation; | ||
4391 | packet.ObjectData = terseAgentUpdateBlocks.ToArray(); | ||
4392 | terseAgentUpdateBlocks.Clear(); | ||
4393 | 4565 | ||
4394 | OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates, oPacket); }); | 4566 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
4395 | } | 4567 | Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); |
4396 | 4568 | ||
4397 | if (objectUpdateBlocks != null) | 4569 | LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); |
4398 | { | 4570 | zc.Position = 7; |
4399 | ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 4571 | |
4400 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4572 | zc.AddUInt64(m_scene.RegionInfo.RegionHandle); |
4401 | packet.RegionData.TimeDilation = timeDilation; | 4573 | zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); |
4402 | packet.ObjectData = objectUpdateBlocks.ToArray(); | 4574 | |
4403 | objectUpdateBlocks.Clear(); | 4575 | zc.AddByte(1); // tmp block count |
4576 | |||
4577 | int countposition = zc.Position - 1; | ||
4578 | |||
4579 | int lastpos = 0; | ||
4580 | int lastzc = 0; | ||
4581 | |||
4582 | int count = 0; | ||
4583 | foreach (EntityUpdate eu in objectUpdates) | ||
4584 | { | ||
4585 | lastpos = zc.Position; | ||
4586 | lastzc = zc.ZeroCount; | ||
4587 | if (eu.Entity is ScenePresence) | ||
4588 | CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); | ||
4589 | else | ||
4590 | CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); | ||
4591 | if (zc.Position < LLUDPServer.MAXPAYLOAD) | ||
4592 | { | ||
4593 | tau.Add(eu); | ||
4594 | ++count; | ||
4595 | --blocks; | ||
4596 | } | ||
4597 | else if (blocks > 0) | ||
4598 | { | ||
4599 | // we need more packets | ||
4600 | UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
4601 | Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same | ||
4404 | 4602 | ||
4405 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates, oPacket); }); | 4603 | buf.Data[countposition] = (byte)count; |
4604 | // get pending zeros at cut point | ||
4605 | if(lastzc > 0) | ||
4606 | { | ||
4607 | buf.Data[lastpos++] = 0; | ||
4608 | buf.Data[lastpos++] = (byte)lastzc; | ||
4609 | } | ||
4610 | buf.DataLength = lastpos; | ||
4611 | |||
4612 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | ||
4613 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); | ||
4614 | |||
4615 | buf = newbuf; | ||
4616 | zc.Data = buf.Data; | ||
4617 | zc.ZeroCount = 0; | ||
4618 | zc.Position = countposition + 1; | ||
4619 | // im lazy now, just do last again | ||
4620 | if (eu.Entity is ScenePresence) | ||
4621 | CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc); | ||
4622 | else | ||
4623 | CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc); | ||
4624 | |||
4625 | tau = new List<EntityUpdate>(30); | ||
4626 | tau.Add(eu); | ||
4627 | count = 1; | ||
4628 | --blocks; | ||
4629 | } | ||
4630 | } | ||
4631 | |||
4632 | if (count > 0) | ||
4633 | { | ||
4634 | buf.Data[countposition] = (byte)count; | ||
4635 | buf.DataLength = zc.Finish(); | ||
4636 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | ||
4637 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); | ||
4638 | } | ||
4406 | } | 4639 | } |
4407 | 4640 | ||
4641 | /* | ||
4408 | if (compressedUpdateBlocks != null) | 4642 | if (compressedUpdateBlocks != null) |
4409 | { | 4643 | { |
4410 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); | 4644 | ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); |
@@ -4415,20 +4649,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4415 | 4649 | ||
4416 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates, oPacket); }); | 4650 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates, oPacket); }); |
4417 | } | 4651 | } |
4418 | 4652 | */ | |
4419 | if (terseUpdateBlocks != null) | 4653 | if (terseUpdates != null) |
4420 | { | 4654 | { |
4421 | ImprovedTerseObjectUpdatePacket packet = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( | 4655 | int blocks = terseUpdates.Count; |
4422 | PacketType.ImprovedTerseObjectUpdate); | 4656 | List<EntityUpdate> tau = new List<EntityUpdate>(30); |
4423 | packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | 4657 | |
4424 | packet.RegionData.TimeDilation = timeDilation; | 4658 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
4425 | packet.ObjectData = terseUpdateBlocks.ToArray(); | 4659 | |
4426 | terseUpdateBlocks.Clear(); | 4660 | //setup header and regioninfo block |
4661 | Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7); | ||
4662 | Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7); | ||
4663 | Utils.UInt16ToBytes(timeDilation, buf.Data, 15); | ||
4664 | int pos = 18; | ||
4665 | int lastpos = 0; | ||
4427 | 4666 | ||
4428 | OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates, oPacket); }); | 4667 | int count = 0; |
4668 | foreach (EntityUpdate eu in terseUpdates) | ||
4669 | { | ||
4670 | lastpos = pos; | ||
4671 | CreateImprovedTerseBlock(eu.Entity, buf.Data, ref pos, (eu.Flags & PrimUpdateFlags.Textures) != 0); | ||
4672 | if (pos < LLUDPServer.MAXPAYLOAD) | ||
4673 | { | ||
4674 | tau.Add(eu); | ||
4675 | ++count; | ||
4676 | --blocks; | ||
4677 | } | ||
4678 | else if (blocks > 0) | ||
4679 | { | ||
4680 | // we need more packets | ||
4681 | UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
4682 | Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, 17); // start is the same | ||
4683 | // copy what we done in excess | ||
4684 | int extralen = pos - lastpos; | ||
4685 | if(extralen > 0) | ||
4686 | Buffer.BlockCopy(buf.Data, lastpos, newbuf.Data, 18, extralen); | ||
4687 | |||
4688 | pos = 18 + extralen; | ||
4689 | |||
4690 | buf.Data[17] = (byte)count; | ||
4691 | buf.DataLength = lastpos; | ||
4692 | // zero encode is not as spec | ||
4693 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | ||
4694 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); | ||
4695 | |||
4696 | tau = new List<EntityUpdate>(30); | ||
4697 | tau.Add(eu); | ||
4698 | count = 1; | ||
4699 | --blocks; | ||
4700 | buf = newbuf; | ||
4701 | } | ||
4702 | } | ||
4703 | |||
4704 | if (count > 0) | ||
4705 | { | ||
4706 | buf.Data[17] = (byte)count; | ||
4707 | buf.DataLength = pos; | ||
4708 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, | ||
4709 | delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, true); | ||
4710 | } | ||
4429 | } | 4711 | } |
4430 | 4712 | ||
4431 | if(ObjectAnimationUpdates != null) | 4713 | if (ObjectAnimationUpdates != null) |
4432 | { | 4714 | { |
4433 | foreach (SceneObjectPart sop in ObjectAnimationUpdates) | 4715 | foreach (SceneObjectPart sop in ObjectAnimationUpdates) |
4434 | { | 4716 | { |
@@ -4445,13 +4727,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4445 | UUID[] ids = null; | 4727 | UUID[] ids = null; |
4446 | int[] seqs = null; | 4728 | int[] seqs = null; |
4447 | int count = sop.GetAnimations(out ids, out seqs); | 4729 | int count = sop.GetAnimations(out ids, out seqs); |
4448 | if(count < 0) | ||
4449 | continue; | ||
4450 | 4730 | ||
4451 | ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation); | 4731 | ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation); |
4452 | ani.Sender = new ObjectAnimationPacket.SenderBlock(); | 4732 | ani.Sender = new ObjectAnimationPacket.SenderBlock(); |
4453 | ani.Sender.ID = sop.UUID; | 4733 | ani.Sender.ID = sop.UUID; |
4454 | ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[sop.Animations.Count]; | 4734 | ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[count]; |
4455 | 4735 | ||
4456 | for(int i = 0; i< count; i++) | 4736 | for(int i = 0; i< count; i++) |
4457 | { | 4737 | { |
@@ -4642,9 +4922,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4642 | // These are used to implement an adaptive backoff in the number | 4922 | // These are used to implement an adaptive backoff in the number |
4643 | // of updates converted to packets. Since we don't want packets | 4923 | // of updates converted to packets. Since we don't want packets |
4644 | // to sit in the queue with old data, only convert enough updates | 4924 | // to sit in the queue with old data, only convert enough updates |
4645 | // to packets that can be sent in 200ms. | 4925 | // to packets that can be sent in 30ms. |
4646 | // private Int32 m_LastQueueFill = 0; | ||
4647 | // private Int32 m_maxUpdates = 0; | ||
4648 | 4926 | ||
4649 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | 4927 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
4650 | { | 4928 | { |
@@ -5645,9 +5923,144 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5645 | return block; | 5923 | return block; |
5646 | } | 5924 | } |
5647 | 5925 | ||
5926 | protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture) | ||
5927 | { | ||
5928 | #region ScenePresence/SOP Handling | ||
5929 | |||
5930 | bool avatar = (entity is ScenePresence); | ||
5931 | uint localID = entity.LocalId; | ||
5932 | uint attachPoint; | ||
5933 | Vector4 collisionPlane; | ||
5934 | Vector3 position, velocity, acceleration, angularVelocity; | ||
5935 | Quaternion rotation; | ||
5936 | byte datasize; | ||
5937 | byte[] te = null; | ||
5938 | |||
5939 | if (avatar) | ||
5940 | { | ||
5941 | ScenePresence presence = (ScenePresence)entity; | ||
5942 | |||
5943 | position = presence.OffsetPosition; | ||
5944 | velocity = presence.Velocity; | ||
5945 | acceleration = Vector3.Zero; | ||
5946 | rotation = presence.Rotation; | ||
5947 | // tpvs can only see rotations around Z in some cases | ||
5948 | if (!presence.Flying && !presence.IsSatOnObject) | ||
5949 | { | ||
5950 | rotation.X = 0f; | ||
5951 | rotation.Y = 0f; | ||
5952 | } | ||
5953 | rotation.Normalize(); | ||
5954 | angularVelocity = presence.AngularVelocity; | ||
5955 | |||
5956 | // m_log.DebugFormat( | ||
5957 | // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name); | ||
5958 | |||
5959 | attachPoint = presence.State; | ||
5960 | collisionPlane = presence.CollisionPlane; | ||
5961 | |||
5962 | datasize = 60; | ||
5963 | } | ||
5964 | else | ||
5965 | { | ||
5966 | SceneObjectPart part = (SceneObjectPart)entity; | ||
5967 | |||
5968 | attachPoint = part.ParentGroup.AttachmentPoint; | ||
5969 | attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16)); | ||
5970 | // m_log.DebugFormat( | ||
5971 | // "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", | ||
5972 | // attachPoint, part.Name, part.LocalId, Name); | ||
5973 | |||
5974 | collisionPlane = Vector4.Zero; | ||
5975 | position = part.RelativePosition; | ||
5976 | velocity = part.Velocity; | ||
5977 | acceleration = part.Acceleration; | ||
5978 | angularVelocity = part.AngularVelocity; | ||
5979 | rotation = part.RotationOffset; | ||
5980 | |||
5981 | datasize = 44; | ||
5982 | if(includeTexture) | ||
5983 | te = part.Shape.TextureEntry; | ||
5984 | } | ||
5985 | |||
5986 | #endregion ScenePresence/SOP Handling | ||
5987 | //object block size | ||
5988 | data[pos++] = datasize; | ||
5989 | |||
5990 | // LocalID | ||
5991 | Utils.UIntToBytes(localID, data, pos); | ||
5992 | pos += 4; | ||
5993 | |||
5994 | data[pos++] = (byte)attachPoint; | ||
5995 | |||
5996 | // Avatar/CollisionPlane | ||
5997 | if (avatar) | ||
5998 | { | ||
5999 | data[pos++] = 1; | ||
6000 | |||
6001 | if (collisionPlane == Vector4.Zero) | ||
6002 | collisionPlane = Vector4.UnitW; | ||
6003 | //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane); | ||
6004 | collisionPlane.ToBytes(data, pos); | ||
6005 | pos += 16; | ||
6006 | } | ||
6007 | else | ||
6008 | { | ||
6009 | data[pos++] = 0; | ||
6010 | } | ||
6011 | |||
6012 | // Position | ||
6013 | position.ToBytes(data, pos); | ||
6014 | pos += 12; | ||
6015 | |||
6016 | // Velocity | ||
6017 | ClampVectorForUint(ref velocity, 128f); | ||
6018 | Utils.FloatToUInt16Bytes(velocity.X, 128.0f, data, pos); pos += 2; | ||
6019 | Utils.FloatToUInt16Bytes(velocity.Y, 128.0f, data, pos); pos += 2; | ||
6020 | Utils.FloatToUInt16Bytes(velocity.Z, 128.0f, data, pos); pos += 2; | ||
6021 | |||
6022 | // Acceleration | ||
6023 | ClampVectorForUint(ref acceleration, 64f); | ||
6024 | Utils.FloatToUInt16Bytes(acceleration.X, 64.0f, data, pos); pos += 2; | ||
6025 | Utils.FloatToUInt16Bytes(acceleration.Y, 64.0f, data, pos); pos += 2; | ||
6026 | Utils.FloatToUInt16Bytes(acceleration.Z, 64.0f, data, pos); pos += 2; | ||
6027 | |||
6028 | // Rotation | ||
6029 | Utils.FloatToUInt16Bytes(rotation.X, 1.0f, data, pos); pos += 2; | ||
6030 | Utils.FloatToUInt16Bytes(rotation.Y, 1.0f, data, pos); pos += 2; | ||
6031 | Utils.FloatToUInt16Bytes(rotation.Z, 1.0f, data, pos); pos += 2; | ||
6032 | Utils.FloatToUInt16Bytes(rotation.W, 1.0f, data, pos); pos += 2; | ||
6033 | |||
6034 | // Angular Velocity | ||
6035 | ClampVectorForUint(ref angularVelocity, 64f); | ||
6036 | Utils.FloatToUInt16Bytes(angularVelocity.X, 64.0f, data, pos); pos += 2; | ||
6037 | Utils.FloatToUInt16Bytes(angularVelocity.Y, 64.0f, data, pos); pos += 2; | ||
6038 | Utils.FloatToUInt16Bytes(angularVelocity.Z, 64.0f, data, pos); pos += 2; | ||
6039 | |||
6040 | // texture entry block size | ||
6041 | if(te == null) | ||
6042 | { | ||
6043 | data[pos++] = 0; | ||
6044 | data[pos++] = 0; | ||
6045 | } | ||
6046 | else | ||
6047 | { | ||
6048 | int len = te.Length & 0x7fff; | ||
6049 | int totlen = len + 4; | ||
6050 | data[pos++] = (byte)totlen; | ||
6051 | data[pos++] = (byte)(totlen >> 8); | ||
6052 | data[pos++] = (byte)len; // wtf ??? | ||
6053 | data[pos++] = (byte)(len >> 8); | ||
6054 | data[pos++] = 0; | ||
6055 | data[pos++] = 0; | ||
6056 | Buffer.BlockCopy(te, 0, data, pos, len); | ||
6057 | pos += len; | ||
6058 | } | ||
6059 | // total size 63 or 47 + (texture size + 4) | ||
6060 | } | ||
6061 | |||
5648 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) | 6062 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) |
5649 | { | 6063 | { |
5650 | Vector3 offsetPosition = data.OffsetPosition; | ||
5651 | Quaternion rotation = data.Rotation; | 6064 | Quaternion rotation = data.Rotation; |
5652 | // tpvs can only see rotations around Z in some cases | 6065 | // tpvs can only see rotations around Z in some cases |
5653 | if(!data.Flying && !data.IsSatOnObject) | 6066 | if(!data.Flying && !data.IsSatOnObject) |
@@ -5657,27 +6070,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5657 | } | 6070 | } |
5658 | rotation.Normalize(); | 6071 | rotation.Normalize(); |
5659 | 6072 | ||
5660 | uint parentID = data.ParentID; | ||
5661 | |||
5662 | // m_log.DebugFormat( | 6073 | // m_log.DebugFormat( |
5663 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); | 6074 | // "[LLCLIENTVIEW]: Sending full update to {0} with pos {1}, vel {2} in {3}", Name, data.OffsetPosition, data.Velocity, m_scene.Name); |
5664 | 6075 | ||
5665 | byte[] objectData = new byte[76]; | 6076 | byte[] objectData = new byte[76]; |
5666 | 6077 | ||
5667 | Vector3 velocity = new Vector3(0, 0, 0); | 6078 | //Vector3 velocity = Vector3.Zero; |
5668 | Vector3 acceleration = new Vector3(0, 0, 0); | 6079 | Vector3 acceleration = Vector3.Zero; |
6080 | Vector3 angularvelocity = Vector3.Zero; | ||
5669 | 6081 | ||
5670 | data.CollisionPlane.ToBytes(objectData, 0); | 6082 | data.CollisionPlane.ToBytes(objectData, 0); |
5671 | offsetPosition.ToBytes(objectData, 16); | 6083 | data.OffsetPosition.ToBytes(objectData, 16); |
5672 | velocity.ToBytes(objectData, 28); | 6084 | data.Velocity.ToBytes(objectData, 28); |
5673 | acceleration.ToBytes(objectData, 40); | 6085 | acceleration.ToBytes(objectData, 40); |
5674 | rotation.ToBytes(objectData, 52); | 6086 | rotation.ToBytes(objectData, 52); |
5675 | data.AngularVelocity.ToBytes(objectData, 64); | 6087 | angularvelocity.ToBytes(objectData, 64); |
5676 | 6088 | ||
5677 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | 6089 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); |
5678 | 6090 | ||
5679 | update.Data = Utils.EmptyBytes; | 6091 | update.Data = Utils.EmptyBytes; |
5680 | update.ExtraParams = new byte[1]; | 6092 | update.ExtraParams = Utils.EmptyBytes; |
5681 | update.FullID = data.UUID; | 6093 | update.FullID = data.UUID; |
5682 | update.ID = data.LocalId; | 6094 | update.ID = data.LocalId; |
5683 | update.Material = (byte)Material.Flesh; | 6095 | update.Material = (byte)Material.Flesh; |
@@ -5714,7 +6126,158 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5714 | return update; | 6126 | return update; |
5715 | } | 6127 | } |
5716 | 6128 | ||
5717 | // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | 6129 | protected void CreateAvatarUpdateBlock(ScenePresence data, byte[] dest, ref int pos) |
6130 | { | ||
6131 | Quaternion rotation = data.Rotation; | ||
6132 | // tpvs can only see rotations around Z in some cases | ||
6133 | if (!data.Flying && !data.IsSatOnObject) | ||
6134 | { | ||
6135 | rotation.X = 0f; | ||
6136 | rotation.Y = 0f; | ||
6137 | } | ||
6138 | rotation.Normalize(); | ||
6139 | |||
6140 | //Vector3 velocity = Vector3.Zero; | ||
6141 | //Vector3 acceleration = Vector3.Zero; | ||
6142 | //Vector3 angularvelocity = Vector3.Zero; | ||
6143 | |||
6144 | Utils.UIntToBytesSafepos(data.LocalId, dest, pos); pos += 4; | ||
6145 | dest[pos++] = 0; // state | ||
6146 | data.UUID.ToBytes(dest, pos); pos += 16; | ||
6147 | Utils.UIntToBytesSafepos(0 , dest, pos); pos += 4; // crc | ||
6148 | dest[pos++] = (byte)PCode.Avatar; | ||
6149 | dest[pos++] = (byte)Material.Flesh; | ||
6150 | dest[pos++] = 0; // clickaction | ||
6151 | data.Appearance.AvatarSize.ToBytes(dest, pos); pos += 12; | ||
6152 | |||
6153 | // objectdata block | ||
6154 | dest[pos++] = 76; | ||
6155 | data.CollisionPlane.ToBytes(dest, pos); pos += 16; | ||
6156 | data.OffsetPosition.ToBytes(dest, pos); pos += 12; | ||
6157 | data.Velocity.ToBytes(dest, pos); pos += 12; | ||
6158 | |||
6159 | //acceleration.ToBytes(dest, pos); pos += 12; | ||
6160 | Array.Clear(dest, pos, 12); pos += 12; | ||
6161 | |||
6162 | rotation.ToBytes(dest, pos); pos += 12; | ||
6163 | |||
6164 | //angularvelocity.ToBytes(dest, pos); pos += 12; | ||
6165 | Array.Clear(dest, pos, 12); pos += 12; | ||
6166 | |||
6167 | SceneObjectPart parentPart = data.ParentPart; | ||
6168 | if (parentPart != null) | ||
6169 | { | ||
6170 | Utils.UIntToBytesSafepos(parentPart.ParentGroup.LocalId, dest, pos); | ||
6171 | pos += 4; | ||
6172 | } | ||
6173 | else | ||
6174 | { | ||
6175 | // Utils.UIntToBytesSafepos(0, dest, pos); | ||
6176 | // pos += 4; | ||
6177 | dest[pos++] = 0; | ||
6178 | dest[pos++] = 0; | ||
6179 | dest[pos++] = 0; | ||
6180 | dest[pos++] = 0; | ||
6181 | } | ||
6182 | |||
6183 | //Utils.UIntToBytesSafepos(0, dest, pos); pos += 4; //update flags | ||
6184 | dest[pos++] = 0; | ||
6185 | dest[pos++] = 0; | ||
6186 | dest[pos++] = 0; | ||
6187 | dest[pos++] = 0; | ||
6188 | |||
6189 | //pbs | ||
6190 | dest[pos++] = 16; | ||
6191 | dest[pos++] = 1; | ||
6192 | //Utils.UInt16ToBytes(0, dest, pos); pos += 2; | ||
6193 | //Utils.UInt16ToBytes(0, dest, pos); pos += 2; | ||
6194 | dest[pos++] = 0; | ||
6195 | dest[pos++] = 0; | ||
6196 | dest[pos++] = 0; | ||
6197 | dest[pos++] = 0; | ||
6198 | |||
6199 | dest[pos++] = 100; | ||
6200 | dest[pos++] = 100; | ||
6201 | |||
6202 | // rest of pbs is 0 (15), texture entry (2) and texture anim (1) | ||
6203 | const int pbszeros = 15 + 2 + 1; | ||
6204 | Array.Clear(dest, pos, pbszeros); pos += pbszeros; | ||
6205 | |||
6206 | //NameValue | ||
6207 | byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + | ||
6208 | data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); | ||
6209 | int len = nv.Length; | ||
6210 | dest[pos++] = (byte)len; | ||
6211 | dest[pos++] = (byte)(len >> 8); | ||
6212 | Buffer.BlockCopy(nv, 0, dest, pos, len); pos += len; | ||
6213 | |||
6214 | // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1), | ||
6215 | // sound id(16), sound owner(16) gain (4), flags (1), radius (4) | ||
6216 | // jointtype(1) joint pivot(12) joint offset(12) | ||
6217 | const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12; | ||
6218 | Array.Clear(dest, pos, lastzeros); pos += lastzeros; | ||
6219 | } | ||
6220 | |||
6221 | protected void CreateAvatarUpdateBlock(ScenePresence data, LLUDPZeroEncoder zc) | ||
6222 | { | ||
6223 | Quaternion rotation = data.Rotation; | ||
6224 | // tpvs can only see rotations around Z in some cases | ||
6225 | if (!data.Flying && !data.IsSatOnObject) | ||
6226 | { | ||
6227 | rotation.X = 0f; | ||
6228 | rotation.Y = 0f; | ||
6229 | } | ||
6230 | rotation.Normalize(); | ||
6231 | |||
6232 | zc.AddUInt(data.LocalId); | ||
6233 | zc.AddByte(0); | ||
6234 | zc.AddUUID(data.UUID); | ||
6235 | zc.AddZeros(4); // crc unused | ||
6236 | zc.AddByte((byte)PCode.Avatar); | ||
6237 | zc.AddByte((byte)Material.Flesh); | ||
6238 | zc.AddByte(0); // clickaction | ||
6239 | zc.AddVector3(data.Appearance.AvatarSize); | ||
6240 | |||
6241 | // objectdata block | ||
6242 | zc.AddByte(76); // fixed avatar block size | ||
6243 | zc.AddVector4(data.CollisionPlane); | ||
6244 | zc.AddVector3(data.OffsetPosition); | ||
6245 | zc.AddVector3(data.Velocity); | ||
6246 | //zc.AddVector3(acceleration); | ||
6247 | zc.AddZeros(12); | ||
6248 | zc.AddNormQuat(rotation); | ||
6249 | //zc.AddVector3(angularvelocity); | ||
6250 | zc.AddZeros(12); | ||
6251 | |||
6252 | SceneObjectPart parentPart = data.ParentPart; | ||
6253 | if (parentPart != null) | ||
6254 | zc.AddUInt(parentPart.ParentGroup.LocalId); | ||
6255 | else | ||
6256 | zc.AddZeros(4); | ||
6257 | |||
6258 | zc.AddZeros(4); //update flags | ||
6259 | |||
6260 | //pbs volume data 23 | ||
6261 | //texture entry 2 | ||
6262 | //texture anim (1) | ||
6263 | const int pbszeros = 23 + 2 + 1; | ||
6264 | zc.AddZeros(pbszeros); | ||
6265 | |||
6266 | //NameValue | ||
6267 | byte[] nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + | ||
6268 | data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); | ||
6269 | int len = nv.Length; | ||
6270 | zc.AddByte((byte)len); | ||
6271 | zc.AddByte((byte)(len >> 8)); | ||
6272 | zc.AddBytes(nv, len); | ||
6273 | |||
6274 | // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1), | ||
6275 | // sound id(16), sound owner(16) gain (4), flags (1), radius (4) | ||
6276 | // jointtype(1) joint pivot(12) joint offset(12) | ||
6277 | const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12; | ||
6278 | zc.AddZeros(lastzeros); | ||
6279 | } | ||
6280 | |||
5718 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) | 6281 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) |
5719 | { | 6282 | { |
5720 | byte[] objectData = new byte[60]; | 6283 | byte[] objectData = new byte[60]; |
@@ -5737,32 +6300,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5737 | //update.JointPivot = Vector3.Zero; | 6300 | //update.JointPivot = Vector3.Zero; |
5738 | //update.JointType = 0; | 6301 | //update.JointType = 0; |
5739 | update.Material = part.Material; | 6302 | update.Material = part.Material; |
5740 | /* | ||
5741 | if (data.ParentGroup.IsAttachment) | ||
5742 | { | ||
5743 | update.NameValue | ||
5744 | = Util.StringToBytes256( | ||
5745 | string.Format("AttachItemID STRING RW SV {0}", data.ParentGroup.FromItemID)); | ||
5746 | |||
5747 | update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); | ||
5748 | |||
5749 | // m_log.DebugFormat( | ||
5750 | // "[LLCLIENTVIEW]: Sending NameValue {0} for {1} {2} to {3}", | ||
5751 | // Util.UTF8.GetString(update.NameValue), data.Name, data.LocalId, Name); | ||
5752 | // | ||
5753 | // m_log.DebugFormat( | ||
5754 | // "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}", | ||
5755 | // update.State, data.Name, data.LocalId, Name); | ||
5756 | } | ||
5757 | else | ||
5758 | { | ||
5759 | update.NameValue = Utils.EmptyBytes; | ||
5760 | |||
5761 | // The root part state is the canonical state for all parts of the object. The other part states in the | ||
5762 | // case for attachments may contain conflicting values that can end up crashing the viewer. | ||
5763 | update.State = data.ParentGroup.RootPart.Shape.State; | ||
5764 | } | ||
5765 | */ | ||
5766 | 6303 | ||
5767 | if (part.ParentGroup.IsAttachment) | 6304 | if (part.ParentGroup.IsAttachment) |
5768 | { | 6305 | { |
@@ -5858,15 +6395,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5858 | 6395 | ||
5859 | #endregion PrimFlags | 6396 | #endregion PrimFlags |
5860 | 6397 | ||
5861 | if (part.Sound != UUID.Zero || part.SoundFlags != 0) | 6398 | bool hassound = part.Sound != UUID.Zero || part.SoundFlags != 0; |
6399 | if (hassound) | ||
5862 | { | 6400 | { |
5863 | update.Sound = part.Sound; | 6401 | update.Sound = part.Sound; |
5864 | update.OwnerID = part.OwnerID; | ||
5865 | update.Gain = (float)part.SoundGain; | 6402 | update.Gain = (float)part.SoundGain; |
5866 | update.Radius = (float)part.SoundRadius; | 6403 | update.Radius = (float)part.SoundRadius; |
5867 | update.Flags = part.SoundFlags; | 6404 | update.Flags = part.SoundFlags; |
5868 | } | 6405 | } |
5869 | 6406 | ||
6407 | if(hassound || update.PSBlock.Length > 1) | ||
6408 | update.OwnerID = part.OwnerID; | ||
6409 | |||
5870 | switch ((PCode)part.Shape.PCode) | 6410 | switch ((PCode)part.Shape.PCode) |
5871 | { | 6411 | { |
5872 | case PCode.Grass: | 6412 | case PCode.Grass: |
@@ -5882,6 +6422,308 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5882 | return update; | 6422 | return update; |
5883 | } | 6423 | } |
5884 | 6424 | ||
6425 | protected void CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc) | ||
6426 | { | ||
6427 | // prepare data | ||
6428 | |||
6429 | #region PrimFlags | ||
6430 | // prim/update flags | ||
6431 | PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); | ||
6432 | // Don't send the CreateSelected flag to everyone | ||
6433 | primflags &= ~PrimFlags.CreateSelected; | ||
6434 | if (sp.UUID == part.OwnerID) | ||
6435 | { | ||
6436 | if (part.CreateSelected) | ||
6437 | { | ||
6438 | // Only send this flag once, then unset it | ||
6439 | primflags |= PrimFlags.CreateSelected; | ||
6440 | part.CreateSelected = false; | ||
6441 | } | ||
6442 | } | ||
6443 | #endregion PrimFlags | ||
6444 | |||
6445 | // data block | ||
6446 | byte[] data = null; | ||
6447 | byte state = part.Shape.State; | ||
6448 | PCode pcode = (PCode)part.Shape.PCode; | ||
6449 | |||
6450 | //vegetation is special so just do it inline | ||
6451 | if(pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree) | ||
6452 | { | ||
6453 | zc.AddUInt(part.LocalId); | ||
6454 | zc.AddByte(state); // state | ||
6455 | zc.AddUUID(part.UUID); | ||
6456 | zc.AddZeros(4); // crc unused | ||
6457 | zc.AddByte((byte)pcode); | ||
6458 | // material 1 | ||
6459 | // clickaction 1 | ||
6460 | zc.AddZeros(2); | ||
6461 | zc.AddVector3(part.Shape.Scale); | ||
6462 | |||
6463 | // objectdata block | ||
6464 | zc.AddByte(60); // fixed object block size | ||
6465 | zc.AddVector3(part.RelativePosition); | ||
6466 | if (pcode == PCode.Grass) | ||
6467 | zc.AddZeros(48); | ||
6468 | else | ||
6469 | { | ||
6470 | zc.AddZeros(24); | ||
6471 | Quaternion rot = part.RotationOffset; | ||
6472 | rot.Normalize(); | ||
6473 | zc.AddNormQuat(rot); | ||
6474 | zc.AddZeros(12); | ||
6475 | } | ||
6476 | |||
6477 | zc.AddUInt(part.ParentID); | ||
6478 | zc.AddUInt((uint)primflags); //update flags | ||
6479 | |||
6480 | /* | ||
6481 | if (pcode == PCode.Grass) | ||
6482 | { | ||
6483 | //pbs volume data 23 | ||
6484 | //texture entry 2 | ||
6485 | //texture anim 1 | ||
6486 | //name value 2 | ||
6487 | // data 1 | ||
6488 | // text 5 | ||
6489 | // media url 1 | ||
6490 | // particle system 1 | ||
6491 | // Extraparams 1 | ||
6492 | // sound id 16 | ||
6493 | // ownwer 16 | ||
6494 | // sound gain 4 | ||
6495 | // sound flags 1 | ||
6496 | // sound radius 4 | ||
6497 | // jointtype 1 | ||
6498 | // joint pivot 12 | ||
6499 | // joint offset 12 | ||
6500 | zc.AddZeros(23 + 2 + 1 + 2 + 1 + 5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12); | ||
6501 | return; | ||
6502 | } | ||
6503 | */ | ||
6504 | |||
6505 | //pbs volume data 23 | ||
6506 | //texture entry 2 | ||
6507 | //texture anim 1 | ||
6508 | //name value 2 | ||
6509 | zc.AddZeros(23 + 2 + 1 + 2); | ||
6510 | |||
6511 | //data: the tree type | ||
6512 | zc.AddByte(1); | ||
6513 | zc.AddZeros(1); | ||
6514 | zc.AddByte(state); | ||
6515 | |||
6516 | // text 5 | ||
6517 | // media url 1 | ||
6518 | // particle system 1 | ||
6519 | // Extraparams 1 | ||
6520 | // sound id 16 | ||
6521 | // ownwer 16 | ||
6522 | // sound gain 4 | ||
6523 | // sound flags 1 | ||
6524 | // sound radius 4 | ||
6525 | // jointtype 1 | ||
6526 | // joint pivot 12 | ||
6527 | // joint offset 12 | ||
6528 | zc.AddZeros(5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12); | ||
6529 | |||
6530 | return; | ||
6531 | } | ||
6532 | |||
6533 | //NameValue and state | ||
6534 | byte[] nv = null; | ||
6535 | |||
6536 | if (part.ParentGroup.IsAttachment) | ||
6537 | { | ||
6538 | if (part.IsRoot) | ||
6539 | nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); | ||
6540 | |||
6541 | int st = (int)part.ParentGroup.AttachmentPoint; | ||
6542 | state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; | ||
6543 | } | ||
6544 | |||
6545 | // filter out mesh faces hack | ||
6546 | ushort profileBegin = part.Shape.ProfileBegin; | ||
6547 | ushort profileHollow = part.Shape.ProfileHollow; | ||
6548 | byte profileCurve = part.Shape.ProfileCurve; | ||
6549 | byte pathScaleY = part.Shape.PathScaleY; | ||
6550 | |||
6551 | if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack | ||
6552 | { | ||
6553 | profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); | ||
6554 | // fix old values that confused viewers | ||
6555 | if (profileBegin == 1) | ||
6556 | profileBegin = 9375; | ||
6557 | if (profileHollow == 1) | ||
6558 | profileHollow = 27500; | ||
6559 | // fix torus hole size Y that also confuse some viewers | ||
6560 | if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150) | ||
6561 | pathScaleY = 150; | ||
6562 | } | ||
6563 | |||
6564 | // do encode the things | ||
6565 | zc.AddUInt(part.LocalId); | ||
6566 | zc.AddByte(state); // state | ||
6567 | zc.AddUUID(part.UUID); | ||
6568 | zc.AddZeros(4); // crc unused | ||
6569 | zc.AddByte((byte)pcode); | ||
6570 | zc.AddByte(part.Material); | ||
6571 | zc.AddByte(part.ClickAction); // clickaction | ||
6572 | zc.AddVector3(part.Shape.Scale); | ||
6573 | |||
6574 | // objectdata block | ||
6575 | zc.AddByte(60); // fixed object block size | ||
6576 | zc.AddVector3(part.RelativePosition); | ||
6577 | zc.AddVector3(part.Velocity); | ||
6578 | zc.AddVector3(part.Acceleration); | ||
6579 | Quaternion rotation = part.RotationOffset; | ||
6580 | rotation.Normalize(); | ||
6581 | zc.AddNormQuat(rotation); | ||
6582 | zc.AddVector3(part.AngularVelocity); | ||
6583 | |||
6584 | zc.AddUInt(part.ParentID); | ||
6585 | zc.AddUInt((uint)primflags); //update flags | ||
6586 | |||
6587 | //pbs | ||
6588 | zc.AddByte(part.Shape.PathCurve); | ||
6589 | zc.AddByte(profileCurve); | ||
6590 | zc.AddUInt16(part.Shape.PathBegin); | ||
6591 | zc.AddUInt16(part.Shape.PathEnd); | ||
6592 | zc.AddByte(part.Shape.PathScaleX); | ||
6593 | zc.AddByte(pathScaleY); | ||
6594 | zc.AddByte(part.Shape.PathShearX); | ||
6595 | zc.AddByte(part.Shape.PathShearY); | ||
6596 | zc.AddByte((byte)part.Shape.PathTwist); | ||
6597 | zc.AddByte((byte)part.Shape.PathTwistBegin); | ||
6598 | zc.AddByte((byte)part.Shape.PathRadiusOffset); | ||
6599 | zc.AddByte((byte)part.Shape.PathTaperX); | ||
6600 | zc.AddByte((byte)part.Shape.PathTaperY); | ||
6601 | zc.AddByte(part.Shape.PathRevolutions); | ||
6602 | zc.AddByte((byte)part.Shape.PathSkew); | ||
6603 | zc.AddUInt16(profileBegin); | ||
6604 | zc.AddUInt16(part.Shape.ProfileEnd); | ||
6605 | zc.AddUInt16(profileHollow); | ||
6606 | |||
6607 | // texture | ||
6608 | byte[] tentry = part.Shape.TextureEntry; | ||
6609 | if (tentry == null) | ||
6610 | zc.AddZeros(2); | ||
6611 | else | ||
6612 | { | ||
6613 | int len = tentry.Length; | ||
6614 | zc.AddByte((byte)len); | ||
6615 | zc.AddByte((byte)(len >> 8)); | ||
6616 | zc.AddBytes(tentry, len); | ||
6617 | } | ||
6618 | |||
6619 | // texture animation | ||
6620 | byte[] tanim = part.TextureAnimation; | ||
6621 | if (tanim == null) | ||
6622 | zc.AddZeros(1); | ||
6623 | else | ||
6624 | { | ||
6625 | int len = tanim.Length; | ||
6626 | zc.AddByte((byte)len); | ||
6627 | zc.AddBytes(tanim, len); | ||
6628 | } | ||
6629 | |||
6630 | //NameValue | ||
6631 | if(nv == null) | ||
6632 | zc.AddZeros(2); | ||
6633 | else | ||
6634 | { | ||
6635 | int len = nv.Length; | ||
6636 | zc.AddByte((byte)len); | ||
6637 | zc.AddByte((byte)(len >> 8)); | ||
6638 | zc.AddBytes(nv, len); | ||
6639 | } | ||
6640 | |||
6641 | // data | ||
6642 | if (data == null) | ||
6643 | zc.AddZeros(2); | ||
6644 | else | ||
6645 | { | ||
6646 | int len = data.Length; | ||
6647 | zc.AddByte((byte)len); | ||
6648 | zc.AddByte((byte)(len >> 8)); | ||
6649 | zc.AddBytes(data, len); | ||
6650 | } | ||
6651 | |||
6652 | //text | ||
6653 | if (part.Text == null || part.Text.Length == 0) | ||
6654 | zc.AddZeros(5); | ||
6655 | else | ||
6656 | { | ||
6657 | byte[] tbuf = Util.StringToBytes(part.Text, 254); | ||
6658 | int len = tbuf.Length; | ||
6659 | zc.AddByte((byte)len); | ||
6660 | zc.AddBytes(tbuf, len); | ||
6661 | |||
6662 | //textcolor | ||
6663 | byte[] tc = part.GetTextColor().GetBytes(false); | ||
6664 | zc.AddBytes(tc, 4); | ||
6665 | } | ||
6666 | |||
6667 | //media url | ||
6668 | if (part.MediaUrl == null || part.MediaUrl.Length == 0) | ||
6669 | zc.AddZeros(1); | ||
6670 | else | ||
6671 | { | ||
6672 | byte[] tbuf = Util.StringToBytes(part.MediaUrl, 255); | ||
6673 | int len = tbuf.Length; | ||
6674 | zc.AddByte((byte)len); | ||
6675 | zc.AddBytes(tbuf, len); | ||
6676 | } | ||
6677 | |||
6678 | bool hasps = false; | ||
6679 | //particle system | ||
6680 | byte[] ps = part.ParticleSystem; | ||
6681 | if (ps == null || ps.Length < 1) | ||
6682 | zc.AddZeros(1); | ||
6683 | else | ||
6684 | { | ||
6685 | int len = ps.Length; | ||
6686 | zc.AddByte((byte)len); | ||
6687 | zc.AddBytes(ps, len); | ||
6688 | hasps = true; | ||
6689 | } | ||
6690 | |||
6691 | //Extraparams | ||
6692 | byte[] ep = part.Shape.ExtraParams; | ||
6693 | if (ep == null || ep.Length < 2) | ||
6694 | zc.AddZeros(1); | ||
6695 | else | ||
6696 | { | ||
6697 | int len = ep.Length; | ||
6698 | zc.AddByte((byte)len); | ||
6699 | zc.AddBytes(ep, len); | ||
6700 | } | ||
6701 | |||
6702 | bool hassound = part.Sound != UUID.Zero || part.SoundFlags != 0; | ||
6703 | if (hassound) | ||
6704 | zc.AddUUID(part.Sound); | ||
6705 | else | ||
6706 | zc.AddZeros(16); | ||
6707 | |||
6708 | if (hassound || hasps) | ||
6709 | zc.AddUUID(part.OwnerID); | ||
6710 | else | ||
6711 | zc.AddZeros(16); | ||
6712 | |||
6713 | if (hassound) | ||
6714 | { | ||
6715 | zc.AddFloat((float)part.SoundGain); | ||
6716 | zc.AddByte(part.SoundFlags); | ||
6717 | zc.AddFloat((float)part.SoundRadius); | ||
6718 | } | ||
6719 | else | ||
6720 | zc.AddZeros(9); | ||
6721 | |||
6722 | // jointtype(1) joint pivot(12) joint offset(12) | ||
6723 | const int lastzeros = 1 + 12 + 12; | ||
6724 | zc.AddZeros(lastzeros); | ||
6725 | } | ||
6726 | |||
5885 | protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) | 6727 | protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) |
5886 | { | 6728 | { |
5887 | // TODO: Implement this | 6729 | // TODO: Implement this |
@@ -10047,7 +10889,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10047 | 10889 | ||
10048 | UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[1].Parameter), out Prey); | 10890 | UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[1].Parameter), out Prey); |
10049 | 10891 | ||
10050 | OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey); | 10892 | OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey, false); |
10051 | } | 10893 | } |
10052 | return true; | 10894 | return true; |
10053 | case "teleporthomeallusers": | 10895 | case "teleporthomeallusers": |
@@ -10195,7 +11037,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10195 | 11037 | ||
10196 | UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[0].Parameter), out Prey); | 11038 | UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[0].Parameter), out Prey); |
10197 | 11039 | ||
10198 | OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey); | 11040 | OnEstateTeleportOneUserHomeRequest(this, invoice, SenderID, Prey, true); |
10199 | } | 11041 | } |
10200 | return true; | 11042 | return true; |
10201 | 11043 | ||
@@ -12560,14 +13402,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
12560 | /// provide your own method.</param> | 13402 | /// provide your own method.</param> |
12561 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) | 13403 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) |
12562 | { | 13404 | { |
12563 | |||
12564 | /* this is causing packet loss for some reason | ||
12565 | if(!m_udpClient.IsConnected) | ||
12566 | { | ||
12567 | PacketPool.Instance.ReturnPacket(packet); | ||
12568 | return; | ||
12569 | } | ||
12570 | */ | ||
12571 | if (m_outPacketsToDrop != null) | 13405 | if (m_outPacketsToDrop != null) |
12572 | { | 13406 | { |
12573 | if (m_outPacketsToDrop.Contains(packet.Type.ToString())) | 13407 | if (m_outPacketsToDrop.Contains(packet.Type.ToString())) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 439621a..2981337 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -120,7 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
120 | /// <summary>Circuit code that this client is connected on</summary> | 120 | /// <summary>Circuit code that this client is connected on</summary> |
121 | public readonly uint CircuitCode; | 121 | public readonly uint CircuitCode; |
122 | /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary> | 122 | /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary> |
123 | public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); | 123 | public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(256); |
124 | 124 | ||
125 | /// <summary>Packets we have sent that need to be ACKed by the client</summary> | 125 | /// <summary>Packets we have sent that need to be ACKed by the client</summary> |
126 | public UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); | 126 | public UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); |
@@ -210,12 +210,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | /// <summary> | ||
214 | /// This is the percentage of the udp texture queue to add to the task queue since | ||
215 | /// textures are now generally handled through http. | ||
216 | /// </summary> | ||
217 | private double m_cannibalrate = 0.0; | ||
218 | |||
219 | private ClientInfo m_info = new ClientInfo(); | 213 | private ClientInfo m_info = new ClientInfo(); |
220 | 214 | ||
221 | /// <summary> | 215 | /// <summary> |
@@ -257,8 +251,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
257 | // Create an array of token buckets for this clients different throttle categories | 251 | // Create an array of token buckets for this clients different throttle categories |
258 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 252 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
259 | 253 | ||
260 | m_cannibalrate = rates.CannibalizeTextureRate; | ||
261 | |||
262 | m_burst = rates.Total * rates.BrustTime; | 254 | m_burst = rates.Total * rates.BrustTime; |
263 | 255 | ||
264 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 256 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
@@ -449,12 +441,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
449 | asset = Math.Max(asset, LLUDPServer.MTU); | 441 | asset = Math.Max(asset, LLUDPServer.MTU); |
450 | */ | 442 | */ |
451 | 443 | ||
452 | // Since most textures are now delivered through http, make it possible | ||
453 | // to cannibalize some of the bw from the texture throttle to use for | ||
454 | // the task queue (e.g. object updates) | ||
455 | task = task + (int)(m_cannibalrate * texture); | ||
456 | texture = (int)((1 - m_cannibalrate) * texture); | ||
457 | |||
458 | int total = resend + land + wind + cloud + task + texture + asset; | 444 | int total = resend + land + wind + cloud + task + texture + asset; |
459 | 445 | ||
460 | float m_burst = total * m_burstTime; | 446 | float m_burst = total * m_burstTime; |
@@ -575,22 +561,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
575 | { | 561 | { |
576 | DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; | 562 | DoubleLocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; |
577 | 563 | ||
578 | if (m_deliverPackets == false) | 564 | if (forceQueue || m_deliverPackets == false) |
579 | { | 565 | { |
580 | queue.Enqueue(packet, highPriority); | 566 | queue.Enqueue(packet, highPriority); |
581 | return true; | 567 | return true; |
582 | } | 568 | } |
583 | 569 | ||
584 | TokenBucket bucket = m_throttleCategories[category]; | 570 | // need to enqueue if queue is not empty |
585 | |||
586 | // Don't send this packet if queue is not empty | ||
587 | if (queue.Count > 0 || m_nextPackets[category] != null) | 571 | if (queue.Count > 0 || m_nextPackets[category] != null) |
588 | { | 572 | { |
589 | queue.Enqueue(packet, highPriority); | 573 | queue.Enqueue(packet, highPriority); |
590 | return true; | 574 | return true; |
591 | } | 575 | } |
592 | 576 | ||
593 | if (!forceQueue && bucket.CheckTokens(packet.Buffer.DataLength)) | 577 | // check bandwidth |
578 | TokenBucket bucket = m_throttleCategories[category]; | ||
579 | if (bucket.CheckTokens(packet.Buffer.DataLength)) | ||
594 | { | 580 | { |
595 | // enough tokens so it can be sent imediatly by caller | 581 | // enough tokens so it can be sent imediatly by caller |
596 | bucket.RemoveTokens(packet.Buffer.DataLength); | 582 | bucket.RemoveTokens(packet.Buffer.DataLength); |
@@ -608,7 +594,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
608 | // We don't have a token bucket for this category, so it will not be queued | 594 | // We don't have a token bucket for this category, so it will not be queued |
609 | return false; | 595 | return false; |
610 | } | 596 | } |
611 | |||
612 | } | 597 | } |
613 | 598 | ||
614 | /// <summary> | 599 | /// <summary> |
@@ -650,6 +635,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
650 | // leaving a dequeued packet still waiting to be sent out. Try to | 635 | // leaving a dequeued packet still waiting to be sent out. Try to |
651 | // send it again | 636 | // send it again |
652 | OutgoingPacket nextPacket = m_nextPackets[i]; | 637 | OutgoingPacket nextPacket = m_nextPackets[i]; |
638 | if(nextPacket.Buffer == null) | ||
639 | { | ||
640 | if (m_packetOutboxes[i].Count < 5) | ||
641 | emptyCategories |= CategoryToFlag(i); | ||
642 | continue; | ||
643 | } | ||
653 | if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) | 644 | if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) |
654 | { | 645 | { |
655 | // Send the packet | 646 | // Send the packet |
@@ -681,21 +672,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
681 | { | 672 | { |
682 | // A packet was pulled off the queue. See if we have | 673 | // A packet was pulled off the queue. See if we have |
683 | // enough tokens in the bucket to send it out | 674 | // enough tokens in the bucket to send it out |
684 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) | 675 | if(packet.Buffer == null) |
685 | { | 676 | { |
686 | // Send the packet | 677 | // packet canceled elsewhere (by a ack for example) |
687 | m_udpServer.SendPacketFinal(packet); | ||
688 | packetSent = true; | ||
689 | |||
690 | if (queue.Count < 5) | 678 | if (queue.Count < 5) |
691 | emptyCategories |= CategoryToFlag(i); | 679 | emptyCategories |= CategoryToFlag(i); |
692 | } | 680 | } |
693 | else | 681 | else |
694 | { | 682 | { |
695 | // Save the dequeued packet for the next iteration | 683 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) |
696 | m_nextPackets[i] = packet; | 684 | { |
685 | // Send the packet | ||
686 | m_udpServer.SendPacketFinal(packet); | ||
687 | packetSent = true; | ||
688 | |||
689 | if (queue.Count < 5) | ||
690 | emptyCategories |= CategoryToFlag(i); | ||
691 | } | ||
692 | else | ||
693 | { | ||
694 | // Save the dequeued packet for the next iteration | ||
695 | m_nextPackets[i] = packet; | ||
696 | } | ||
697 | } | 697 | } |
698 | |||
699 | } | 698 | } |
700 | else | 699 | else |
701 | { | 700 | { |
@@ -803,8 +802,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
803 | } | 802 | } |
804 | } | 803 | } |
805 | 804 | ||
806 | |||
807 | |||
808 | /// <summary> | 805 | /// <summary> |
809 | /// Fires the OnQueueEmpty callback and sets the minimum time that it | 806 | /// Fires the OnQueueEmpty callback and sets the minimum time that it |
810 | /// can be called again | 807 | /// can be called again |
@@ -843,6 +840,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
843 | return 0; | 840 | return 0; |
844 | } | 841 | } |
845 | 842 | ||
843 | public void FreeUDPBuffer(UDPPacketBuffer buf) | ||
844 | { | ||
845 | m_udpServer.FreeUDPBuffer(buf); | ||
846 | } | ||
847 | |||
846 | /// <summary> | 848 | /// <summary> |
847 | /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a | 849 | /// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a |
848 | /// flag value | 850 | /// flag value |
@@ -853,34 +855,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
853 | { | 855 | { |
854 | ThrottleOutPacketType category = (ThrottleOutPacketType)i; | 856 | ThrottleOutPacketType category = (ThrottleOutPacketType)i; |
855 | 857 | ||
856 | /* | ||
857 | * Land = 1, | ||
858 | /// <summary>Wind data</summary> | ||
859 | Wind = 2, | ||
860 | /// <summary>Cloud data</summary> | ||
861 | Cloud = 3, | ||
862 | /// <summary>Any packets that do not fit into the other throttles</summary> | ||
863 | Task = 4, | ||
864 | /// <summary>Texture assets</summary> | ||
865 | Texture = 5, | ||
866 | /// <summary>Non-texture assets</summary> | ||
867 | Asset = 6, | ||
868 | */ | ||
869 | |||
870 | switch (category) | 858 | switch (category) |
871 | { | 859 | { |
872 | case ThrottleOutPacketType.Land: | 860 | case ThrottleOutPacketType.Land: |
873 | return ThrottleOutPacketTypeFlags.Land; | 861 | return ThrottleOutPacketTypeFlags.Land; // Terrain data |
874 | case ThrottleOutPacketType.Wind: | 862 | case ThrottleOutPacketType.Wind: |
875 | return ThrottleOutPacketTypeFlags.Wind; | 863 | return ThrottleOutPacketTypeFlags.Wind; // Wind data |
876 | case ThrottleOutPacketType.Cloud: | 864 | case ThrottleOutPacketType.Cloud: |
877 | return ThrottleOutPacketTypeFlags.Cloud; | 865 | return ThrottleOutPacketTypeFlags.Cloud; // Cloud data |
878 | case ThrottleOutPacketType.Task: | 866 | case ThrottleOutPacketType.Task: |
879 | return ThrottleOutPacketTypeFlags.Task; | 867 | return ThrottleOutPacketTypeFlags.Task; // Object updates and everything not on the other categories |
880 | case ThrottleOutPacketType.Texture: | 868 | case ThrottleOutPacketType.Texture: |
881 | return ThrottleOutPacketTypeFlags.Texture; | 869 | return ThrottleOutPacketTypeFlags.Texture; // Textures data (also impacts http texture and mesh by default) |
882 | case ThrottleOutPacketType.Asset: | 870 | case ThrottleOutPacketType.Asset: |
883 | return ThrottleOutPacketTypeFlags.Asset; | 871 | return ThrottleOutPacketTypeFlags.Asset; // Non-texture Assets data |
884 | default: | 872 | default: |
885 | return 0; | 873 | return 0; |
886 | } | 874 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 35d29a5..2300800 100644..100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -256,6 +256,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
256 | 256 | ||
257 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> | 257 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> |
258 | public const int MTU = 1400; | 258 | public const int MTU = 1400; |
259 | public const int MAXPAYLOAD = 1250; | ||
259 | 260 | ||
260 | /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary> | 261 | /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary> |
261 | public int ClientLogoutsDueToNoReceives { get; protected set; } | 262 | public int ClientLogoutsDueToNoReceives { get; protected set; } |
@@ -274,10 +275,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
274 | /// <summary>The measured resolution of Environment.TickCount</summary> | 275 | /// <summary>The measured resolution of Environment.TickCount</summary> |
275 | public readonly float TickCountResolution; | 276 | public readonly float TickCountResolution; |
276 | 277 | ||
277 | /// <summary>Number of prim updates to put on the queue each time the | ||
278 | /// OnQueueEmpty event is triggered for updates</summary> | ||
279 | public readonly int PrimUpdatesPerCallback; | ||
280 | |||
281 | /// <summary>Number of texture packets to put on the queue each time the | 278 | /// <summary>Number of texture packets to put on the queue each time the |
282 | /// OnQueueEmpty event is triggered for textures</summary> | 279 | /// OnQueueEmpty event is triggered for textures</summary> |
283 | public readonly int TextureSendLimit; | 280 | public readonly int TextureSendLimit; |
@@ -344,18 +341,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
344 | 341 | ||
345 | protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); | 342 | protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); |
346 | 343 | ||
347 | protected Pool<IncomingPacket> m_incomingPacketPool; | ||
348 | |||
349 | /// <summary> | ||
350 | /// Stat for number of packets in the main pool awaiting use. | ||
351 | /// </summary> | ||
352 | protected Stat m_poolCountStat; | ||
353 | |||
354 | /// <summary> | ||
355 | /// Stat for number of packets in the inbound packet pool awaiting use. | ||
356 | /// </summary> | ||
357 | protected Stat m_incomingPacketPoolStat; | ||
358 | |||
359 | protected int m_defaultRTO = 0; | 344 | protected int m_defaultRTO = 0; |
360 | protected int m_maxRTO = 0; | 345 | protected int m_maxRTO = 0; |
361 | protected int m_ackTimeout = 0; | 346 | protected int m_ackTimeout = 0; |
@@ -452,7 +437,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
452 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); | 437 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); |
453 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); | 438 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); |
454 | 439 | ||
455 | PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); | ||
456 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); | 440 | TextureSendLimit = config.GetInt("TextureSendLimit", 20); |
457 | 441 | ||
458 | m_defaultRTO = config.GetInt("DefaultRTO", 0); | 442 | m_defaultRTO = config.GetInt("DefaultRTO", 0); |
@@ -463,7 +447,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
463 | } | 447 | } |
464 | else | 448 | else |
465 | { | 449 | { |
466 | PrimUpdatesPerCallback = 100; | ||
467 | TextureSendLimit = 20; | 450 | TextureSendLimit = 20; |
468 | m_ackTimeout = 1000 * 60; // 1 minute | 451 | m_ackTimeout = 1000 * 60; // 1 minute |
469 | m_pausedAckTimeout = 1000 * 300; // 5 minutes | 452 | m_pausedAckTimeout = 1000 * 300; // 5 minutes |
@@ -498,7 +481,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
498 | 481 | ||
499 | // if (usePools) | 482 | // if (usePools) |
500 | // EnablePools(); | 483 | // EnablePools(); |
501 | base.DisablePools(); | ||
502 | } | 484 | } |
503 | 485 | ||
504 | public void Start() | 486 | public void Start() |
@@ -554,83 +536,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
554 | OqrEngine.Stop(); | 536 | OqrEngine.Stop(); |
555 | } | 537 | } |
556 | 538 | ||
557 | public override bool EnablePools() | ||
558 | { | ||
559 | if (!UsePools) | ||
560 | { | ||
561 | base.EnablePools(); | ||
562 | |||
563 | m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); | ||
564 | |||
565 | return true; | ||
566 | } | ||
567 | |||
568 | return false; | ||
569 | } | ||
570 | |||
571 | public override bool DisablePools() | ||
572 | { | ||
573 | if (UsePools) | ||
574 | { | ||
575 | base.DisablePools(); | ||
576 | |||
577 | StatsManager.DeregisterStat(m_incomingPacketPoolStat); | ||
578 | |||
579 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | ||
580 | |||
581 | return true; | ||
582 | } | ||
583 | |||
584 | return false; | ||
585 | } | ||
586 | |||
587 | /// <summary> | ||
588 | /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene | ||
589 | /// stats. | ||
590 | /// </summary> | ||
591 | protected internal void EnablePoolStats() | ||
592 | { | ||
593 | m_poolCountStat | ||
594 | = new Stat( | ||
595 | "UDPPacketBufferPoolCount", | ||
596 | "Objects within the UDPPacketBuffer pool", | ||
597 | "The number of objects currently stored within the UDPPacketBuffer pool", | ||
598 | "", | ||
599 | "clientstack", | ||
600 | Scene.Name, | ||
601 | StatType.Pull, | ||
602 | stat => stat.Value = Pool.Count, | ||
603 | StatVerbosity.Debug); | ||
604 | |||
605 | StatsManager.RegisterStat(m_poolCountStat); | ||
606 | |||
607 | m_incomingPacketPoolStat | ||
608 | = new Stat( | ||
609 | "IncomingPacketPoolCount", | ||
610 | "Objects within incoming packet pool", | ||
611 | "The number of objects currently stored within the incoming packet pool", | ||
612 | "", | ||
613 | "clientstack", | ||
614 | Scene.Name, | ||
615 | StatType.Pull, | ||
616 | stat => stat.Value = m_incomingPacketPool.Count, | ||
617 | StatVerbosity.Debug); | ||
618 | |||
619 | StatsManager.RegisterStat(m_incomingPacketPoolStat); | ||
620 | } | ||
621 | |||
622 | /// <summary> | ||
623 | /// Disables pool stats. | ||
624 | /// </summary> | ||
625 | protected internal void DisablePoolStats() | ||
626 | { | ||
627 | StatsManager.DeregisterStat(m_poolCountStat); | ||
628 | m_poolCountStat = null; | ||
629 | |||
630 | StatsManager.DeregisterStat(m_incomingPacketPoolStat); | ||
631 | m_incomingPacketPoolStat = null; | ||
632 | } | ||
633 | |||
634 | /// <summary> | 539 | /// <summary> |
635 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. | 540 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. |
636 | /// </summary> | 541 | /// </summary> |
@@ -658,8 +563,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
658 | string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), | 563 | string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), |
659 | "INCOMING PACKET ASYNC HANDLING ENGINE"); | 564 | "INCOMING PACKET ASYNC HANDLING ENGINE"); |
660 | */ | 565 | */ |
661 | OqrEngine | 566 | OqrEngine = new JobEngine( |
662 | = new JobEngine( | ||
663 | string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), | 567 | string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), |
664 | "OUTGOING QUEUE REFILL ENGINE"); | 568 | "OUTGOING QUEUE REFILL ENGINE"); |
665 | 569 | ||
@@ -769,15 +673,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
769 | stat => stat.Value = OqrEngine.JobsWaiting, | 673 | stat => stat.Value = OqrEngine.JobsWaiting, |
770 | StatVerbosity.Debug)); | 674 | StatVerbosity.Debug)); |
771 | 675 | ||
772 | // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by | 676 | StatsManager.RegisterStat( |
773 | // scene name | 677 | new Stat( |
774 | if (UsePools) | 678 | "UDPBuffersPoolCount", |
775 | EnablePoolStats(); | 679 | "Buffers in the UDP buffers pool", |
776 | 680 | "The number of buffers currently stored within the UDP buffers pool", | |
681 | "", | ||
682 | "clientstack", | ||
683 | Scene.Name, | ||
684 | StatType.Pull, | ||
685 | stat => stat.Value = m_udpBuffersPoolPtr + 1, | ||
686 | StatVerbosity.Debug)); | ||
777 | 687 | ||
778 | LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); | 688 | LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); |
779 | commands.Register(); | 689 | commands.Register(); |
780 | |||
781 | } | 690 | } |
782 | 691 | ||
783 | public bool HandlesRegion(Location x) | 692 | public bool HandlesRegion(Location x) |
@@ -939,9 +848,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
939 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting | 848 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting |
940 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here | 849 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here |
941 | // to accomodate for both common scenarios and provide ample room for ACK appending in both | 850 | // to accomodate for both common scenarios and provide ample room for ACK appending in both |
942 | int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; | 851 | //int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; |
943 | 852 | ||
944 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); | 853 | //UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); |
854 | UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); | ||
945 | 855 | ||
946 | // Zerocode if needed | 856 | // Zerocode if needed |
947 | if (doZerocode) | 857 | if (doZerocode) |
@@ -971,7 +881,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
971 | // If the packet data wasn't already copied during zerocoding, copy it now | 881 | // If the packet data wasn't already copied during zerocoding, copy it now |
972 | if (doCopy) | 882 | if (doCopy) |
973 | { | 883 | { |
974 | if (dataLength <= buffer.Data.Length) | 884 | //if (dataLength <= buffer.Data.Length) |
885 | if (dataLength <= LLUDPServer.MTU) | ||
975 | { | 886 | { |
976 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 887 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); |
977 | } | 888 | } |
@@ -979,7 +890,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
979 | { | 890 | { |
980 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + | 891 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + |
981 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); | 892 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); |
982 | buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); | 893 | // buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); |
894 | buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); | ||
983 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 895 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); |
984 | } | 896 | } |
985 | } | 897 | } |
@@ -1017,6 +929,89 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1017 | #endregion Queue or Send | 929 | #endregion Queue or Send |
1018 | } | 930 | } |
1019 | 931 | ||
932 | public unsafe UDPPacketBuffer ZeroEncode(UDPPacketBuffer input) | ||
933 | { | ||
934 | UDPPacketBuffer zb = GetNewUDPBuffer(null); | ||
935 | int srclen = input.DataLength; | ||
936 | byte[] src = input.Data; | ||
937 | byte[] dest = zb.Data; | ||
938 | |||
939 | int zerolen = 6; | ||
940 | byte zerocount = 0; | ||
941 | |||
942 | for (int i = zerolen; i < srclen; i++) | ||
943 | { | ||
944 | if (src[i] == 0x00) | ||
945 | { | ||
946 | zerocount++; | ||
947 | if (zerocount == 0) | ||
948 | { | ||
949 | dest[zerolen++] = 0x00; | ||
950 | dest[zerolen++] = 0xff; | ||
951 | zerocount++; | ||
952 | } | ||
953 | } | ||
954 | else | ||
955 | { | ||
956 | if (zerocount != 0) | ||
957 | { | ||
958 | dest[zerolen++] = 0x00; | ||
959 | dest[zerolen++] = zerocount; | ||
960 | zerocount = 0; | ||
961 | } | ||
962 | |||
963 | dest[zerolen++] = src[i]; | ||
964 | } | ||
965 | } | ||
966 | |||
967 | if (zerocount != 0) | ||
968 | { | ||
969 | dest[zerolen++] = 0x00; | ||
970 | dest[zerolen++] = zerocount; | ||
971 | } | ||
972 | |||
973 | if(zerolen >= srclen) | ||
974 | { | ||
975 | FreeUDPBuffer(zb); | ||
976 | |||
977 | src[0] &= unchecked((byte)~Helpers.MSG_ZEROCODED); | ||
978 | return input; | ||
979 | } | ||
980 | |||
981 | Buffer.BlockCopy(src, 0, dest, 0, 6); | ||
982 | |||
983 | zb.RemoteEndPoint = input.RemoteEndPoint; | ||
984 | zb.DataLength = zerolen; | ||
985 | |||
986 | FreeUDPBuffer(input); | ||
987 | |||
988 | return zb; | ||
989 | } | ||
990 | |||
991 | public void SendUDPPacket( | ||
992 | LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category, UnackedPacketMethod method, bool forcequeue, bool zerocode) | ||
993 | { | ||
994 | bool highPriority = false; | ||
995 | |||
996 | if(zerocode) | ||
997 | buffer = ZeroEncode(buffer); | ||
998 | |||
999 | if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0) | ||
1000 | { | ||
1001 | category = (ThrottleOutPacketType)((int)category & 127); | ||
1002 | highPriority = true; | ||
1003 | } | ||
1004 | |||
1005 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); | ||
1006 | |||
1007 | // If we were not provided a method for handling unacked, use the UDPServer default method | ||
1008 | if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0) | ||
1009 | outgoingPacket.UnackedMethod = ((method == null) ? delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method); | ||
1010 | |||
1011 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forcequeue, highPriority)) | ||
1012 | SendPacketFinal(outgoingPacket); | ||
1013 | } | ||
1014 | |||
1020 | public void SendAcks(LLUDPClient udpClient) | 1015 | public void SendAcks(LLUDPClient udpClient) |
1021 | { | 1016 | { |
1022 | uint ack; | 1017 | uint ack; |
@@ -1066,7 +1061,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1066 | { | 1061 | { |
1067 | LLUDPClient udpClient = client.UDPClient; | 1062 | LLUDPClient udpClient = client.UDPClient; |
1068 | 1063 | ||
1069 | if (!udpClient.IsConnected) | 1064 | if (!client.IsActive || !udpClient.IsConnected) |
1070 | return; | 1065 | return; |
1071 | 1066 | ||
1072 | // Disconnect an agent if no packets are received for some time | 1067 | // Disconnect an agent if no packets are received for some time |
@@ -1136,14 +1131,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1136 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) | 1131 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) |
1137 | { | 1132 | { |
1138 | UDPPacketBuffer buffer = outgoingPacket.Buffer; | 1133 | UDPPacketBuffer buffer = outgoingPacket.Buffer; |
1134 | if(buffer == null) // canceled packet | ||
1135 | return; | ||
1136 | LLUDPClient udpClient = outgoingPacket.Client; | ||
1137 | if (!udpClient.IsConnected) | ||
1138 | return; | ||
1139 | |||
1139 | byte flags = buffer.Data[0]; | 1140 | byte flags = buffer.Data[0]; |
1140 | bool isResend = (flags & Helpers.MSG_RESENT) != 0; | 1141 | bool isResend = (flags & Helpers.MSG_RESENT) != 0; |
1141 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; | 1142 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; |
1142 | bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; | 1143 | bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; |
1143 | LLUDPClient udpClient = outgoingPacket.Client; | ||
1144 | |||
1145 | if (!udpClient.IsConnected) | ||
1146 | return; | ||
1147 | 1144 | ||
1148 | int dataLength = buffer.DataLength; | 1145 | int dataLength = buffer.DataLength; |
1149 | 1146 | ||
@@ -1154,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1154 | // no more ACKs to append | 1151 | // no more ACKs to append |
1155 | int ackCount = 0; | 1152 | int ackCount = 0; |
1156 | uint ack; | 1153 | uint ack; |
1157 | while (dataLength + 5 < buffer.Data.Length && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) | 1154 | while (dataLength + 5 < MTU && ackCount < 256 && udpClient.PendingAcks.Dequeue(out ack)) |
1158 | { | 1155 | { |
1159 | Utils.UIntToBytesBig(ack, buffer.Data, dataLength); | 1156 | Utils.UIntToBytesBig(ack, buffer.Data, dataLength); |
1160 | dataLength += 4; | 1157 | dataLength += 4; |
@@ -1168,22 +1165,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1168 | // Set the appended ACKs flag on this packet | 1165 | // Set the appended ACKs flag on this packet |
1169 | buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); | 1166 | buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); |
1170 | } | 1167 | } |
1168 | buffer.DataLength = dataLength; | ||
1171 | } | 1169 | } |
1172 | 1170 | ||
1173 | buffer.DataLength = dataLength; | ||
1174 | |||
1175 | if (!isResend) | 1171 | if (!isResend) |
1176 | { | 1172 | { |
1177 | // Not a resend, assign a new sequence number | 1173 | // Not a resend, assign a new sequence number |
1178 | uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence); | 1174 | uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence); |
1179 | Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); | 1175 | Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); |
1180 | outgoingPacket.SequenceNumber = sequenceNumber; | 1176 | outgoingPacket.SequenceNumber = sequenceNumber; |
1181 | |||
1182 | if (isReliable) | ||
1183 | { | ||
1184 | // Add this packet to the list of ACK responses we are waiting on from the server | ||
1185 | udpClient.NeedAcks.Add(outgoingPacket); | ||
1186 | } | ||
1187 | } | 1177 | } |
1188 | else | 1178 | else |
1189 | { | 1179 | { |
@@ -1196,9 +1186,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1196 | PacketsSentCount++; | 1186 | PacketsSentCount++; |
1197 | 1187 | ||
1198 | SyncSend(buffer); | 1188 | SyncSend(buffer); |
1189 | |||
1199 | // Keep track of when this packet was sent out (right now) | 1190 | // Keep track of when this packet was sent out (right now) |
1200 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; | 1191 | outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; |
1201 | 1192 | ||
1193 | if (outgoingPacket.UnackedMethod == null) | ||
1194 | FreeUDPBuffer(buffer); | ||
1195 | else if(!isResend) | ||
1196 | { | ||
1197 | // Add this packet to the list of ACK responses we are waiting on from the server | ||
1198 | udpClient.NeedAcks.Add(outgoingPacket); | ||
1199 | } | ||
1200 | |||
1202 | if (udpClient.DebugDataOutLevel > 0) | 1201 | if (udpClient.DebugDataOutLevel > 0) |
1203 | m_log.DebugFormat( | 1202 | m_log.DebugFormat( |
1204 | "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", | 1203 | "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", |
@@ -1240,7 +1239,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1240 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | 1239 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); |
1241 | 1240 | ||
1242 | RecordMalformedInboundPacket(endPoint); | 1241 | RecordMalformedInboundPacket(endPoint); |
1243 | 1242 | FreeUDPBuffer(buffer); | |
1244 | return; // Drop undersized packet | 1243 | return; // Drop undersized packet |
1245 | } | 1244 | } |
1246 | 1245 | ||
@@ -1260,21 +1259,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1260 | // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | 1259 | // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); |
1261 | 1260 | ||
1262 | RecordMalformedInboundPacket(endPoint); | 1261 | RecordMalformedInboundPacket(endPoint); |
1263 | 1262 | FreeUDPBuffer(buffer); | |
1264 | return; // Malformed header | 1263 | return; // Malformed header |
1265 | } | 1264 | } |
1266 | 1265 | ||
1267 | try | 1266 | try |
1268 | { | 1267 | { |
1269 | // packet = Packet.BuildPacket(buffer.Data, ref packetEnd, | 1268 | // get a buffer for zero decode using the udp buffers pool |
1270 | // // Only allocate a buffer for zerodecoding if the packet is zerocoded | 1269 | UDPPacketBuffer zerodecodebufferholder = null; |
1271 | // ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); | 1270 | byte[] zerodecodebuffer = null; |
1271 | // only if needed | ||
1272 | if (((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0)) | ||
1273 | { | ||
1274 | zerodecodebufferholder = GetNewUDPBuffer(null); | ||
1275 | zerodecodebuffer = zerodecodebufferholder.Data; | ||
1276 | } | ||
1277 | |||
1278 | packet = Packet.BuildPacket(buffer.Data, ref packetEnd, zerodecodebuffer); | ||
1272 | // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we | 1279 | // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we |
1273 | // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all | 1280 | // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all |
1274 | // bytes are copied out). | 1281 | // bytes are copied out). |
1275 | packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, | 1282 | // packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, zerodecodebuffer); |
1276 | // Only allocate a buffer for zerodecoding if the packet is zerocoded | 1283 | if(zerodecodebufferholder != null) |
1277 | ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); | 1284 | FreeUDPBuffer(zerodecodebufferholder); |
1278 | } | 1285 | } |
1279 | catch (Exception e) | 1286 | catch (Exception e) |
1280 | { | 1287 | { |
@@ -1292,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1292 | } | 1299 | } |
1293 | 1300 | ||
1294 | RecordMalformedInboundPacket(endPoint); | 1301 | RecordMalformedInboundPacket(endPoint); |
1295 | 1302 | FreeUDPBuffer(buffer); | |
1296 | return; | 1303 | return; |
1297 | } | 1304 | } |
1298 | 1305 | ||
@@ -1311,17 +1318,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1311 | lock (m_pendingCache) | 1318 | lock (m_pendingCache) |
1312 | { | 1319 | { |
1313 | if (m_pendingCache.Contains(endPoint)) | 1320 | if (m_pendingCache.Contains(endPoint)) |
1321 | { | ||
1322 | FreeUDPBuffer(buffer); | ||
1314 | return; | 1323 | return; |
1324 | } | ||
1315 | 1325 | ||
1316 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); | 1326 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); |
1317 | } | 1327 | } |
1318 | 1328 | ||
1319 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | 1329 | Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet }); |
1320 | // buffer. | 1330 | FreeUDPBuffer(buffer); |
1321 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1322 | |||
1323 | Util.FireAndForget(HandleUseCircuitCode, array); | ||
1324 | |||
1325 | return; | 1331 | return; |
1326 | } | 1332 | } |
1327 | } | 1333 | } |
@@ -1336,24 +1342,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1336 | queue.Enqueue(buffer); | 1342 | queue.Enqueue(buffer); |
1337 | return; | 1343 | return; |
1338 | } | 1344 | } |
1339 | |||
1340 | /* | ||
1341 | else if (packet.Type == PacketType.CompleteAgentMovement) | ||
1342 | { | ||
1343 | // Send ack straight away to let the viewer know that we got it. | ||
1344 | SendAckImmediate(endPoint, packet.Header.Sequence); | ||
1345 | |||
1346 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the | ||
1347 | // buffer. | ||
1348 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
1349 | |||
1350 | Util.FireAndForget(HandleCompleteMovementIntoRegion, array); | ||
1351 | |||
1352 | return; | ||
1353 | } | ||
1354 | */ | ||
1355 | } | 1345 | } |
1356 | 1346 | ||
1347 | FreeUDPBuffer(buffer); | ||
1348 | |||
1357 | // Determine which agent this packet came from | 1349 | // Determine which agent this packet came from |
1358 | if (client == null || !(client is LLClientView)) | 1350 | if (client == null || !(client is LLClientView)) |
1359 | { | 1351 | { |
@@ -1471,10 +1463,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1471 | LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); | 1463 | LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); |
1472 | #endregion BinaryStats | 1464 | #endregion BinaryStats |
1473 | 1465 | ||
1474 | |||
1475 | //AgentUpdate removed from here | ||
1476 | |||
1477 | |||
1478 | #region Ping Check Handling | 1466 | #region Ping Check Handling |
1479 | 1467 | ||
1480 | if (packet.Type == PacketType.StartPingCheck) | 1468 | if (packet.Type == PacketType.StartPingCheck) |
@@ -1506,17 +1494,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1506 | 1494 | ||
1507 | IncomingPacket incomingPacket; | 1495 | IncomingPacket incomingPacket; |
1508 | 1496 | ||
1509 | // Inbox insertion | 1497 | incomingPacket = new IncomingPacket((LLClientView)client, packet); |
1510 | if (UsePools) | ||
1511 | { | ||
1512 | incomingPacket = m_incomingPacketPool.GetObject(); | ||
1513 | incomingPacket.Client = (LLClientView)client; | ||
1514 | incomingPacket.Packet = packet; | ||
1515 | } | ||
1516 | else | ||
1517 | { | ||
1518 | incomingPacket = new IncomingPacket((LLClientView)client, packet); | ||
1519 | } | ||
1520 | 1498 | ||
1521 | // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || | 1499 | // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || |
1522 | // incomingPacket.Packet.Type == PacketType.ChatFromViewer) | 1500 | // incomingPacket.Packet.Type == PacketType.ChatFromViewer) |
@@ -1525,7 +1503,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1525 | // else | 1503 | // else |
1526 | // packetInbox.Enqueue(incomingPacket); | 1504 | // packetInbox.Enqueue(incomingPacket); |
1527 | packetInbox.Add(incomingPacket); | 1505 | packetInbox.Add(incomingPacket); |
1528 | |||
1529 | } | 1506 | } |
1530 | 1507 | ||
1531 | #region BinaryStats | 1508 | #region BinaryStats |
@@ -1685,7 +1662,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1685 | { | 1662 | { |
1686 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | 1663 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); |
1687 | return; | 1664 | return; |
1688 | |||
1689 | } | 1665 | } |
1690 | m_pendingCache.Remove(endPoint); | 1666 | m_pendingCache.Remove(endPoint); |
1691 | } | 1667 | } |
@@ -1881,13 +1857,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1881 | byte[] packetData = ack.ToBytes(); | 1857 | byte[] packetData = ack.ToBytes(); |
1882 | int length = packetData.Length; | 1858 | int length = packetData.Length; |
1883 | 1859 | ||
1884 | UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); | 1860 | UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint); |
1885 | buffer.DataLength = length; | 1861 | buffer.DataLength = length; |
1886 | 1862 | ||
1887 | Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); | 1863 | Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); |
1888 | 1864 | ||
1889 | // AsyncBeginSend(buffer); | 1865 | // AsyncBeginSend(buffer); |
1890 | SyncSend(buffer); | 1866 | SyncSend(buffer); |
1867 | FreeUDPBuffer(buffer); | ||
1891 | } | 1868 | } |
1892 | 1869 | ||
1893 | protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) | 1870 | protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) |
@@ -1982,21 +1959,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1982 | Scene.ThreadAlive(1); | 1959 | Scene.ThreadAlive(1); |
1983 | try | 1960 | try |
1984 | { | 1961 | { |
1985 | packetInbox.TryTake(out incomingPacket, 250); | 1962 | packetInbox.TryTake(out incomingPacket, 4500); |
1986 | 1963 | ||
1987 | if (incomingPacket != null && IsRunningInbound) | 1964 | if (incomingPacket != null && IsRunningInbound) |
1988 | { | 1965 | { |
1989 | ProcessInPacket(incomingPacket); | 1966 | ProcessInPacket(incomingPacket); |
1990 | |||
1991 | if (UsePools) | ||
1992 | { | ||
1993 | incomingPacket.Client = null; | ||
1994 | m_incomingPacketPool.ReturnObject(incomingPacket); | ||
1995 | } | ||
1996 | incomingPacket = null; | 1967 | incomingPacket = null; |
1997 | } | 1968 | } |
1998 | } | 1969 | } |
1999 | catch(Exception ex) | 1970 | catch (ThreadAbortException) |
1971 | { | ||
1972 | Thread.ResetAbort(); | ||
1973 | } | ||
1974 | catch (Exception ex) | ||
2000 | { | 1975 | { |
2001 | m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); | 1976 | m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); |
2002 | } | 1977 | } |
@@ -2025,7 +2000,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2025 | { | 2000 | { |
2026 | Scene.ThreadAlive(2); | 2001 | Scene.ThreadAlive(2); |
2027 | 2002 | ||
2028 | |||
2029 | try | 2003 | try |
2030 | { | 2004 | { |
2031 | m_packetSent = false; | 2005 | m_packetSent = false; |
@@ -2080,7 +2054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2080 | } | 2054 | } |
2081 | else if (!m_packetSent) | 2055 | else if (!m_packetSent) |
2082 | // Thread.Sleep((int)TickCountResolution); outch this is bad on linux | 2056 | // Thread.Sleep((int)TickCountResolution); outch this is bad on linux |
2083 | Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms. | 2057 | Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms. |
2084 | 2058 | ||
2085 | Watchdog.UpdateThread(); | 2059 | Watchdog.UpdateThread(); |
2086 | } | 2060 | } |
@@ -2104,14 +2078,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2104 | 2078 | ||
2105 | if (udpClient.IsConnected) | 2079 | if (udpClient.IsConnected) |
2106 | { | 2080 | { |
2107 | if (m_resendUnacked) | 2081 | if (client.IsActive && m_resendUnacked) |
2108 | HandleUnacked(llClient); | 2082 | HandleUnacked(llClient); |
2109 | 2083 | ||
2110 | if (m_sendAcks) | 2084 | if (client.IsActive) |
2111 | SendAcks(udpClient); | 2085 | { |
2086 | if (m_sendAcks) | ||
2087 | SendAcks(udpClient); | ||
2112 | 2088 | ||
2113 | if (m_sendPing) | 2089 | if (m_sendPing) |
2114 | SendPing(udpClient); | 2090 | SendPing(udpClient); |
2091 | } | ||
2115 | 2092 | ||
2116 | // Dequeue any outgoing packets that are within the throttle limits | 2093 | // Dequeue any outgoing packets that are within the throttle limits |
2117 | if (udpClient.DequeueOutgoing()) | 2094 | if (udpClient.DequeueOutgoing()) |
@@ -2124,7 +2101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2124 | m_log.Error( | 2101 | m_log.Error( |
2125 | string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); | 2102 | string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); |
2126 | } | 2103 | } |
2127 | client = null; | ||
2128 | } | 2104 | } |
2129 | 2105 | ||
2130 | #region Emergency Monitoring | 2106 | #region Emergency Monitoring |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs index 012a57d..a4d7eb9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs | |||
@@ -777,41 +777,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
777 | m_udpServer.StopOutbound(); | 777 | m_udpServer.StopOutbound(); |
778 | } | 778 | } |
779 | 779 | ||
780 | private void HandlePoolCommand(string module, string[] args) | ||
781 | { | ||
782 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | ||
783 | return; | ||
784 | |||
785 | if (args.Length != 4) | ||
786 | { | ||
787 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
788 | return; | ||
789 | } | ||
790 | |||
791 | string enabled = args[3]; | ||
792 | |||
793 | if (enabled == "on") | ||
794 | { | ||
795 | if (m_udpServer.EnablePools()) | ||
796 | { | ||
797 | m_udpServer.EnablePoolStats(); | ||
798 | MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name); | ||
799 | } | ||
800 | } | ||
801 | else if (enabled == "off") | ||
802 | { | ||
803 | if (m_udpServer.DisablePools()) | ||
804 | { | ||
805 | m_udpServer.DisablePoolStats(); | ||
806 | MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name); | ||
807 | } | ||
808 | } | ||
809 | else | ||
810 | { | ||
811 | MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); | ||
812 | } | ||
813 | } | ||
814 | |||
815 | private void HandleAgentUpdateCommand(string module, string[] args) | 780 | private void HandleAgentUpdateCommand(string module, string[] args) |
816 | { | 781 | { |
817 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) | 782 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) |
@@ -834,8 +799,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
834 | MainConsole.Instance.OutputFormat( | 799 | MainConsole.Instance.OutputFormat( |
835 | "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled"); | 800 | "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled"); |
836 | 801 | ||
837 | MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off"); | ||
838 | |||
839 | MainConsole.Instance.OutputFormat( | 802 | MainConsole.Instance.OutputFormat( |
840 | "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel); | 803 | "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel); |
841 | } | 804 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs new file mode 100644 index 0000000..8ed2cf1 --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using OpenSim.Framework; | ||
30 | using Nini.Config; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
34 | { | ||
35 | public sealed class LLUDPZeroEncoder | ||
36 | { | ||
37 | private byte[] m_tmp = new byte[16]; | ||
38 | private byte[] m_dest; | ||
39 | private int zerocount; | ||
40 | private int pos; | ||
41 | |||
42 | public LLUDPZeroEncoder() | ||
43 | { | ||
44 | } | ||
45 | |||
46 | public LLUDPZeroEncoder(byte[] data) | ||
47 | { | ||
48 | m_dest = data; | ||
49 | zerocount = 0; | ||
50 | } | ||
51 | |||
52 | public byte[] Data | ||
53 | { | ||
54 | get | ||
55 | { | ||
56 | return m_dest; | ||
57 | } | ||
58 | set | ||
59 | { | ||
60 | m_dest = value; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | public int ZeroCount | ||
65 | { | ||
66 | get | ||
67 | { | ||
68 | return zerocount; | ||
69 | } | ||
70 | set | ||
71 | { | ||
72 | zerocount = value; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public int Position | ||
77 | { | ||
78 | get | ||
79 | { | ||
80 | return pos; | ||
81 | } | ||
82 | set | ||
83 | { | ||
84 | pos = value; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | public unsafe void AddZeros(int len) | ||
89 | { | ||
90 | zerocount += len; | ||
91 | while (zerocount > 255) | ||
92 | { | ||
93 | m_dest[pos++] = 0x00; | ||
94 | m_dest[pos++] = 0xff; | ||
95 | zerocount -= 256; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | public unsafe int Finish() | ||
100 | { | ||
101 | if(zerocount > 0) | ||
102 | { | ||
103 | m_dest[pos++] = 0x00; | ||
104 | m_dest[pos++] = (byte)zerocount; | ||
105 | } | ||
106 | return pos; | ||
107 | } | ||
108 | |||
109 | public unsafe void AddBytes(byte[] src, int srclen) | ||
110 | { | ||
111 | for (int i = 0; i < srclen; ++i) | ||
112 | { | ||
113 | if (src[i] == 0x00) | ||
114 | { | ||
115 | zerocount++; | ||
116 | if (zerocount == 0) | ||
117 | { | ||
118 | m_dest[pos++] = 0x00; | ||
119 | m_dest[pos++] = 0xff; | ||
120 | zerocount++; | ||
121 | } | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | if (zerocount != 0) | ||
126 | { | ||
127 | m_dest[pos++] = 0x00; | ||
128 | m_dest[pos++] = (byte)zerocount; | ||
129 | zerocount = 0; | ||
130 | } | ||
131 | |||
132 | m_dest[pos++] = src[i]; | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | public unsafe void AddByte(byte v) | ||
138 | { | ||
139 | if (v == 0x00) | ||
140 | { | ||
141 | zerocount++; | ||
142 | if (zerocount == 0) | ||
143 | { | ||
144 | m_dest[pos++] = 0x00; | ||
145 | m_dest[pos++] = 0xff; | ||
146 | zerocount++; | ||
147 | } | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | if (zerocount != 0) | ||
152 | { | ||
153 | m_dest[pos++] = 0x00; | ||
154 | m_dest[pos++] = (byte)zerocount; | ||
155 | zerocount = 0; | ||
156 | } | ||
157 | |||
158 | m_dest[pos++] = v; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | public void AddInt16(short v) | ||
163 | { | ||
164 | if (v == 0) | ||
165 | AddZeros(2); | ||
166 | else | ||
167 | { | ||
168 | Utils.Int16ToBytes(v, m_tmp, 0); | ||
169 | AddBytes(m_tmp, 2); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | public void AddUInt16(ushort v) | ||
174 | { | ||
175 | if (v == 0) | ||
176 | AddZeros(2); | ||
177 | else | ||
178 | { | ||
179 | Utils.UInt16ToBytes(v, m_tmp, 0); | ||
180 | AddBytes(m_tmp, 2); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | public void AddInt(int v) | ||
185 | { | ||
186 | if (v == 0) | ||
187 | AddZeros(4); | ||
188 | else | ||
189 | { | ||
190 | Utils.IntToBytesSafepos(v, m_tmp, 0); | ||
191 | AddBytes(m_tmp, 4); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | public unsafe void AddUInt(uint v) | ||
196 | { | ||
197 | if (v == 0) | ||
198 | AddZeros(4); | ||
199 | else | ||
200 | { | ||
201 | Utils.UIntToBytesSafepos(v, m_tmp, 0); | ||
202 | AddBytes(m_tmp, 4); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | public void AddFloatToUInt16(float v, float range) | ||
207 | { | ||
208 | Utils.FloatToUInt16Bytes(v, range, m_tmp, 0); | ||
209 | AddBytes(m_tmp, 2); | ||
210 | } | ||
211 | |||
212 | public void AddFloat(float v) | ||
213 | { | ||
214 | if (v == 0f) | ||
215 | AddZeros(4); | ||
216 | else | ||
217 | { | ||
218 | Utils.FloatToBytesSafepos(v, m_tmp, 0); | ||
219 | AddBytes(m_tmp, 4); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | public void AddInt64(long v) | ||
224 | { | ||
225 | if (v == 0) | ||
226 | AddZeros(8); | ||
227 | else | ||
228 | { | ||
229 | Utils.Int64ToBytesSafepos(v, m_tmp, 0); | ||
230 | AddBytes(m_tmp, 8); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | public void AddUInt64(ulong v) | ||
235 | { | ||
236 | if (v == 0) | ||
237 | AddZeros(8); | ||
238 | else | ||
239 | { | ||
240 | Utils.UInt64ToBytesSafepos(v, m_tmp, 0); | ||
241 | AddBytes(m_tmp, 8); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | public void AddVector3(Vector3 v) | ||
246 | { | ||
247 | if (v == Vector3.Zero) | ||
248 | AddZeros(12); | ||
249 | else | ||
250 | { | ||
251 | v.ToBytes(m_tmp, 0); | ||
252 | AddBytes(m_tmp, 12); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | public void AddVector4(Vector4 v) | ||
257 | { | ||
258 | if (v == Vector4.Zero) | ||
259 | AddZeros(16); | ||
260 | else | ||
261 | { | ||
262 | v.ToBytes(m_tmp, 0); | ||
263 | AddBytes(m_tmp, 16); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | public void AddNormQuat(Quaternion v) | ||
268 | { | ||
269 | v.ToBytes(m_tmp, 0); | ||
270 | AddBytes(m_tmp, 12); | ||
271 | } | ||
272 | |||
273 | public void AddUUID(UUID v) | ||
274 | { | ||
275 | v.ToBytes(m_tmp, 0); | ||
276 | AddBytes(m_tmp, 16); | ||
277 | } | ||
278 | } | ||
279 | } | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index f362b06..49aca3c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Concurrent; | ||
29 | using System.Net; | 30 | using System.Net; |
30 | using System.Net.Sockets; | 31 | using System.Net.Sockets; |
31 | using System.Threading; | 32 | using System.Threading; |
@@ -57,15 +58,9 @@ namespace OpenMetaverse | |||
57 | /// <summary>UDP socket, used in either client or server mode</summary> | 58 | /// <summary>UDP socket, used in either client or server mode</summary> |
58 | private Socket m_udpSocket; | 59 | private Socket m_udpSocket; |
59 | 60 | ||
60 | /// <summary> | 61 | public static Object m_udpBuffersPoolLock = new Object(); |
61 | /// Are we to use object pool(s) to reduce memory churn when receiving data? | 62 | public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000]; |
62 | /// </summary> | 63 | public static int m_udpBuffersPoolPtr = -1; |
63 | public bool UsePools { get; protected set; } | ||
64 | |||
65 | /// <summary> | ||
66 | /// Pool to use for handling data. May be null if UsePools = false; | ||
67 | /// </summary> | ||
68 | protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; } | ||
69 | 64 | ||
70 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> | 65 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> |
71 | public bool IsRunningInbound { get; private set; } | 66 | public bool IsRunningInbound { get; private set; } |
@@ -186,6 +181,37 @@ namespace OpenMetaverse | |||
186 | if(m_udpSocket !=null) | 181 | if(m_udpSocket !=null) |
187 | try { m_udpSocket.Close(); } catch { } | 182 | try { m_udpSocket.Close(); } catch { } |
188 | } | 183 | } |
184 | |||
185 | public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint) | ||
186 | { | ||
187 | lock (m_udpBuffersPoolLock) | ||
188 | { | ||
189 | if (m_udpBuffersPoolPtr >= 0) | ||
190 | { | ||
191 | UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; | ||
192 | m_udpBuffersPool[m_udpBuffersPoolPtr] = null; | ||
193 | m_udpBuffersPoolPtr--; | ||
194 | buf.RemoteEndPoint = remoteEndpoint; | ||
195 | return buf; | ||
196 | } | ||
197 | } | ||
198 | return new UDPPacketBuffer(remoteEndpoint); | ||
199 | } | ||
200 | |||
201 | public void FreeUDPBuffer(UDPPacketBuffer buf) | ||
202 | { | ||
203 | lock (m_udpBuffersPoolLock) | ||
204 | { | ||
205 | if (m_udpBuffersPoolPtr < 999) | ||
206 | { | ||
207 | buf.RemoteEndPoint = null; | ||
208 | buf.DataLength = 0; | ||
209 | m_udpBuffersPoolPtr++; | ||
210 | m_udpBuffersPool[m_udpBuffersPoolPtr] = buf; | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
189 | /// <summary> | 215 | /// <summary> |
190 | /// Start inbound UDP packet handling. | 216 | /// Start inbound UDP packet handling. |
191 | /// </summary> | 217 | /// </summary> |
@@ -202,6 +228,7 @@ namespace OpenMetaverse | |||
202 | /// manner (not throwing an exception when the remote side resets the | 228 | /// manner (not throwing an exception when the remote side resets the |
203 | /// connection). This call is ignored on Mono where the flag is not | 229 | /// connection). This call is ignored on Mono where the flag is not |
204 | /// necessary</remarks> | 230 | /// necessary</remarks> |
231 | |||
205 | public virtual void StartInbound(int recvBufferSize) | 232 | public virtual void StartInbound(int recvBufferSize) |
206 | { | 233 | { |
207 | if (!IsRunningInbound) | 234 | if (!IsRunningInbound) |
@@ -306,102 +333,56 @@ namespace OpenMetaverse | |||
306 | IsRunningOutbound = false; | 333 | IsRunningOutbound = false; |
307 | } | 334 | } |
308 | 335 | ||
309 | public virtual bool EnablePools() | 336 | private void AsyncBeginReceive() |
310 | { | 337 | { |
311 | if (!UsePools) | 338 | if (!IsRunningInbound) |
312 | { | 339 | return; |
313 | Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
314 | |||
315 | UsePools = true; | ||
316 | |||
317 | return true; | ||
318 | } | ||
319 | |||
320 | return false; | ||
321 | } | ||
322 | 340 | ||
323 | public virtual bool DisablePools() | 341 | UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least |
324 | { | 342 | try |
325 | if (UsePools) | ||
326 | { | 343 | { |
327 | UsePools = false; | 344 | // kick off an async read |
328 | 345 | m_udpSocket.BeginReceiveFrom( | |
329 | // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. | 346 | buf.Data, |
330 | 347 | 0, | |
331 | return true; | 348 | buf.Data.Length, |
349 | SocketFlags.None, | ||
350 | ref buf.RemoteEndPoint, | ||
351 | AsyncEndReceive, | ||
352 | buf); | ||
332 | } | 353 | } |
333 | 354 | catch (SocketException e) | |
334 | return false; | ||
335 | } | ||
336 | |||
337 | private void AsyncBeginReceive() | ||
338 | { | ||
339 | UDPPacketBuffer buf; | ||
340 | |||
341 | // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other | ||
342 | // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. | ||
343 | // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. | ||
344 | // if (UsePools) | ||
345 | // buf = Pool.GetObject(); | ||
346 | // else | ||
347 | buf = new UDPPacketBuffer(); | ||
348 | |||
349 | if (IsRunningInbound) | ||
350 | { | 355 | { |
351 | try | 356 | if (e.SocketErrorCode == SocketError.ConnectionReset) |
352 | { | ||
353 | // kick off an async read | ||
354 | m_udpSocket.BeginReceiveFrom( | ||
355 | //wrappedBuffer.Instance.Data, | ||
356 | buf.Data, | ||
357 | 0, | ||
358 | UDPPacketBuffer.BUFFER_SIZE, | ||
359 | SocketFlags.None, | ||
360 | ref buf.RemoteEndPoint, | ||
361 | AsyncEndReceive, | ||
362 | //wrappedBuffer); | ||
363 | buf); | ||
364 | } | ||
365 | catch (SocketException e) | ||
366 | { | 357 | { |
367 | if (e.SocketErrorCode == SocketError.ConnectionReset) | 358 | m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); |
359 | bool salvaged = false; | ||
360 | while (!salvaged) | ||
368 | { | 361 | { |
369 | m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); | 362 | try |
370 | bool salvaged = false; | ||
371 | while (!salvaged) | ||
372 | { | 363 | { |
373 | try | 364 | m_udpSocket.BeginReceiveFrom( |
374 | { | 365 | buf.Data, |
375 | m_udpSocket.BeginReceiveFrom( | 366 | 0, |
376 | //wrappedBuffer.Instance.Data, | 367 | buf.Data.Length, |
377 | buf.Data, | 368 | SocketFlags.None, |
378 | 0, | 369 | ref buf.RemoteEndPoint, |
379 | UDPPacketBuffer.BUFFER_SIZE, | 370 | AsyncEndReceive, |
380 | SocketFlags.None, | 371 | buf); |
381 | ref buf.RemoteEndPoint, | 372 | salvaged = true; |
382 | AsyncEndReceive, | ||
383 | //wrappedBuffer); | ||
384 | buf); | ||
385 | salvaged = true; | ||
386 | } | ||
387 | catch (SocketException) { } | ||
388 | catch (ObjectDisposedException) { return; } | ||
389 | } | 373 | } |
390 | 374 | catch (SocketException) { } | |
391 | m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); | 375 | catch (ObjectDisposedException) { return; } |
392 | } | 376 | } |
393 | } | 377 | |
394 | catch (ObjectDisposedException e) | 378 | m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); |
395 | { | ||
396 | m_log.Error( | ||
397 | string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); | ||
398 | } | ||
399 | catch (Exception e) | ||
400 | { | ||
401 | m_log.Error( | ||
402 | string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); | ||
403 | } | 379 | } |
404 | } | 380 | } |
381 | catch (Exception e) | ||
382 | { | ||
383 | m_log.Error( | ||
384 | string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); | ||
385 | } | ||
405 | } | 386 | } |
406 | 387 | ||
407 | private void AsyncEndReceive(IAsyncResult iar) | 388 | private void AsyncEndReceive(IAsyncResult iar) |
@@ -453,11 +434,6 @@ namespace OpenMetaverse | |||
453 | UdpReceives, se.ErrorCode), | 434 | UdpReceives, se.ErrorCode), |
454 | se); | 435 | se); |
455 | } | 436 | } |
456 | catch (ObjectDisposedException e) | ||
457 | { | ||
458 | m_log.Error( | ||
459 | string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e); | ||
460 | } | ||
461 | catch (Exception e) | 437 | catch (Exception e) |
462 | { | 438 | { |
463 | m_log.Error( | 439 | m_log.Error( |
@@ -465,14 +441,12 @@ namespace OpenMetaverse | |||
465 | } | 441 | } |
466 | finally | 442 | finally |
467 | { | 443 | { |
468 | // if (UsePools) | ||
469 | // Pool.ReturnObject(buffer); | ||
470 | |||
471 | AsyncBeginReceive(); | 444 | AsyncBeginReceive(); |
472 | } | 445 | } |
473 | } | 446 | } |
474 | } | 447 | } |
475 | 448 | ||
449 | /* not in use | ||
476 | public void AsyncBeginSend(UDPPacketBuffer buf) | 450 | public void AsyncBeginSend(UDPPacketBuffer buf) |
477 | { | 451 | { |
478 | // if (IsRunningOutbound) | 452 | // if (IsRunningOutbound) |
@@ -511,9 +485,11 @@ namespace OpenMetaverse | |||
511 | catch (SocketException) { } | 485 | catch (SocketException) { } |
512 | catch (ObjectDisposedException) { } | 486 | catch (ObjectDisposedException) { } |
513 | } | 487 | } |
514 | 488 | */ | |
515 | public void SyncSend(UDPPacketBuffer buf) | 489 | public void SyncSend(UDPPacketBuffer buf) |
516 | { | 490 | { |
491 | if(buf.RemoteEndPoint == null) | ||
492 | return; // already expired | ||
517 | try | 493 | try |
518 | { | 494 | { |
519 | m_udpSocket.SendTo( | 495 | m_udpSocket.SendTo( |
@@ -527,7 +503,7 @@ namespace OpenMetaverse | |||
527 | } | 503 | } |
528 | catch (SocketException e) | 504 | catch (SocketException e) |
529 | { | 505 | { |
530 | m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message); | 506 | m_log.WarnFormat("[UDPBASE]: sync send SocketException {0} {1}", buf.RemoteEndPoint, e.Message); |
531 | } | 507 | } |
532 | catch (ObjectDisposedException) { } | 508 | catch (ObjectDisposedException) { } |
533 | } | 509 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs index f8ec97a..3277638 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs | |||
@@ -66,9 +66,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
66 | /// </summary> | 66 | /// </summary> |
67 | public Int64 MinimumAdaptiveThrottleRate; | 67 | public Int64 MinimumAdaptiveThrottleRate; |
68 | 68 | ||
69 | /// <summary>Amount of the texture throttle to steal for the task throttle</summary> | ||
70 | public double CannibalizeTextureRate; | ||
71 | |||
72 | public int ClientMaxRate; | 69 | public int ClientMaxRate; |
73 | public float BrustTime; | 70 | public float BrustTime; |
74 | 71 | ||
@@ -104,12 +101,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
104 | // AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false); | 101 | // AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false); |
105 | AdaptiveThrottlesEnabled = false; | 102 | AdaptiveThrottlesEnabled = false; |
106 | MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000); | 103 | MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000); |
107 | |||
108 | // http textures do use udp bandwidth setting | ||
109 | // CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f); | ||
110 | // CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9); | ||
111 | CannibalizeTextureRate = 0f; | ||
112 | |||
113 | } | 104 | } |
114 | catch (Exception) { } | 105 | catch (Exception) { } |
115 | } | 106 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs index 76f4c6f..1f978e1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs | |||
@@ -189,8 +189,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
189 | // Process all the pending adds | 189 | // Process all the pending adds |
190 | OutgoingPacket pendingAdd; | 190 | OutgoingPacket pendingAdd; |
191 | while (m_pendingAdds.TryDequeue(out pendingAdd)) | 191 | while (m_pendingAdds.TryDequeue(out pendingAdd)) |
192 | { | ||
192 | if (pendingAdd != null) | 193 | if (pendingAdd != null) |
193 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | 194 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; |
195 | } | ||
194 | 196 | ||
195 | // Process all the pending removes, including updating statistics and round-trip times | 197 | // Process all the pending removes, including updating statistics and round-trip times |
196 | PendingAck pendingAcknowledgement; | 198 | PendingAck pendingAcknowledgement; |
@@ -204,13 +206,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
204 | { | 206 | { |
205 | m_packets.Remove(pendingAcknowledgement.SequenceNumber); | 207 | m_packets.Remove(pendingAcknowledgement.SequenceNumber); |
206 | 208 | ||
209 | // Update stats | ||
210 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
211 | |||
212 | ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); | ||
213 | ackedPacket.Buffer = null; | ||
214 | |||
207 | // As with other network applications, assume that an acknowledged packet is an | 215 | // As with other network applications, assume that an acknowledged packet is an |
208 | // indication that the network can handle a little more load, speed up the transmission | 216 | // indication that the network can handle a little more load, speed up the transmission |
209 | ackedPacket.Client.FlowThrottle.AcknowledgePackets(1); | 217 | ackedPacket.Client.FlowThrottle.AcknowledgePackets(1); |
210 | 218 | ||
211 | // Update stats | ||
212 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
213 | |||
214 | if (!pendingAcknowledgement.FromResend) | 219 | if (!pendingAcknowledgement.FromResend) |
215 | { | 220 | { |
216 | // Calculate the round-trip time for this packet and its ACK | 221 | // Calculate the round-trip time for this packet and its ACK |
@@ -244,6 +249,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
244 | 249 | ||
245 | // Update stats | 250 | // Update stats |
246 | Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); | 251 | Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); |
252 | |||
253 | removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); | ||
254 | removedPacket.Buffer = null; | ||
247 | } | 255 | } |
248 | } | 256 | } |
249 | } | 257 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d36d770..5205576 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -953,13 +953,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
953 | return; | 953 | return; |
954 | } | 954 | } |
955 | 955 | ||
956 | // Saving attachments for NPCs messes them up for the real owner! | 956 | if(sp.IsNPC) |
957 | INPCModule module = m_scene.RequestModuleInterface<INPCModule>(); | 957 | return; |
958 | if (module != null) | ||
959 | { | ||
960 | if (module.IsNPC(sp.UUID, m_scene)) | ||
961 | return; | ||
962 | } | ||
963 | 958 | ||
964 | if (grp.HasGroupChanged) | 959 | if (grp.HasGroupChanged) |
965 | { | 960 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 4e1958a..10bc6aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs | |||
@@ -77,7 +77,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
77 | } | 77 | } |
78 | 78 | ||
79 | scene.EventManager.OnAvatarKilled += KillAvatar; | 79 | scene.EventManager.OnAvatarKilled += KillAvatar; |
80 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | ||
81 | } | 80 | } |
82 | 81 | ||
83 | public void RemoveRegion(Scene scene) | 82 | public void RemoveRegion(Scene scene) |
@@ -86,7 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
86 | m_scenel.Remove(scene.RegionInfo.RegionHandle); | 85 | m_scenel.Remove(scene.RegionInfo.RegionHandle); |
87 | 86 | ||
88 | scene.EventManager.OnAvatarKilled -= KillAvatar; | 87 | scene.EventManager.OnAvatarKilled -= KillAvatar; |
89 | scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; | ||
90 | } | 88 | } |
91 | 89 | ||
92 | public void RegionLoaded(Scene scene) | 90 | public void RegionLoaded(Scene scene) |
@@ -177,31 +175,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
177 | deadAvatar.setHealthWithUpdate(100.0f); | 175 | deadAvatar.setHealthWithUpdate(100.0f); |
178 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); | 176 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); |
179 | } | 177 | } |
180 | |||
181 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) | ||
182 | { | ||
183 | try | ||
184 | { | ||
185 | ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | ||
186 | if (obj == null) | ||
187 | return; | ||
188 | if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 | ||
189 | || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) | ||
190 | { | ||
191 | avatar.Invulnerable = false; | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | avatar.Invulnerable = true; | ||
196 | if (avatar.Health < 100.0f) | ||
197 | { | ||
198 | avatar.setHealthWithUpdate(100.0f); | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | catch (Exception) | ||
203 | { | ||
204 | } | ||
205 | } | ||
206 | } | 178 | } |
207 | } | 179 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d6c65a1..69c1e4e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -526,16 +526,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
526 | item.AssetType = (int)AssetType.Object; | 526 | item.AssetType = (int)AssetType.Object; |
527 | item.AssetID = asset.FullID; | 527 | item.AssetID = asset.FullID; |
528 | 528 | ||
529 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 529 | if (action == DeRezAction.SaveToExistingUserInventoryItem) |
530 | { | 530 | { |
531 | m_Scene.InventoryService.UpdateItem(item); | 531 | m_Scene.InventoryService.UpdateItem(item); |
532 | } | 532 | } |
533 | else | 533 | else |
534 | { | 534 | { |
535 | AddPermissions(item, objlist[0], objlist, remoteClient); | 535 | bool isowner = remoteClient != null && item.Owner == remoteClient.AgentId; |
536 | if(action == DeRezAction.Return) | ||
537 | AddPermissions(item, objlist[0], objlist, null); | ||
538 | else if(action == DeRezAction.Delete && !isowner) | ||
539 | AddPermissions(item, objlist[0], objlist, null); | ||
540 | else | ||
541 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
542 | |||
536 | m_Scene.AddInventoryItem(item); | 543 | m_Scene.AddInventoryItem(item); |
537 | 544 | ||
538 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 545 | if (isowner) |
539 | { | 546 | { |
540 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 547 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
541 | } | 548 | } |
@@ -1010,7 +1017,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1010 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); | 1017 | group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); |
1011 | rootPart.ParentGroup.ResumeScripts(); | 1018 | rootPart.ParentGroup.ResumeScripts(); |
1012 | 1019 | ||
1013 | group.ScheduleGroupForFullUpdate(); | 1020 | group.ScheduleGroupForFullAnimUpdate(); |
1014 | } | 1021 | } |
1015 | else | 1022 | else |
1016 | m_Scene.AddNewSceneObject(group, true, false); | 1023 | m_Scene.AddNewSceneObject(group, true, false); |
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index c3f6d6b..83d91c4 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Collections.Concurrent; | ||
30 | using System.IO; | 31 | using System.IO; |
31 | using System.Net; | 32 | using System.Net; |
32 | using System.Net.Mail; | 33 | using System.Net.Mail; |
@@ -94,18 +95,31 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
94 | { | 95 | { |
95 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 96 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
96 | 97 | ||
97 | private object HttpListLock = new object(); | 98 | private object m_httpListLock = new object(); |
98 | private int httpTimeout = 30000; | 99 | private int m_httpTimeout = 30000; |
99 | private string m_name = "HttpScriptRequests"; | 100 | private string m_name = "HttpScriptRequests"; |
100 | 101 | ||
101 | private OutboundUrlFilter m_outboundUrlFilter; | 102 | private OutboundUrlFilter m_outboundUrlFilter; |
102 | private string m_proxyurl = ""; | 103 | private string m_proxyurl = ""; |
103 | private string m_proxyexcepts = ""; | 104 | private string m_proxyexcepts = ""; |
104 | 105 | ||
106 | private float m_primPerSec = 1.0f; | ||
107 | private float m_primBurst = 3.0f; | ||
108 | private float m_primOwnerPerSec = 25.0f; | ||
109 | private float m_primOwnerBurst = 5.0f; | ||
110 | |||
111 | private struct ThrottleData | ||
112 | { | ||
113 | public double lastTime; | ||
114 | public float count; | ||
115 | } | ||
116 | |||
105 | // <request id, HttpRequestClass> | 117 | // <request id, HttpRequestClass> |
106 | private Dictionary<UUID, HttpRequestClass> m_pendingRequests; | 118 | private Dictionary<UUID, HttpRequestClass> m_pendingRequests; |
107 | private Scene m_scene; | 119 | private ConcurrentQueue<HttpRequestClass> m_CompletedRequests; |
108 | // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); | 120 | private ConcurrentDictionary<uint, ThrottleData> m_RequestsThrottle; |
121 | private ConcurrentDictionary<UUID, ThrottleData> m_OwnerRequestsThrottle; | ||
122 | |||
109 | public static SmartThreadPool ThreadPool = null; | 123 | public static SmartThreadPool ThreadPool = null; |
110 | 124 | ||
111 | public HttpRequestModule() | 125 | public HttpRequestModule() |
@@ -119,10 +133,77 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
119 | return UUID.Zero; | 133 | return UUID.Zero; |
120 | } | 134 | } |
121 | 135 | ||
136 | public bool CheckThrottle(uint localID, UUID ownerID) | ||
137 | { | ||
138 | ThrottleData th; | ||
139 | double now = Util.GetTimeStamp(); | ||
140 | bool ret; | ||
141 | |||
142 | if (m_RequestsThrottle.TryGetValue(localID, out th)) | ||
143 | { | ||
144 | double delta = now - th.lastTime; | ||
145 | th.lastTime = now; | ||
146 | |||
147 | float add = (float)(m_primPerSec * delta); | ||
148 | th.count += add; | ||
149 | if (th.count > m_primBurst) | ||
150 | th.count = m_primBurst; | ||
151 | |||
152 | ret = th.count > 0; | ||
153 | if (ret) | ||
154 | th.count--; | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | th = new ThrottleData() | ||
159 | { | ||
160 | lastTime = now, | ||
161 | count = m_primBurst - 1 | ||
162 | }; | ||
163 | ret = true; | ||
164 | } | ||
165 | m_RequestsThrottle[localID] = th; | ||
166 | |||
167 | if(!ret) | ||
168 | return false; | ||
169 | |||
170 | if (m_OwnerRequestsThrottle.TryGetValue(ownerID, out th)) | ||
171 | { | ||
172 | double delta = now - th.lastTime; | ||
173 | th.lastTime = now; | ||
174 | |||
175 | float add = (float)(m_primOwnerPerSec * delta); | ||
176 | th.count += add; | ||
177 | if (th.count > m_primOwnerBurst) | ||
178 | th.count = m_primOwnerBurst; | ||
179 | |||
180 | ret = th.count > 0; | ||
181 | if (ret) | ||
182 | th.count--; | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | th = new ThrottleData() | ||
187 | { | ||
188 | lastTime = now, | ||
189 | count = m_primOwnerBurst - 1 | ||
190 | }; | ||
191 | } | ||
192 | m_OwnerRequestsThrottle[ownerID] = th; | ||
193 | |||
194 | return ret; | ||
195 | } | ||
196 | |||
122 | public UUID StartHttpRequest( | 197 | public UUID StartHttpRequest( |
123 | uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body, | 198 | uint localID, UUID itemID, string url, List<string> parameters, Dictionary<string, string> headers, string body, |
124 | out HttpInitialRequestStatus status) | 199 | out HttpInitialRequestStatus status) |
125 | { | 200 | { |
201 | if (!CheckAllowed(new Uri(url))) | ||
202 | { | ||
203 | status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; | ||
204 | return UUID.Zero; | ||
205 | } | ||
206 | |||
126 | UUID reqID = UUID.Random(); | 207 | UUID reqID = UUID.Random(); |
127 | HttpRequestClass htc = new HttpRequestClass(); | 208 | HttpRequestClass htc = new HttpRequestClass(); |
128 | 209 | ||
@@ -207,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
207 | htc.ItemID = itemID; | 288 | htc.ItemID = itemID; |
208 | htc.Url = url; | 289 | htc.Url = url; |
209 | htc.ReqID = reqID; | 290 | htc.ReqID = reqID; |
210 | htc.HttpTimeout = httpTimeout; | 291 | htc.HttpTimeout = m_httpTimeout; |
211 | htc.OutboundBody = body; | 292 | htc.OutboundBody = body; |
212 | htc.ResponseHeaders = headers; | 293 | htc.ResponseHeaders = headers; |
213 | htc.proxyurl = m_proxyurl; | 294 | htc.proxyurl = m_proxyurl; |
@@ -216,16 +297,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
216 | // Same number as default HttpWebRequest.MaximumAutomaticRedirections | 297 | // Same number as default HttpWebRequest.MaximumAutomaticRedirections |
217 | htc.MaxRedirects = 50; | 298 | htc.MaxRedirects = 50; |
218 | 299 | ||
219 | if (StartHttpRequest(htc)) | 300 | lock (m_httpListLock) |
220 | { | 301 | m_pendingRequests.Add(reqID, htc); |
221 | status = HttpInitialRequestStatus.OK; | 302 | |
222 | return htc.ReqID; | 303 | htc.Process(); |
223 | } | 304 | status = HttpInitialRequestStatus.OK; |
224 | else | 305 | return reqID; |
225 | { | ||
226 | status = HttpInitialRequestStatus.DISALLOWED_BY_FILTER; | ||
227 | return UUID.Zero; | ||
228 | } | ||
229 | } | 306 | } |
230 | 307 | ||
231 | /// <summary> | 308 | /// <summary> |
@@ -237,34 +314,21 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
237 | return m_outboundUrlFilter.CheckAllowed(url); | 314 | return m_outboundUrlFilter.CheckAllowed(url); |
238 | } | 315 | } |
239 | 316 | ||
240 | public bool StartHttpRequest(HttpRequestClass req) | ||
241 | { | ||
242 | if (!CheckAllowed(new Uri(req.Url))) | ||
243 | return false; | ||
244 | |||
245 | lock (HttpListLock) | ||
246 | { | ||
247 | m_pendingRequests.Add(req.ReqID, req); | ||
248 | } | ||
249 | |||
250 | req.Process(); | ||
251 | |||
252 | return true; | ||
253 | } | ||
254 | |||
255 | public void StopHttpRequest(uint m_localID, UUID m_itemID) | 317 | public void StopHttpRequest(uint m_localID, UUID m_itemID) |
256 | { | 318 | { |
257 | if (m_pendingRequests != null) | 319 | List<UUID> toremove = new List<UUID>(); |
320 | lock (m_httpListLock) | ||
258 | { | 321 | { |
259 | lock (HttpListLock) | 322 | foreach (HttpRequestClass tmpReq in m_pendingRequests.Values) |
260 | { | 323 | { |
261 | HttpRequestClass tmpReq; | 324 | if(tmpReq.ItemID == m_itemID) |
262 | if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq)) | ||
263 | { | 325 | { |
264 | tmpReq.Stop(); | 326 | tmpReq.Stop(); |
265 | m_pendingRequests.Remove(m_itemID); | 327 | toremove.Add(tmpReq.ReqID); |
266 | } | 328 | } |
267 | } | 329 | } |
330 | foreach(UUID id in toremove) | ||
331 | m_pendingRequests.Remove(id); | ||
268 | } | 332 | } |
269 | } | 333 | } |
270 | 334 | ||
@@ -276,37 +340,35 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
276 | * finished. I thought about setting up a queue for this, but | 340 | * finished. I thought about setting up a queue for this, but |
277 | * it will need some refactoring and this works 'enough' right now | 341 | * it will need some refactoring and this works 'enough' right now |
278 | */ | 342 | */ |
343 | public void GotCompletedRequest(HttpRequestClass req) | ||
344 | { | ||
345 | lock (m_httpListLock) | ||
346 | { | ||
347 | if (req.Removed) | ||
348 | return; | ||
349 | m_pendingRequests.Remove(req.ReqID); | ||
350 | m_CompletedRequests.Enqueue(req); | ||
351 | } | ||
352 | } | ||
279 | 353 | ||
280 | public IServiceRequest GetNextCompletedRequest() | 354 | public IServiceRequest GetNextCompletedRequest() |
281 | { | 355 | { |
282 | lock (HttpListLock) | 356 | HttpRequestClass req; |
283 | { | 357 | if(m_CompletedRequests.TryDequeue(out req)) |
284 | foreach (UUID luid in m_pendingRequests.Keys) | 358 | return req; |
285 | { | ||
286 | HttpRequestClass tmpReq; | ||
287 | 359 | ||
288 | if (m_pendingRequests.TryGetValue(luid, out tmpReq)) | ||
289 | { | ||
290 | if (tmpReq.Finished) | ||
291 | { | ||
292 | return tmpReq; | ||
293 | } | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | return null; | 360 | return null; |
298 | } | 361 | } |
299 | 362 | ||
300 | public void RemoveCompletedRequest(UUID id) | 363 | public void RemoveCompletedRequest(UUID reqId) |
301 | { | 364 | { |
302 | lock (HttpListLock) | 365 | lock (m_httpListLock) |
303 | { | 366 | { |
304 | HttpRequestClass tmpReq; | 367 | HttpRequestClass tmpReq; |
305 | if (m_pendingRequests.TryGetValue(id, out tmpReq)) | 368 | if (m_pendingRequests.TryGetValue(reqId, out tmpReq)) |
306 | { | 369 | { |
307 | tmpReq.Stop(); | 370 | tmpReq.Stop(); |
308 | tmpReq = null; | 371 | m_pendingRequests.Remove(reqId); |
309 | m_pendingRequests.Remove(id); | ||
310 | } | 372 | } |
311 | } | 373 | } |
312 | } | 374 | } |
@@ -322,17 +384,28 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
322 | 384 | ||
323 | HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384); | 385 | HttpRequestClass.HttpBodyMaxLenMAX = config.Configs["Network"].GetInt("HttpBodyMaxLenMAX", 16384); |
324 | 386 | ||
325 | |||
326 | m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); | 387 | m_outboundUrlFilter = new OutboundUrlFilter("Script HTTP request module", config); |
327 | int maxThreads = 15; | ||
328 | 388 | ||
329 | IConfig httpConfig = config.Configs["HttpRequestModule"]; | 389 | int maxThreads = 8; |
390 | IConfig httpConfig = config.Configs["ScriptsHttpRequestModule"]; | ||
330 | if (httpConfig != null) | 391 | if (httpConfig != null) |
331 | { | 392 | { |
332 | maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); | 393 | maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); |
394 | m_primBurst = httpConfig.GetFloat("PrimRequestsBurst", m_primBurst); | ||
395 | m_primPerSec = httpConfig.GetFloat("PrimRequestsPerSec", m_primPerSec); | ||
396 | m_primOwnerBurst = httpConfig.GetFloat("PrimOwnerRequestsBurst", m_primOwnerBurst); | ||
397 | m_primOwnerPerSec = httpConfig.GetFloat("PrimOwnerRequestsPerSec", m_primOwnerPerSec); | ||
398 | m_httpTimeout = httpConfig.GetInt("RequestsTimeOut", m_httpTimeout); | ||
399 | if(m_httpTimeout > 60000) | ||
400 | m_httpTimeout = 60000; | ||
401 | else if(m_httpTimeout < 200) | ||
402 | m_httpTimeout = 200; | ||
333 | } | 403 | } |
334 | 404 | ||
335 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); | 405 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); |
406 | m_CompletedRequests = new ConcurrentQueue<HttpRequestClass>(); | ||
407 | m_RequestsThrottle = new ConcurrentDictionary<uint, ThrottleData>(); | ||
408 | m_OwnerRequestsThrottle = new ConcurrentDictionary<UUID, ThrottleData>(); | ||
336 | 409 | ||
337 | // First instance sets this up for all sims | 410 | // First instance sets this up for all sims |
338 | if (ThreadPool == null) | 411 | if (ThreadPool == null) |
@@ -352,16 +425,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
352 | 425 | ||
353 | public void AddRegion(Scene scene) | 426 | public void AddRegion(Scene scene) |
354 | { | 427 | { |
355 | m_scene = scene; | 428 | scene.RegisterModuleInterface<IHttpRequestModule>(this); |
356 | |||
357 | m_scene.RegisterModuleInterface<IHttpRequestModule>(this); | ||
358 | } | 429 | } |
359 | 430 | ||
360 | public void RemoveRegion(Scene scene) | 431 | public void RemoveRegion(Scene scene) |
361 | { | 432 | { |
362 | scene.UnregisterModuleInterface<IHttpRequestModule>(this); | 433 | scene.UnregisterModuleInterface<IHttpRequestModule>(this); |
363 | if (scene == m_scene) | ||
364 | m_scene = null; | ||
365 | } | 434 | } |
366 | 435 | ||
367 | public void PostInitialise() | 436 | public void PostInitialise() |
@@ -406,11 +475,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
406 | /// </summary> | 475 | /// </summary> |
407 | public HttpRequestModule RequestModule { get; set; } | 476 | public HttpRequestModule RequestModule { get; set; } |
408 | 477 | ||
409 | private bool _finished; | 478 | public bool Finished { get; private set;} |
410 | public bool Finished | 479 | public bool Removed{ get; set;} |
411 | { | ||
412 | get { return _finished; } | ||
413 | } | ||
414 | 480 | ||
415 | public static int HttpBodyMaxLenMAX = 16384; | 481 | public static int HttpBodyMaxLenMAX = 16384; |
416 | 482 | ||
@@ -427,19 +493,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
427 | public bool HttpPragmaNoCache = true; | 493 | public bool HttpPragmaNoCache = true; |
428 | 494 | ||
429 | // Request info | 495 | // Request info |
430 | private UUID _itemID; | 496 | public UUID ReqID { get; set; } |
431 | public UUID ItemID | 497 | public UUID ItemID { get; set;} |
432 | { | 498 | public uint LocalID { get; set;} |
433 | get { return _itemID; } | 499 | |
434 | set { _itemID = value; } | ||
435 | } | ||
436 | private uint _localID; | ||
437 | public uint LocalID | ||
438 | { | ||
439 | get { return _localID; } | ||
440 | set { _localID = value; } | ||
441 | } | ||
442 | public DateTime Next; | ||
443 | public string proxyurl; | 500 | public string proxyurl; |
444 | public string proxyexcepts; | 501 | public string proxyexcepts; |
445 | 502 | ||
@@ -454,12 +511,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
454 | public int MaxRedirects { get; set; } | 511 | public int MaxRedirects { get; set; } |
455 | 512 | ||
456 | public string OutboundBody; | 513 | public string OutboundBody; |
457 | private UUID _reqID; | 514 | |
458 | public UUID ReqID | ||
459 | { | ||
460 | get { return _reqID; } | ||
461 | set { _reqID = value; } | ||
462 | } | ||
463 | public HttpWebRequest Request; | 515 | public HttpWebRequest Request; |
464 | public string ResponseBody; | 516 | public string ResponseBody; |
465 | public List<string> ResponseMetadata; | 517 | public List<string> ResponseMetadata; |
@@ -469,10 +521,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
469 | 521 | ||
470 | public void Process() | 522 | public void Process() |
471 | { | 523 | { |
472 | _finished = false; | 524 | WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); |
473 | |||
474 | lock (HttpRequestModule.ThreadPool) | ||
475 | WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); | ||
476 | } | 525 | } |
477 | 526 | ||
478 | private object StpSendWrapper(object o) | 527 | private object StpSendWrapper(object o) |
@@ -521,6 +570,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
521 | 570 | ||
522 | public void SendRequest() | 571 | public void SendRequest() |
523 | { | 572 | { |
573 | if(Removed) | ||
574 | return; | ||
575 | |||
524 | HttpWebResponse response = null; | 576 | HttpWebResponse response = null; |
525 | Stream resStream = null; | 577 | Stream resStream = null; |
526 | byte[] buf = new byte[HttpBodyMaxLenMAX + 16]; | 578 | byte[] buf = new byte[HttpBodyMaxLenMAX + 16]; |
@@ -534,6 +586,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
534 | 586 | ||
535 | Request.AllowAutoRedirect = false; | 587 | Request.AllowAutoRedirect = false; |
536 | Request.KeepAlive = false; | 588 | Request.KeepAlive = false; |
589 | Request.Timeout = HttpTimeout; | ||
537 | 590 | ||
538 | //This works around some buggy HTTP Servers like Lighttpd | 591 | //This works around some buggy HTTP Servers like Lighttpd |
539 | Request.ServicePoint.Expect100Continue = false; | 592 | Request.ServicePoint.Expect100Continue = false; |
@@ -593,7 +646,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
593 | bstream.Write(data, 0, data.Length); | 646 | bstream.Write(data, 0, data.Length); |
594 | } | 647 | } |
595 | 648 | ||
596 | Request.Timeout = HttpTimeout; | ||
597 | try | 649 | try |
598 | { | 650 | { |
599 | // execute the request | 651 | // execute the request |
@@ -672,7 +724,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
672 | if (response != null) | 724 | if (response != null) |
673 | response.Close(); | 725 | response.Close(); |
674 | 726 | ||
675 | |||
676 | // We need to resubmit | 727 | // We need to resubmit |
677 | if ( | 728 | if ( |
678 | (Status == (int)HttpStatusCode.MovedPermanently | 729 | (Status == (int)HttpStatusCode.MovedPermanently |
@@ -684,7 +735,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
684 | { | 735 | { |
685 | Status = (int)OSHttpStatusCode.ClientErrorJoker; | 736 | Status = (int)OSHttpStatusCode.ClientErrorJoker; |
686 | ResponseBody = "Number of redirects exceeded max redirects"; | 737 | ResponseBody = "Number of redirects exceeded max redirects"; |
687 | _finished = true; | 738 | WorkItem = null; |
739 | RequestModule.GotCompletedRequest(this); | ||
688 | } | 740 | } |
689 | else | 741 | else |
690 | { | 742 | { |
@@ -694,13 +746,15 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
694 | { | 746 | { |
695 | Status = (int)OSHttpStatusCode.ClientErrorJoker; | 747 | Status = (int)OSHttpStatusCode.ClientErrorJoker; |
696 | ResponseBody = "HTTP redirect code but no location header"; | 748 | ResponseBody = "HTTP redirect code but no location header"; |
697 | _finished = true; | 749 | WorkItem = null; |
750 | RequestModule.GotCompletedRequest(this); | ||
698 | } | 751 | } |
699 | else if (!RequestModule.CheckAllowed(new Uri(location))) | 752 | else if (!RequestModule.CheckAllowed(new Uri(location))) |
700 | { | 753 | { |
701 | Status = (int)OSHttpStatusCode.ClientErrorJoker; | 754 | Status = (int)OSHttpStatusCode.ClientErrorJoker; |
702 | ResponseBody = "URL from HTTP redirect blocked: " + location; | 755 | ResponseBody = "URL from HTTP redirect blocked: " + location; |
703 | _finished = true; | 756 | WorkItem = null; |
757 | RequestModule.GotCompletedRequest(this); | ||
704 | } | 758 | } |
705 | else | 759 | else |
706 | { | 760 | { |
@@ -717,9 +771,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
717 | } | 771 | } |
718 | else | 772 | else |
719 | { | 773 | { |
720 | _finished = true; | 774 | WorkItem = null; |
721 | if (ResponseBody == null) | 775 | if (ResponseBody == null) |
722 | ResponseBody = String.Empty; | 776 | ResponseBody = String.Empty; |
777 | RequestModule.GotCompletedRequest(this); | ||
723 | } | 778 | } |
724 | } | 779 | } |
725 | } | 780 | } |
@@ -728,10 +783,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
728 | { | 783 | { |
729 | try | 784 | try |
730 | { | 785 | { |
786 | Removed = true; | ||
787 | if(WorkItem == null) | ||
788 | return; | ||
789 | |||
731 | if (!WorkItem.Cancel()) | 790 | if (!WorkItem.Cancel()) |
732 | { | ||
733 | WorkItem.Cancel(true); | 791 | WorkItem.Cancel(true); |
734 | } | ||
735 | } | 792 | } |
736 | catch (Exception) | 793 | catch (Exception) |
737 | { | 794 | { |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 2e801e3..ac28cee 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -1204,28 +1204,33 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1204 | } | 1204 | } |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) | 1207 | private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey, bool kick) |
1208 | { | 1208 | { |
1209 | if (prey == UUID.Zero) | ||
1210 | return; | ||
1211 | |||
1209 | EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest; | 1212 | EstateTeleportOneUserHomeRequest evOverride = OnEstateTeleportOneUserHomeRequest; |
1210 | if(evOverride != null) | 1213 | if(evOverride != null) |
1211 | { | 1214 | { |
1212 | evOverride(remover_client, invoice, senderID, prey); | 1215 | evOverride(remover_client, invoice, senderID, prey, kick); |
1213 | return; | 1216 | return; |
1214 | } | 1217 | } |
1215 | 1218 | ||
1216 | if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false)) | 1219 | if (!Scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false)) |
1217 | return; | 1220 | return; |
1218 | 1221 | ||
1219 | if (prey != UUID.Zero) | 1222 | ScenePresence s = Scene.GetScenePresence(prey); |
1223 | if (s != null && !s.IsDeleted && !s.IsInTransit) | ||
1220 | { | 1224 | { |
1221 | ScenePresence s = Scene.GetScenePresence(prey); | 1225 | if (kick) |
1222 | if (s != null && !s.IsDeleted && !s.IsInTransit) | ||
1223 | { | 1226 | { |
1224 | if (!Scene.TeleportClientHome(prey, s.ControllingClient)) | 1227 | s.ControllingClient.Kick("You have been kicked"); |
1225 | { | 1228 | Scene.CloseAgent(s.UUID, false); |
1226 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | 1229 | } |
1227 | Scene.CloseAgent(s.UUID, false); | 1230 | else if (!Scene.TeleportClientHome(prey, s.ControllingClient)) |
1228 | } | 1231 | { |
1232 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed "); | ||
1233 | Scene.CloseAgent(s.UUID, false); | ||
1229 | } | 1234 | } |
1230 | } | 1235 | } |
1231 | } | 1236 | } |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs index f4a174a..c8b9032 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateModule.cs | |||
@@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
204 | m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message); | 204 | m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message); |
205 | } | 205 | } |
206 | 206 | ||
207 | private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey) | 207 | private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey, bool kick) |
208 | { | 208 | { |
209 | if (prey == UUID.Zero) | 209 | if (prey == UUID.Zero) |
210 | return; | 210 | return; |
@@ -227,8 +227,20 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
227 | ScenePresence p = scene.GetScenePresence(prey); | 227 | ScenePresence p = scene.GetScenePresence(prey); |
228 | if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit) | 228 | if (p != null && !p.IsChildAgent && !p.IsDeleted && !p.IsInTransit) |
229 | { | 229 | { |
230 | p.ControllingClient.SendTeleportStart(16); | 230 | if (kick) |
231 | scene.TeleportClientHome(prey, client); | 231 | { |
232 | p.ControllingClient.Kick("You have been kicked out"); | ||
233 | s.CloseAgent(p.UUID, false); | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | p.ControllingClient.SendTeleportStart(16); | ||
238 | if (!s.TeleportClientHome(prey, client)) | ||
239 | { | ||
240 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed"); | ||
241 | s.CloseAgent(p.UUID, false); | ||
242 | } | ||
243 | } | ||
232 | return; | 244 | return; |
233 | } | 245 | } |
234 | } | 246 | } |
@@ -259,6 +271,11 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
259 | { | 271 | { |
260 | p.ControllingClient.SendTeleportStart(16); | 272 | p.ControllingClient.SendTeleportStart(16); |
261 | scene.TeleportClientHome(p.ControllingClient.AgentId, client); | 273 | scene.TeleportClientHome(p.ControllingClient.AgentId, client); |
274 | if (!s.TeleportClientHome(p.ControllingClient.AgentId, client)) | ||
275 | { | ||
276 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | ||
277 | s.CloseAgent(p.UUID, false); | ||
278 | } | ||
262 | } | 279 | } |
263 | }); | 280 | }); |
264 | } | 281 | } |
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs index 978c248..2c75844 100644 --- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs +++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs | |||
@@ -87,5 +87,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
87 | void StopHttpRequest(uint m_localID, UUID m_itemID); | 87 | void StopHttpRequest(uint m_localID, UUID m_itemID); |
88 | IServiceRequest GetNextCompletedRequest(); | 88 | IServiceRequest GetNextCompletedRequest(); |
89 | void RemoveCompletedRequest(UUID id); | 89 | void RemoveCompletedRequest(UUID id); |
90 | bool CheckThrottle(uint localID, UUID onerID); | ||
90 | } | 91 | } |
91 | } | 92 | } |
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 7509686..eae6d6f 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs | |||
@@ -94,19 +94,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
94 | m_inventoryDeletes.Enqueue(dtis); | 94 | m_inventoryDeletes.Enqueue(dtis); |
95 | } | 95 | } |
96 | 96 | ||
97 | if (Enabled) | ||
98 | lock (m_inventoryTicker) | ||
99 | m_inventoryTicker.Start(); | ||
100 | |||
101 | // Visually remove it, even if it isnt really gone yet. This means that if we crash before the object | ||
102 | // has gone to inventory, it will reappear in the region again on restart instead of being lost. | ||
103 | // This is not ideal since the object will still be available for manipulation when it should be, but it's | ||
104 | // better than losing the object for now. | ||
105 | if (permissionToDelete) | 97 | if (permissionToDelete) |
106 | { | 98 | { |
107 | foreach (SceneObjectGroup g in objectGroups) | 99 | foreach (SceneObjectGroup g in objectGroups) |
108 | g.DeleteGroupFromScene(false); | 100 | g.DeleteGroupFromScene(false); |
109 | } | 101 | } |
102 | |||
103 | if (Enabled) | ||
104 | lock (m_inventoryTicker) | ||
105 | m_inventoryTicker.Start(); | ||
110 | } | 106 | } |
111 | 107 | ||
112 | private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) | 108 | private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) |
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index f76f882..edc8886 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs | |||
@@ -539,7 +539,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
539 | /// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/> | 539 | /// <see cref="SceneObjectPart.TriggerScriptChangedEvent"/> |
540 | /// </remarks> | 540 | /// </remarks> |
541 | public event ScriptChangedEvent OnScriptChangedEvent; | 541 | public event ScriptChangedEvent OnScriptChangedEvent; |
542 | public delegate void ScriptChangedEvent(uint localID, uint change); | 542 | public delegate void ScriptChangedEvent(uint localID, uint change, object data); |
543 | 543 | ||
544 | public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed); | 544 | public delegate void ScriptControlEvent(UUID item, UUID avatarID, uint held, uint changed); |
545 | 545 | ||
@@ -1185,7 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1185 | } | 1185 | } |
1186 | } | 1186 | } |
1187 | 1187 | ||
1188 | public void TriggerOnScriptChangedEvent(uint localID, uint change) | 1188 | public void TriggerOnScriptChangedEvent(uint localID, uint change, object parameter = null) |
1189 | { | 1189 | { |
1190 | ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent; | 1190 | ScriptChangedEvent handlerScriptChangedEvent = OnScriptChangedEvent; |
1191 | if (handlerScriptChangedEvent != null) | 1191 | if (handlerScriptChangedEvent != null) |
@@ -1194,7 +1194,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1194 | { | 1194 | { |
1195 | try | 1195 | try |
1196 | { | 1196 | { |
1197 | d(localID, change); | 1197 | d(localID, change, parameter); |
1198 | } | 1198 | } |
1199 | catch (Exception e) | 1199 | catch (Exception e) |
1200 | { | 1200 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e6e0354..debcad3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2110,7 +2110,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2110 | // build a list of eligible objects | 2110 | // build a list of eligible objects |
2111 | List<uint> deleteIDs = new List<uint>(); | 2111 | List<uint> deleteIDs = new List<uint>(); |
2112 | List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); | 2112 | List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); |
2113 | List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>(); | 2113 | List<SceneObjectGroup> takeCopyGroups = new List<SceneObjectGroup>(); |
2114 | List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>(); | 2114 | List<SceneObjectGroup> takeDeleteGroups = new List<SceneObjectGroup>(); |
2115 | 2115 | ||
2116 | ScenePresence sp = null; | 2116 | ScenePresence sp = null; |
@@ -2119,11 +2119,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2119 | else if(action != DeRezAction.Return) | 2119 | else if(action != DeRezAction.Return) |
2120 | return; // only Return can be called without a client | 2120 | return; // only Return can be called without a client |
2121 | 2121 | ||
2122 | // Start with true for both, then remove the flags if objects | 2122 | // this is not as 0.8x code |
2123 | // that we can't derez are part of the selection | 2123 | // 0.8x did refuse all operation is not allowed on all objects |
2124 | bool permissionToTake = true; | 2124 | // this will do it on allowed objects |
2125 | bool permissionToTakeCopy = true; | 2125 | // current viewers only ask if all allowed |
2126 | bool permissionToDelete = true; | ||
2127 | 2126 | ||
2128 | foreach (uint localID in localIDs) | 2127 | foreach (uint localID in localIDs) |
2129 | { | 2128 | { |
@@ -2136,8 +2135,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2136 | continue; | 2135 | continue; |
2137 | } | 2136 | } |
2138 | 2137 | ||
2139 | // Already deleted by someone else | 2138 | SceneObjectGroup grp = part.ParentGroup; |
2140 | if (part.ParentGroup.IsDeleted) | 2139 | if (grp == null || grp.IsDeleted) |
2141 | { | 2140 | { |
2142 | //Client still thinks the object exists, kill it | 2141 | //Client still thinks the object exists, kill it |
2143 | deleteIDs.Add(localID); | 2142 | deleteIDs.Add(localID); |
@@ -2145,132 +2144,105 @@ namespace OpenSim.Region.Framework.Scenes | |||
2145 | } | 2144 | } |
2146 | 2145 | ||
2147 | // Can't delete child prims | 2146 | // Can't delete child prims |
2148 | if (part != part.ParentGroup.RootPart) | 2147 | if (part != grp.RootPart) |
2149 | continue; | 2148 | continue; |
2150 | 2149 | ||
2151 | SceneObjectGroup grp = part.ParentGroup; | ||
2152 | if (grp.IsAttachment) | 2150 | if (grp.IsAttachment) |
2153 | continue; | 2151 | { |
2152 | if(!sp.IsGod || action != DeRezAction.Return || action != DeRezAction.Delete) | ||
2153 | continue; | ||
2154 | // this may break the attachment, but its a security action | ||
2155 | // viewers don't allow it anyways | ||
2156 | } | ||
2154 | 2157 | ||
2155 | // If child prims have invalid perms, fix them | 2158 | // If child prims have invalid perms, fix them |
2156 | grp.AdjustChildPrimPermissions(false); | 2159 | grp.AdjustChildPrimPermissions(false); |
2157 | 2160 | ||
2158 | if (remoteClient == null) | 2161 | switch (action) |
2159 | { | 2162 | { |
2160 | // Autoreturn has a null client. Nothing else does. So | 2163 | case DeRezAction.SaveToExistingUserInventoryItem: |
2161 | // allow only returns | ||
2162 | if (action != DeRezAction.Return) | ||
2163 | { | 2164 | { |
2164 | m_log.WarnFormat( | 2165 | if (Permissions.CanTakeCopyObject(grp, sp)) |
2165 | "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", | 2166 | takeCopyGroups.Add(grp); |
2166 | action, grp.Name, grp.UUID); | 2167 | break; |
2167 | return; | ||
2168 | } | 2168 | } |
2169 | 2169 | ||
2170 | permissionToTakeCopy = false; | 2170 | case DeRezAction.TakeCopy: |
2171 | } | ||
2172 | else | ||
2173 | { | ||
2174 | if (action == DeRezAction.TakeCopy) | ||
2175 | { | 2171 | { |
2176 | if (!Permissions.CanTakeCopyObject(grp, sp)) | 2172 | if (Permissions.CanTakeCopyObject(grp, sp)) |
2177 | permissionToTakeCopy = false; | 2173 | takeCopyGroups.Add(grp); |
2174 | break; | ||
2178 | } | 2175 | } |
2179 | else | 2176 | |
2177 | case DeRezAction.Take: | ||
2180 | { | 2178 | { |
2181 | permissionToTakeCopy = false; | 2179 | if (Permissions.CanTakeObject(grp, sp)) |
2180 | takeDeleteGroups.Add(grp); | ||
2181 | break; | ||
2182 | } | 2182 | } |
2183 | if (!Permissions.CanTakeObject(grp, sp)) | ||
2184 | permissionToTake = false; | ||
2185 | |||
2186 | if (!Permissions.CanDeleteObject(grp, remoteClient)) | ||
2187 | permissionToDelete = false; | ||
2188 | } | ||
2189 | |||
2190 | // Handle god perms | ||
2191 | if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) | ||
2192 | { | ||
2193 | permissionToTake = true; | ||
2194 | permissionToTakeCopy = true; | ||
2195 | permissionToDelete = true; | ||
2196 | } | ||
2197 | |||
2198 | // If we're re-saving, we don't even want to delete | ||
2199 | if (action == DeRezAction.SaveToExistingUserInventoryItem) | ||
2200 | permissionToDelete = false; | ||
2201 | 2183 | ||
2202 | // if we want to take a copy, we also don't want to delete | 2184 | case DeRezAction.GodTakeCopy: |
2203 | // Note: after this point, the permissionToTakeCopy flag | ||
2204 | // becomes irrelevant. It already includes the permissionToTake | ||
2205 | // permission and after excluding no copy items here, we can | ||
2206 | // just use that. | ||
2207 | if (action == DeRezAction.TakeCopy) | ||
2208 | { | ||
2209 | // If we don't have permission, stop right here | ||
2210 | if (!permissionToTakeCopy) | ||
2211 | { | 2185 | { |
2212 | remoteClient.SendAlertMessage("You don't have permission to take the object"); | 2186 | if((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) |
2213 | return; | 2187 | takeCopyGroups.Add(grp); |
2188 | break; | ||
2214 | } | 2189 | } |
2215 | 2190 | ||
2216 | permissionToTake = true; | 2191 | case DeRezAction.Delete: |
2217 | // Don't delete | ||
2218 | permissionToDelete = false; | ||
2219 | } | ||
2220 | |||
2221 | if (action == DeRezAction.Return) | ||
2222 | { | ||
2223 | if (remoteClient != null) | ||
2224 | { | 2192 | { |
2225 | if (Permissions.CanReturnObjects( | 2193 | if (Permissions.CanDeleteObject(grp, remoteClient)) |
2226 | null, | ||
2227 | remoteClient, | ||
2228 | new List<SceneObjectGroup>() {grp})) | ||
2229 | { | 2194 | { |
2230 | permissionToTake = true; | 2195 | if(m_useTrashOnDelete || (sp.IsGod && grp.OwnerID != sp.UUID)) |
2231 | permissionToDelete = true; | 2196 | takeDeleteGroups.Add(grp); |
2232 | if(AddToReturns) | 2197 | else |
2233 | AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, | 2198 | deleteGroups.Add(grp); |
2234 | "parcel owner return"); | ||
2235 | } | 2199 | } |
2200 | break; | ||
2236 | } | 2201 | } |
2237 | else // Auto return passes through here with null agent | 2202 | |
2203 | case DeRezAction.Return: | ||
2238 | { | 2204 | { |
2239 | permissionToTake = true; | 2205 | if (remoteClient != null) |
2240 | permissionToDelete = true; | 2206 | { |
2207 | if (Permissions.CanReturnObjects( null, remoteClient, new List<SceneObjectGroup>() {grp})) | ||
2208 | { | ||
2209 | takeDeleteGroups.Add(grp); | ||
2210 | if (AddToReturns) | ||
2211 | AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, | ||
2212 | "parcel owner return"); | ||
2213 | } | ||
2214 | } | ||
2215 | else // Auto return passes through here with null agent | ||
2216 | { | ||
2217 | takeDeleteGroups.Add(grp); | ||
2218 | } | ||
2219 | break; | ||
2241 | } | 2220 | } |
2242 | } | ||
2243 | 2221 | ||
2244 | if (permissionToDelete) | 2222 | default: |
2245 | { | 2223 | break; |
2246 | if (permissionToTake) | ||
2247 | takeDeleteGroups.Add(grp); | ||
2248 | else | ||
2249 | deleteGroups.Add(grp); | ||
2250 | deleteIDs.Add(grp.LocalId); | ||
2251 | } | 2224 | } |
2252 | else if(permissionToTake) | ||
2253 | takeGroups.Add(grp); | ||
2254 | } | 2225 | } |
2255 | 2226 | ||
2256 | SendKillObject(deleteIDs); | 2227 | if(deleteIDs.Count > 0) |
2228 | SendKillObject(deleteIDs); | ||
2257 | 2229 | ||
2258 | if (takeDeleteGroups.Count > 0) | 2230 | if (takeDeleteGroups.Count > 0) |
2259 | { | 2231 | { |
2260 | m_asyncSceneObjectDeleter.DeleteToInventory( | 2232 | m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeDeleteGroups, |
2261 | action, destinationID, takeDeleteGroups, remoteClient, | 2233 | remoteClient, true); |
2262 | true); | ||
2263 | } | 2234 | } |
2264 | if (takeGroups.Count > 0) | 2235 | |
2236 | if (takeCopyGroups.Count > 0) | ||
2265 | { | 2237 | { |
2266 | m_asyncSceneObjectDeleter.DeleteToInventory( | 2238 | m_asyncSceneObjectDeleter.DeleteToInventory(action, destinationID, takeCopyGroups, |
2267 | action, destinationID, takeGroups, remoteClient, | 2239 | remoteClient, false); |
2268 | false); | ||
2269 | } | 2240 | } |
2241 | |||
2270 | if (deleteGroups.Count > 0) | 2242 | if (deleteGroups.Count > 0) |
2271 | { | 2243 | { |
2272 | foreach (SceneObjectGroup g in deleteGroups) | 2244 | foreach (SceneObjectGroup g in deleteGroups) |
2273 | DeleteSceneObject(g, true); | 2245 | DeleteSceneObject(g, false); |
2274 | } | 2246 | } |
2275 | } | 2247 | } |
2276 | 2248 | ||
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b526fe9..ea037be 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -1913,9 +1913,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1913 | { | 1913 | { |
1914 | if (parentGroup.OwnerID == child.OwnerID) | 1914 | if (parentGroup.OwnerID == child.OwnerID) |
1915 | { | 1915 | { |
1916 | parentGroup.LinkToGroup(child); | ||
1917 | |||
1918 | child.DetachFromBackup(); | 1916 | child.DetachFromBackup(); |
1917 | parentGroup.LinkToGroup(child); | ||
1919 | 1918 | ||
1920 | // this is here so physics gets updated! | 1919 | // this is here so physics gets updated! |
1921 | // Don't remove! Bad juju! Stay away! or fix physics! | 1920 | // Don't remove! Bad juju! Stay away! or fix physics! |
@@ -1943,7 +1942,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1943 | */ | 1942 | */ |
1944 | parentGroup.AdjustChildPrimPermissions(false); | 1943 | parentGroup.AdjustChildPrimPermissions(false); |
1945 | parentGroup.HasGroupChanged = true; | 1944 | parentGroup.HasGroupChanged = true; |
1946 | parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true); | ||
1947 | parentGroup.ScheduleGroupForFullAnimUpdate(); | 1945 | parentGroup.ScheduleGroupForFullAnimUpdate(); |
1948 | Monitor.Exit(m_linkLock); | 1946 | Monitor.Exit(m_linkLock); |
1949 | } | 1947 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index bf217a5..8899e96 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -154,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
154 | // We're adding this to a prim we don't own. Force | 154 | // We're adding this to a prim we don't own. Force |
155 | // owner change | 155 | // owner change |
156 | taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; | 156 | taskItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; |
157 | 157 | taskItem.LastOwnerID = item.Owner; | |
158 | } | 158 | } |
159 | else | 159 | else |
160 | { | 160 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a23ebbf..312ce26 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -3242,8 +3242,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3242 | if (ParentGroup.Scene.GetNumberOfClients() == 0) | 3242 | if (ParentGroup.Scene.GetNumberOfClients() == 0) |
3243 | return; | 3243 | return; |
3244 | 3244 | ||
3245 | ParentGroup.QueueForUpdateCheck(); | ||
3246 | |||
3247 | bool isfull = false; | 3245 | bool isfull = false; |
3248 | if (ParentGroup.IsAttachment) | 3246 | if (ParentGroup.IsAttachment) |
3249 | { | 3247 | { |
@@ -3254,6 +3252,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3254 | lock (UpdateFlagLock) | 3252 | lock (UpdateFlagLock) |
3255 | UpdateFlag |= update; | 3253 | UpdateFlag |= update; |
3256 | 3254 | ||
3255 | ParentGroup.QueueForUpdateCheck(); | ||
3256 | |||
3257 | ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull); | 3257 | ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, isfull); |
3258 | } | 3258 | } |
3259 | 3259 | ||
@@ -4439,10 +4439,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4439 | SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary<string, object>()); | 4439 | SceneObjectSerializer.SOPToXml2(xmlWriter, this, new Dictionary<string, object>()); |
4440 | } | 4440 | } |
4441 | 4441 | ||
4442 | public void TriggerScriptChangedEvent(Changed val) | 4442 | public void TriggerScriptChangedEvent(Changed val, object data = null) |
4443 | { | 4443 | { |
4444 | if (ParentGroup != null && ParentGroup.Scene != null) | 4444 | if (ParentGroup != null && ParentGroup.Scene != null) |
4445 | ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val); | 4445 | ParentGroup.Scene.EventManager.TriggerOnScriptChangedEvent(LocalId, (uint)val, data); |
4446 | } | 4446 | } |
4447 | 4447 | ||
4448 | public void TrimPermissions() | 4448 | public void TrimPermissions() |
@@ -5130,11 +5130,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
5130 | 5130 | ||
5131 | if (changeFlags == 0) | 5131 | if (changeFlags == 0) |
5132 | return; | 5132 | return; |
5133 | m_shape.TextureEntry = newTex.GetBytes(); | 5133 | m_shape.TextureEntry = newTex.GetBytes(9); |
5134 | TriggerScriptChangedEvent(changeFlags); | 5134 | TriggerScriptChangedEvent(changeFlags); |
5135 | ParentGroup.HasGroupChanged = true; | 5135 | ParentGroup.HasGroupChanged = true; |
5136 | ScheduleFullUpdate(); | 5136 | ScheduleUpdate(PrimUpdateFlags.Textures); |
5137 | |||
5138 | } | 5137 | } |
5139 | 5138 | ||
5140 | /// <summary> | 5139 | /// <summary> |
@@ -5160,10 +5159,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
5160 | if (changeFlags == 0) | 5159 | if (changeFlags == 0) |
5161 | return; | 5160 | return; |
5162 | 5161 | ||
5163 | m_shape.TextureEntry = newTex.GetBytes(); | 5162 | m_shape.TextureEntry = newTex.GetBytes(9); |
5164 | TriggerScriptChangedEvent(changeFlags); | 5163 | TriggerScriptChangedEvent(changeFlags); |
5165 | ParentGroup.HasGroupChanged = true; | 5164 | ParentGroup.HasGroupChanged = true; |
5166 | ScheduleFullUpdate(); | 5165 | ScheduleUpdate(PrimUpdateFlags.Textures); |
5167 | } | 5166 | } |
5168 | 5167 | ||
5169 | internal void UpdatePhysicsSubscribedEvents() | 5168 | internal void UpdatePhysicsSubscribedEvents() |
@@ -5575,20 +5574,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
5575 | // handle osVolumeDetect | 5574 | // handle osVolumeDetect |
5576 | public void ScriptSetVolumeDetect(bool makeVolumeDetect) | 5575 | public void ScriptSetVolumeDetect(bool makeVolumeDetect) |
5577 | { | 5576 | { |
5577 | if(ParentGroup.IsDeleted) | ||
5578 | return; | ||
5579 | |||
5578 | if(_parentID == 0) | 5580 | if(_parentID == 0) |
5579 | { | 5581 | { |
5580 | // if root prim do it via SOG | 5582 | // if root prim do it is like llVolumeDetect |
5581 | ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect); | 5583 | ParentGroup.ScriptSetVolumeDetect(makeVolumeDetect); |
5582 | return; | 5584 | return; |
5583 | } | 5585 | } |
5584 | 5586 | ||
5585 | bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0); | 5587 | if(ParentGroup.IsVolumeDetect) |
5586 | bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0); | 5588 | return; // entire linkset is phantom already |
5587 | bool wasPhantom = ((Flags & PrimFlags.Phantom) != 0); | 5589 | |
5590 | bool wasUsingPhysics = ParentGroup.UsesPhysics; | ||
5591 | bool wasTemporary = ParentGroup.IsTemporary; | ||
5592 | bool wasPhantom = ParentGroup.IsPhantom; | ||
5588 | 5593 | ||
5589 | if(PhysActor != null) | 5594 | if(PhysActor != null) |
5590 | PhysActor.Building = true; | 5595 | PhysActor.Building = true; |
5591 | UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false); | 5596 | UpdatePrimFlags(wasUsingPhysics, wasTemporary, wasPhantom, makeVolumeDetect, false); |
5592 | } | 5597 | } |
5593 | 5598 | ||
5594 | protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL); | 5599 | protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4934b83..a0f8959 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -815,10 +815,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
815 | m_items.LockItemsForWrite(true); | 815 | m_items.LockItemsForWrite(true); |
816 | m_items.Add(item.ItemID, item); | 816 | m_items.Add(item.ItemID, item); |
817 | m_items.LockItemsForWrite(false); | 817 | m_items.LockItemsForWrite(false); |
818 | if (allowedDrop) | 818 | if (allowedDrop) |
819 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 819 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP, item.ItemID); |
820 | else | 820 | else |
821 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 821 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
822 | 822 | ||
823 | m_part.AggregateInnerPerms(); | 823 | m_part.AggregateInnerPerms(); |
824 | m_inventorySerial++; | 824 | m_inventorySerial++; |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cfb1be4..1c5d23d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -507,7 +507,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
507 | /// <summary> | 507 | /// <summary> |
508 | /// Physical scene representation of this Avatar. | 508 | /// Physical scene representation of this Avatar. |
509 | /// </summary> | 509 | /// </summary> |
510 | public PhysicsActor PhysicsActor { get; private set; } | 510 | |
511 | PhysicsActor m_physActor; | ||
512 | public PhysicsActor PhysicsActor | ||
513 | { | ||
514 | get | ||
515 | { | ||
516 | return m_physActor; | ||
517 | } | ||
518 | private set | ||
519 | { | ||
520 | m_physActor = value; | ||
521 | } | ||
522 | } | ||
511 | 523 | ||
512 | /// <summary> | 524 | /// <summary> |
513 | /// Record user movement inputs. | 525 | /// Record user movement inputs. |
@@ -523,7 +535,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
523 | 535 | ||
524 | public bool Invulnerable | 536 | public bool Invulnerable |
525 | { | 537 | { |
526 | set { m_invulnerable = value; } | 538 | set |
539 | { | ||
540 | m_invulnerable = value; | ||
541 | if(value && Health != 100.0f) | ||
542 | Health = 100.0f; | ||
543 | } | ||
527 | get { return m_invulnerable; } | 544 | get { return m_invulnerable; } |
528 | } | 545 | } |
529 | 546 | ||
@@ -1636,15 +1653,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1636 | /// </summary> | 1653 | /// </summary> |
1637 | public void RemoveFromPhysicalScene() | 1654 | public void RemoveFromPhysicalScene() |
1638 | { | 1655 | { |
1639 | if (PhysicsActor != null) | 1656 | PhysicsActor pa = Interlocked.Exchange(ref m_physActor, null); |
1657 | if (pa != null) | ||
1640 | { | 1658 | { |
1641 | // PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; | 1659 | // PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; |
1642 | 1660 | ||
1643 | PhysicsActor.OnOutOfBounds -= OutOfBoundsCall; | 1661 | pa.OnOutOfBounds -= OutOfBoundsCall; |
1644 | PhysicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; | 1662 | pa.OnCollisionUpdate -= PhysicsCollisionUpdate; |
1645 | PhysicsActor.UnSubscribeEvents(); | 1663 | pa.UnSubscribeEvents(); |
1646 | m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); | 1664 | m_scene.PhysicsScene.RemoveAvatar(pa); |
1647 | PhysicsActor = null; | ||
1648 | } | 1665 | } |
1649 | // else | 1666 | // else |
1650 | // { | 1667 | // { |
@@ -2537,7 +2554,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2537 | m_pos.X = 127f; | 2554 | m_pos.X = 127f; |
2538 | m_pos.Y = 127f; | 2555 | m_pos.Y = 127f; |
2539 | m_pos.Z = 127f; | 2556 | m_pos.Z = 127f; |
2540 | m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); | 2557 | m_log.Error("[AVATAR]: NonFinite Avatar on lastFiniteposition also. Reset Position. Mantis this please. Error #9999903"); |
2541 | } | 2558 | } |
2542 | 2559 | ||
2543 | if(isphysical) | 2560 | if(isphysical) |
@@ -5007,16 +5024,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
5007 | PhysicsScene scene = m_scene.PhysicsScene; | 5024 | PhysicsScene scene = m_scene.PhysicsScene; |
5008 | Vector3 pVec = AbsolutePosition; | 5025 | Vector3 pVec = AbsolutePosition; |
5009 | 5026 | ||
5010 | PhysicsActor = scene.AddAvatar( | 5027 | PhysicsActor pa = scene.AddAvatar( |
5011 | LocalId, Firstname + "." + Lastname, pVec, | 5028 | LocalId, Firstname + "." + Lastname, pVec, |
5012 | Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying); | 5029 | Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying); |
5013 | PhysicsActor.Orientation = m_bodyRot; | 5030 | pa.Orientation = m_bodyRot; |
5014 | //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; | 5031 | //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; |
5015 | PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; | 5032 | pa.OnCollisionUpdate += PhysicsCollisionUpdate; |
5016 | PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong | 5033 | pa.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong |
5017 | PhysicsActor.SubscribeEvents(100); | 5034 | pa.SubscribeEvents(100); |
5018 | PhysicsActor.LocalID = LocalId; | 5035 | pa.LocalID = LocalId; |
5019 | PhysicsActor.SetAlwaysRun = m_setAlwaysRun; | 5036 | pa.SetAlwaysRun = m_setAlwaysRun; |
5037 | PhysicsActor = pa; | ||
5020 | } | 5038 | } |
5021 | 5039 | ||
5022 | private void OutOfBoundsCall(Vector3 pos) | 5040 | private void OutOfBoundsCall(Vector3 pos) |
diff --git a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs index a60381a..020c7be 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainCompressor.cs | |||
@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
155 | return iout; | 155 | return iout; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* | ||
158 | // new using terrain data and patchs indexes | 159 | // new using terrain data and patchs indexes |
159 | public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] map) | 160 | public static List<LayerDataPacket> CreateLayerDataPackets(TerrainData terrData, int[] map) |
160 | { | 161 | { |
@@ -213,6 +214,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
213 | 214 | ||
214 | return ret; | 215 | return ret; |
215 | } | 216 | } |
217 | */ | ||
216 | 218 | ||
217 | public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) | 219 | public static void CreatePatchFromTerrainData(BitPack output, TerrainData terrData, int patchX, int patchY) |
218 | { | 220 | { |
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index 516f9eb..822439f 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs | |||
@@ -323,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Materials | |||
323 | } | 323 | } |
324 | 324 | ||
325 | if(facechanged) | 325 | if(facechanged) |
326 | part.Shape.TextureEntry = te.GetBytes(); | 326 | part.Shape.TextureEntry = te.GetBytes(9); |
327 | 327 | ||
328 | if(facechanged || partchanged) | 328 | if(facechanged || partchanged) |
329 | { | 329 | { |
@@ -632,7 +632,7 @@ namespace OpenSim.Region.OptionalModules.Materials | |||
632 | faceEntry.MaterialID = id; | 632 | faceEntry.MaterialID = id; |
633 | //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); | 633 | //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); |
634 | // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually | 634 | // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually |
635 | sop.Shape.TextureEntry = te.GetBytes(); | 635 | sop.Shape.TextureEntry = te.GetBytes(9); |
636 | } | 636 | } |
637 | 637 | ||
638 | if(oldid != UUID.Zero) | 638 | if(oldid != UUID.Zero) |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs index 40c6b98..4e9216d 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSActorAvatarMove.cs | |||
@@ -47,9 +47,9 @@ public class BSActorAvatarMove : BSActor | |||
47 | // The amount the step up is applying. Used to smooth stair walking. | 47 | // The amount the step up is applying. Used to smooth stair walking. |
48 | float m_lastStepUp; | 48 | float m_lastStepUp; |
49 | 49 | ||
50 | // There are times the velocity is set but we don't want to inforce stationary until the | 50 | // There are times the velocity or force is set but we don't want to inforce |
51 | // real velocity drops. | 51 | // stationary until some tick in the future and the real velocity drops. |
52 | bool m_waitingForLowVelocityForStationary = false; | 52 | int m_waitingForLowVelocityForStationary = 0; |
53 | 53 | ||
54 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) | 54 | public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName) |
55 | : base(physicsScene, pObj, actorName) | 55 | : base(physicsScene, pObj, actorName) |
@@ -114,14 +114,18 @@ public class BSActorAvatarMove : BSActor | |||
114 | m_velocityMotor.Enabled = true; | 114 | m_velocityMotor.Enabled = true; |
115 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}", | 115 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}", |
116 | m_controllingPrim.LocalID, vel, targ); | 116 | m_controllingPrim.LocalID, vel, targ); |
117 | m_waitingForLowVelocityForStationary = false; | 117 | m_waitingForLowVelocityForStationary = 0; |
118 | } | 118 | } |
119 | }); | 119 | }); |
120 | } | 120 | } |
121 | 121 | ||
122 | public void SuppressStationayCheckUntilLowVelocity() | 122 | public void SuppressStationayCheckUntilLowVelocity() |
123 | { | 123 | { |
124 | m_waitingForLowVelocityForStationary = true; | 124 | m_waitingForLowVelocityForStationary = 1; |
125 | } | ||
126 | public void SuppressStationayCheckUntilLowVelocity(int waitTicks) | ||
127 | { | ||
128 | m_waitingForLowVelocityForStationary = waitTicks; | ||
125 | } | 129 | } |
126 | 130 | ||
127 | // If a movement motor has not been created, create one and start the movement | 131 | // If a movement motor has not been created, create one and start the movement |
@@ -143,7 +147,7 @@ public class BSActorAvatarMove : BSActor | |||
143 | m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; | 147 | m_controllingPrim.OnPreUpdateProperty += Process_OnPreUpdateProperty; |
144 | 148 | ||
145 | m_walkingUpStairs = 0; | 149 | m_walkingUpStairs = 0; |
146 | m_waitingForLowVelocityForStationary = false; | 150 | m_waitingForLowVelocityForStationary = 0; |
147 | } | 151 | } |
148 | } | 152 | } |
149 | 153 | ||
@@ -194,15 +198,17 @@ public class BSActorAvatarMove : BSActor | |||
194 | // if colliding with something stationary and we're not doing volume detect . | 198 | // if colliding with something stationary and we're not doing volume detect . |
195 | if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) | 199 | if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) |
196 | { | 200 | { |
197 | if (m_waitingForLowVelocityForStationary) | 201 | if (m_waitingForLowVelocityForStationary-- <= 0) |
198 | { | 202 | { |
199 | // if waiting for velocity to drop and it has finally dropped, we can be stationary | 203 | // if waiting for velocity to drop and it has finally dropped, we can be stationary |
204 | // m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,waitingForLowVelocity {1}", | ||
205 | // m_controllingPrim.LocalID, m_waitingForLowVelocityForStationary); | ||
200 | if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) | 206 | if (m_controllingPrim.RawVelocity.LengthSquared() < BSParam.AvatarStopZeroThresholdSquared) |
201 | { | 207 | { |
202 | m_waitingForLowVelocityForStationary = false; | 208 | m_waitingForLowVelocityForStationary = 0; |
203 | } | 209 | } |
204 | } | 210 | } |
205 | if (!m_waitingForLowVelocityForStationary) | 211 | if (m_waitingForLowVelocityForStationary <= 0) |
206 | { | 212 | { |
207 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); | 213 | m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); |
208 | m_controllingPrim.IsStationary = true; | 214 | m_controllingPrim.IsStationary = true; |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 2ca7dbc..f971e59 100644..100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs | |||
@@ -701,7 +701,7 @@ public sealed class BSCharacter : BSPhysObject | |||
701 | } | 701 | } |
702 | if (m_moveActor != null) | 702 | if (m_moveActor != null) |
703 | { | 703 | { |
704 | m_moveActor.SuppressStationayCheckUntilLowVelocity(); | 704 | m_moveActor.SuppressStationayCheckUntilLowVelocity(BSParam.AvatarAddForceFrames); |
705 | } | 705 | } |
706 | }); | 706 | }); |
707 | } | 707 | } |
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 495f752..d80b050 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs | |||
@@ -149,6 +149,7 @@ public static class BSParam | |||
149 | public static float AvatarHeightHighFudge { get; private set; } | 149 | public static float AvatarHeightHighFudge { get; private set; } |
150 | public static float AvatarFlyingGroundMargin { get; private set; } | 150 | public static float AvatarFlyingGroundMargin { get; private set; } |
151 | public static float AvatarFlyingGroundUpForce { get; private set; } | 151 | public static float AvatarFlyingGroundUpForce { get; private set; } |
152 | public static int AvatarAddForceFrames { get; private set; } | ||
152 | public static float AvatarTerminalVelocity { get; private set; } | 153 | public static float AvatarTerminalVelocity { get; private set; } |
153 | public static float AvatarContactProcessingThreshold { get; private set; } | 154 | public static float AvatarContactProcessingThreshold { get; private set; } |
154 | public static float AvatarAddForcePushFactor { get; private set; } | 155 | public static float AvatarAddForcePushFactor { get; private set; } |
@@ -634,6 +635,8 @@ public static class BSParam | |||
634 | 5f ), | 635 | 5f ), |
635 | new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin", | 636 | new ParameterDefn<float>("AvatarFlyingGroundUpForce", "Upward force applied to the avatar to keep it at flying ground margin", |
636 | 2.0f ), | 637 | 2.0f ), |
638 | new ParameterDefn<int>("AvatarAddForceFrames", "Frames to allow AddForce to apply before checking for stationary", | ||
639 | 10 ), | ||
637 | new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar", | 640 | new ParameterDefn<float>("AvatarTerminalVelocity", "Terminal Velocity of falling avatar", |
638 | -54.0f ), | 641 | -54.0f ), |
639 | new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", | 642 | new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index 3120d04..a6a2dd8 100644..100755 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs | |||
@@ -221,7 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
221 | /// </summary> | 221 | /// </summary> |
222 | private static void CmdHandlerThreadLoop() | 222 | private static void CmdHandlerThreadLoop() |
223 | { | 223 | { |
224 | while (true) | 224 | bool running = true; |
225 | while (running) | ||
225 | { | 226 | { |
226 | try | 227 | try |
227 | { | 228 | { |
@@ -230,7 +231,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
230 | DoOneCmdHandlerPass(); | 231 | DoOneCmdHandlerPass(); |
231 | Watchdog.UpdateThread(); | 232 | Watchdog.UpdateThread(); |
232 | } | 233 | } |
233 | catch ( System.Threading.ThreadAbortException) { } | 234 | catch ( System.Threading.ThreadAbortException) |
235 | { | ||
236 | Thread.ResetAbort(); | ||
237 | running = false; | ||
238 | } | ||
234 | catch (Exception e) | 239 | catch (Exception e) |
235 | { | 240 | { |
236 | m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); | 241 | m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 943141c..ab3562f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -1936,45 +1936,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1936 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 1936 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
1937 | return; | 1937 | return; |
1938 | 1938 | ||
1939 | Primitive.TextureEntry tex = part.Shape.Textures; | ||
1940 | int nsides = GetNumberOfSides(part); | ||
1941 | Color4 texcolor; | ||
1942 | |||
1943 | if (face >= 0 && face < nsides) | ||
1944 | { | ||
1945 | texcolor = tex.CreateFace((uint)face).RGBA; | ||
1946 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1947 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1948 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1949 | tex.FaceTextures[face].RGBA = texcolor; | ||
1950 | part.UpdateTextureEntry(tex); | ||
1951 | return; | ||
1952 | } | ||
1953 | else if (face == ScriptBaseClass.ALL_SIDES) | ||
1954 | { | ||
1955 | for (uint i = 0; i < nsides; i++) | ||
1956 | { | ||
1957 | if (tex.FaceTextures[i] != null) | ||
1958 | { | ||
1959 | texcolor = tex.FaceTextures[i].RGBA; | ||
1960 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1961 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1962 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1963 | tex.FaceTextures[i].RGBA = texcolor; | ||
1964 | } | ||
1965 | texcolor = tex.DefaultTexture.RGBA; | ||
1966 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1967 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1968 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1969 | tex.DefaultTexture.RGBA = texcolor; | ||
1970 | } | ||
1971 | part.UpdateTextureEntry(tex); | ||
1972 | return; | ||
1973 | } | ||
1974 | |||
1975 | if (face == ScriptBaseClass.ALL_SIDES) | ||
1976 | face = SceneObjectPart.ALL_SIDES; | ||
1977 | |||
1978 | m_host.SetFaceColorAlpha(face, color, null); | 1939 | m_host.SetFaceColorAlpha(face, color, null); |
1979 | } | 1940 | } |
1980 | 1941 | ||
@@ -3577,7 +3538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3577 | public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot) | 3538 | public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot) |
3578 | { | 3539 | { |
3579 | m_host.AddScriptLPS(1); | 3540 | m_host.AddScriptLPS(1); |
3580 | if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) | 3541 | if (string.IsNullOrEmpty(inventory) || Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) |
3581 | return; | 3542 | return; |
3582 | 3543 | ||
3583 | float dist = (float)llVecDist(llGetPos(), pos); | 3544 | float dist = (float)llVecDist(llGetPos(), pos); |
@@ -10653,7 +10614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10653 | return false; | 10614 | return false; |
10654 | 10615 | ||
10655 | texface.MaterialID = id; | 10616 | texface.MaterialID = id; |
10656 | part.Shape.TextureEntry = tex.GetBytes(); | 10617 | part.Shape.TextureEntry = tex.GetBytes(9); |
10657 | m_materialsModule.RemoveMaterial(oldid); | 10618 | m_materialsModule.RemoveMaterial(oldid); |
10658 | return true; | 10619 | return true; |
10659 | } | 10620 | } |
@@ -10710,7 +10671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10710 | return false; | 10671 | return false; |
10711 | 10672 | ||
10712 | texface.MaterialID = id; | 10673 | texface.MaterialID = id; |
10713 | part.Shape.TextureEntry = tex.GetBytes(); | 10674 | part.Shape.TextureEntry = tex.GetBytes(9); |
10714 | m_materialsModule.RemoveMaterial(oldid); | 10675 | m_materialsModule.RemoveMaterial(oldid); |
10715 | return true; | 10676 | return true; |
10716 | } | 10677 | } |
@@ -10777,7 +10738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10777 | return false; | 10738 | return false; |
10778 | 10739 | ||
10779 | texface.MaterialID = id; | 10740 | texface.MaterialID = id; |
10780 | part.Shape.TextureEntry = tex.GetBytes(); | 10741 | part.Shape.TextureEntry = tex.GetBytes(9); |
10781 | m_materialsModule.RemoveMaterial(oldid); | 10742 | m_materialsModule.RemoveMaterial(oldid); |
10782 | return true; | 10743 | return true; |
10783 | } | 10744 | } |
@@ -13945,14 +13906,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13945 | 13906 | ||
13946 | public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) | 13907 | public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) |
13947 | { | 13908 | { |
13948 | // Partial implementation: support for parameter flags needed | ||
13949 | // see http://wiki.secondlife.com/wiki/LlHTTPRequest | ||
13950 | // parameter flags support are implemented in ScriptsHttpRequests.cs | ||
13951 | // in StartHttpRequest | ||
13952 | |||
13953 | m_host.AddScriptLPS(1); | 13909 | m_host.AddScriptLPS(1); |
13954 | IHttpRequestModule httpScriptMod = | 13910 | IHttpRequestModule httpScriptMod = m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); |
13955 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); | 13911 | if(httpScriptMod == null) |
13912 | return ""; | ||
13913 | |||
13914 | if(!httpScriptMod.CheckThrottle(m_host.LocalId, m_host.OwnerID)) | ||
13915 | return UUID.Zero.ToString(); | ||
13916 | |||
13956 | List<string> param = new List<string>(); | 13917 | List<string> param = new List<string>(); |
13957 | bool ok; | 13918 | bool ok; |
13958 | Int32 flag; | 13919 | Int32 flag; |
@@ -14123,8 +14084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14123 | } | 14084 | } |
14124 | 14085 | ||
14125 | HttpInitialRequestStatus status; | 14086 | HttpInitialRequestStatus status; |
14126 | UUID reqID | 14087 | UUID reqID = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status); |
14127 | = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body, out status); | ||
14128 | 14088 | ||
14129 | if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER) | 14089 | if (status == HttpInitialRequestStatus.DISALLOWED_BY_FILTER) |
14130 | Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url)); | 14090 | Error("llHttpRequest", string.Format("Request to {0} disallowed by filter", url)); |
@@ -14132,7 +14092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14132 | if (reqID != UUID.Zero) | 14092 | if (reqID != UUID.Zero) |
14133 | return reqID.ToString(); | 14093 | return reqID.ToString(); |
14134 | else | 14094 | else |
14135 | return null; | 14095 | return ""; |
14136 | } | 14096 | } |
14137 | 14097 | ||
14138 | 14098 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9d5f670..dabd399 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -3629,7 +3629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3629 | { | 3629 | { |
3630 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | 3630 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); |
3631 | 3631 | ||
3632 | World.ForEachRootScenePresence(delegate(ScenePresence sp) | 3632 | World.ForEachRootScenePresence(delegate (ScenePresence sp) |
3633 | { | 3633 | { |
3634 | if (sp.Firstname == FirstName && sp.Lastname == SurName) | 3634 | if (sp.Firstname == FirstName && sp.Lastname == SurName) |
3635 | { | 3635 | { |
@@ -3643,18 +3643,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3643 | }); | 3643 | }); |
3644 | } | 3644 | } |
3645 | 3645 | ||
3646 | public LSL_Float osGetHealth(string avatar) | 3646 | public void osKickAvatar(LSL_Key agentKey, string alert) |
3647 | { | ||
3648 | CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); | ||
3649 | |||
3650 | UUID id; | ||
3651 | if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero) | ||
3652 | return; | ||
3653 | |||
3654 | ScenePresence sp = World.GetScenePresence(id); | ||
3655 | if(sp == null) | ||
3656 | return; | ||
3657 | |||
3658 | // kick client... | ||
3659 | if (alert != null) | ||
3660 | sp.ControllingClient.Kick(alert); | ||
3661 | |||
3662 | // ...and close on our side | ||
3663 | sp.Scene.CloseAgent(id, false); | ||
3664 | } | ||
3665 | |||
3666 | public LSL_Float osGetHealth(LSL_Key agentKey) | ||
3647 | { | 3667 | { |
3648 | CheckThreatLevel(ThreatLevel.None, "osGetHealth"); | 3668 | CheckThreatLevel(ThreatLevel.None, "osGetHealth"); |
3649 | 3669 | ||
3650 | LSL_Float health = new LSL_Float(-1); | 3670 | LSL_Float health = new LSL_Float(-1); |
3651 | ScenePresence presence = World.GetScenePresence(new UUID(avatar)); | 3671 | |
3672 | UUID id; | ||
3673 | if (!UUID.TryParse(agentKey, out id) || id == UUID.Zero) | ||
3674 | return health; | ||
3675 | |||
3676 | ScenePresence presence = World.GetScenePresence(id); | ||
3652 | if (presence != null) | 3677 | if (presence != null) |
3653 | health = presence.Health; | 3678 | health = presence.Health; |
3654 | return health; | 3679 | return health; |
3655 | } | 3680 | } |
3656 | 3681 | ||
3657 | public void osCauseDamage(string avatar, double damage) | 3682 | public void osCauseDamage(LSL_Key avatar, LSL_Float damage) |
3658 | { | 3683 | { |
3659 | CheckThreatLevel(ThreatLevel.High, "osCauseDamage"); | 3684 | CheckThreatLevel(ThreatLevel.High, "osCauseDamage"); |
3660 | 3685 | ||
@@ -3683,7 +3708,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3683 | } | 3708 | } |
3684 | } | 3709 | } |
3685 | 3710 | ||
3686 | public void osCauseHealing(string avatar, double healing) | 3711 | public void osCauseHealing(LSL_Key avatar, LSL_Float healing) |
3687 | { | 3712 | { |
3688 | CheckThreatLevel(ThreatLevel.High, "osCauseHealing"); | 3713 | CheckThreatLevel(ThreatLevel.High, "osCauseHealing"); |
3689 | 3714 | ||
@@ -3704,7 +3729,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3704 | presence.setHealthWithUpdate(health); | 3729 | presence.setHealthWithUpdate(health); |
3705 | } | 3730 | } |
3706 | 3731 | ||
3707 | public void osSetHealth(string avatar, double health) | 3732 | public void osSetHealth(LSL_Key avatar, LSL_Float health) |
3708 | { | 3733 | { |
3709 | CheckThreatLevel(ThreatLevel.High, "osSetHealth"); | 3734 | CheckThreatLevel(ThreatLevel.High, "osSetHealth"); |
3710 | 3735 | ||
@@ -3722,7 +3747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3722 | } | 3747 | } |
3723 | } | 3748 | } |
3724 | 3749 | ||
3725 | public void osSetHealRate(string avatar, double healrate) | 3750 | public void osSetHealRate(LSL_Key avatar, LSL_Float healrate) |
3726 | { | 3751 | { |
3727 | CheckThreatLevel(ThreatLevel.High, "osSetHealRate"); | 3752 | CheckThreatLevel(ThreatLevel.High, "osSetHealRate"); |
3728 | 3753 | ||
@@ -3737,7 +3762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3737 | presence.HealRate = (float)healrate; | 3762 | presence.HealRate = (float)healrate; |
3738 | } | 3763 | } |
3739 | 3764 | ||
3740 | public LSL_Float osGetHealRate(string avatar) | 3765 | public LSL_Float osGetHealRate(LSL_Key avatar) |
3741 | { | 3766 | { |
3742 | CheckThreatLevel(ThreatLevel.None, "osGetHealRate"); | 3767 | CheckThreatLevel(ThreatLevel.None, "osGetHealRate"); |
3743 | 3768 | ||
@@ -3865,29 +3890,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3865 | } | 3890 | } |
3866 | 3891 | ||
3867 | /// <summary> | 3892 | /// <summary> |
3868 | /// Get the description from an inventory item | ||
3869 | /// </summary> | ||
3870 | /// <param name="inventoryName"></param> | ||
3871 | /// <returns>Item description</returns> | ||
3872 | public LSL_String osGetInventoryDesc(string item) | ||
3873 | { | ||
3874 | CheckThreatLevel(); | ||
3875 | |||
3876 | lock (m_host.TaskInventory) | ||
3877 | { | ||
3878 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) | ||
3879 | { | ||
3880 | if (inv.Value.Name == item) | ||
3881 | { | ||
3882 | return inv.Value.Description.ToString(); | ||
3883 | } | ||
3884 | } | ||
3885 | } | ||
3886 | |||
3887 | return String.Empty; | ||
3888 | } | ||
3889 | |||
3890 | /// <summary> | ||
3891 | /// Invite user to the group this object is set to | 3893 | /// Invite user to the group this object is set to |
3892 | /// </summary> | 3894 | /// </summary> |
3893 | /// <param name="agentId"></param> | 3895 | /// <param name="agentId"></param> |
@@ -4849,8 +4851,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4849 | return Math.Atan2(mcross, dot); | 4851 | return Math.Atan2(mcross, dot); |
4850 | } | 4852 | } |
4851 | 4853 | ||
4852 | |||
4853 | //******* link sound | ||
4854 | public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume) | 4854 | public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume) |
4855 | { | 4855 | { |
4856 | m_host.AddScriptLPS(1); | 4856 | m_host.AddScriptLPS(1); |
@@ -5381,5 +5381,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5381 | return 1; | 5381 | return 1; |
5382 | } | 5382 | } |
5383 | 5383 | ||
5384 | public LSL_Key osGetInventoryLastOwner(LSL_String itemNameorid) | ||
5385 | { | ||
5386 | m_host.AddScriptLPS(1); | ||
5387 | |||
5388 | TaskInventoryItem item = null; | ||
5389 | UUID itemID; | ||
5390 | if (UUID.TryParse(itemNameorid, out itemID)) | ||
5391 | item = m_host.Inventory.GetInventoryItem(itemID); | ||
5392 | else | ||
5393 | item = m_host.Inventory.GetInventoryItem(itemNameorid); | ||
5394 | |||
5395 | if (item == null) | ||
5396 | return UUID.Zero.ToString(); | ||
5397 | |||
5398 | UUID id = item.LastOwnerID; | ||
5399 | if(id == UUID.Zero) | ||
5400 | id= item.OwnerID; | ||
5401 | return id.ToString(); | ||
5402 | } | ||
5403 | |||
5404 | public LSL_String osGetInventoryName(LSL_Key itemId) | ||
5405 | { | ||
5406 | m_host.AddScriptLPS(1); | ||
5407 | |||
5408 | TaskInventoryItem item = null; | ||
5409 | UUID itemID; | ||
5410 | if (UUID.TryParse(itemId, out itemID)) | ||
5411 | item = m_host.Inventory.GetInventoryItem(itemID); | ||
5412 | |||
5413 | if (item == null) | ||
5414 | return String.Empty; | ||
5415 | |||
5416 | return item.Name; | ||
5417 | } | ||
5418 | |||
5419 | public LSL_String osGetInventoryDesc(LSL_String itemNameorid) | ||
5420 | { | ||
5421 | m_host.AddScriptLPS(1); | ||
5422 | |||
5423 | TaskInventoryItem item = null; | ||
5424 | UUID itemID; | ||
5425 | if (UUID.TryParse(itemNameorid, out itemID)) | ||
5426 | item = m_host.Inventory.GetInventoryItem(itemID); | ||
5427 | else | ||
5428 | item = m_host.Inventory.GetInventoryItem(itemNameorid); | ||
5429 | |||
5430 | if (item == null) | ||
5431 | return String.Empty; | ||
5432 | |||
5433 | return item.Description; | ||
5434 | } | ||
5435 | |||
5436 | public LSL_Key osGetLastChangedEventKey() | ||
5437 | { | ||
5438 | m_host.AddScriptLPS(1); | ||
5439 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); | ||
5440 | if (detectedParams == null) | ||
5441 | return String.Empty; | ||
5442 | return detectedParams.Key.ToString(); | ||
5443 | } | ||
5384 | } | 5444 | } |
5385 | } \ No newline at end of file | 5445 | } \ No newline at end of file |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs index 629b14b..166f2d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/HttpRequest.cs | |||
@@ -48,14 +48,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
48 | if (m_CmdManager.m_ScriptEngine.World == null) | 48 | if (m_CmdManager.m_ScriptEngine.World == null) |
49 | return; | 49 | return; |
50 | 50 | ||
51 | IHttpRequestModule iHttpReq = | 51 | IHttpRequestModule iHttpReq = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); |
52 | m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); | 52 | if(iHttpReq == null) |
53 | 53 | return; | |
54 | HttpRequestClass httpInfo = null; | ||
55 | |||
56 | if (iHttpReq != null) | ||
57 | httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest(); | ||
58 | 54 | ||
55 | HttpRequestClass httpInfo = (HttpRequestClass)iHttpReq.GetNextCompletedRequest(); | ||
59 | while (httpInfo != null) | 56 | while (httpInfo != null) |
60 | { | 57 | { |
61 | //m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status); | 58 | //m_log.Debug("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status); |
@@ -67,8 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins | |||
67 | // implemented here yet anyway. Should be fixed if/when maxsize | 64 | // implemented here yet anyway. Should be fixed if/when maxsize |
68 | // is supported | 65 | // is supported |
69 | 66 | ||
70 | iHttpReq.RemoveCompletedRequest(httpInfo.ReqID); | ||
71 | |||
72 | object[] resobj = new object[] | 67 | object[] resobj = new object[] |
73 | { | 68 | { |
74 | new LSL_Types.LSLString(httpInfo.ReqID.ToString()), | 69 | new LSL_Types.LSLString(httpInfo.ReqID.ToString()), |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 12e8103..49b3f74 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | |||
@@ -379,15 +379,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
379 | 379 | ||
380 | int osGetSimulatorMemory(); | 380 | int osGetSimulatorMemory(); |
381 | int osGetSimulatorMemoryKB(); | 381 | int osGetSimulatorMemoryKB(); |
382 | void osKickAvatar(string FirstName,string SurName,string alert); | 382 | void osKickAvatar(string FirstName, string SurName, string alert); |
383 | void osKickAvatar(LSL_Key agentId, string alert); | ||
383 | void osSetSpeed(string UUID, LSL_Float SpeedModifier); | 384 | void osSetSpeed(string UUID, LSL_Float SpeedModifier); |
384 | void osSetOwnerSpeed(LSL_Float SpeedModifier); | 385 | void osSetOwnerSpeed(LSL_Float SpeedModifier); |
385 | LSL_Float osGetHealth(string avatar); | 386 | LSL_Float osGetHealth(key agentId); |
386 | void osCauseHealing(string avatar, double healing); | 387 | void osCauseHealing(key agentId, LSL_Float healing); |
387 | void osSetHealth(string avatar, double health); | 388 | void osSetHealth(key agentId, LSL_Float health); |
388 | void osSetHealRate(string avatar, double health); | 389 | void osSetHealRate(key agentId, LSL_Float health); |
389 | LSL_Float osGetHealRate(string avatar); | 390 | LSL_Float osGetHealRate(key agentId); |
390 | void osCauseDamage(string avatar, double damage); | 391 | void osCauseDamage(key avatar, LSL_Float damage); |
391 | void osForceOtherSit(string avatar); | 392 | void osForceOtherSit(string avatar); |
392 | void osForceOtherSit(string avatar, string target); | 393 | void osForceOtherSit(string avatar, string target); |
393 | LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); | 394 | LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); |
@@ -400,8 +401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
400 | 401 | ||
401 | LSL_String osUnixTimeToTimestamp(LSL_Integer time); | 402 | LSL_String osUnixTimeToTimestamp(LSL_Integer time); |
402 | 403 | ||
403 | LSL_String osGetInventoryDesc(string item); | ||
404 | |||
405 | LSL_Integer osInviteToGroup(LSL_Key agentId); | 404 | LSL_Integer osInviteToGroup(LSL_Key agentId); |
406 | LSL_Integer osEjectFromGroup(LSL_Key agentId); | 405 | LSL_Integer osEjectFromGroup(LSL_Key agentId); |
407 | 406 | ||
@@ -546,5 +545,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces | |||
546 | LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin); | 545 | LSL_Integer osApproxEquals(vector va, vector vb, LSL_Float margin); |
547 | LSL_Integer osApproxEquals(rotation ra, rotation rb); | 546 | LSL_Integer osApproxEquals(rotation ra, rotation rb); |
548 | LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); | 547 | LSL_Integer osApproxEquals(rotation ra, rotation rb, LSL_Float margin); |
548 | LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId); | ||
549 | LSL_String osGetInventoryName(LSL_Key itemId); | ||
550 | LSL_String osGetInventoryDesc(LSL_String itemNameOrId); | ||
551 | LSL_Key osGetLastChangedEventKey(); | ||
549 | } | 552 | } |
550 | } | 553 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 49f46b7..8b70128 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
35 | public partial class ScriptBaseClass | 35 | public partial class ScriptBaseClass |
36 | { | 36 | { |
37 | // SCRIPTS CONSTANTS | 37 | // SCRIPTS CONSTANTS |
38 | public static readonly LSLInteger OS_APIVERSION = 2; | 38 | public static readonly LSLInteger OS_APIVERSION = 3; |
39 | 39 | ||
40 | public static readonly LSLInteger TRUE = 1; | 40 | public static readonly LSLInteger TRUE = 1; |
41 | public static readonly LSLInteger FALSE = 0; | 41 | public static readonly LSLInteger FALSE = 0; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 94df1ea..fb491e4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | |||
@@ -965,11 +965,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
965 | return m_OSSL_Functions.osGetSimulatorMemoryKB(); | 965 | return m_OSSL_Functions.osGetSimulatorMemoryKB(); |
966 | } | 966 | } |
967 | 967 | ||
968 | public void osKickAvatar(string FirstName,string SurName,string alert) | 968 | public void osKickAvatar(string FirstName, string SurName, string alert) |
969 | { | 969 | { |
970 | m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); | 970 | m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); |
971 | } | 971 | } |
972 | 972 | ||
973 | public void osKickAvatar(LSL_Key agentId, string alert) | ||
974 | { | ||
975 | m_OSSL_Functions.osKickAvatar(agentId, alert); | ||
976 | } | ||
977 | |||
973 | public void osSetSpeed(string UUID, LSL_Float SpeedModifier) | 978 | public void osSetSpeed(string UUID, LSL_Float SpeedModifier) |
974 | { | 979 | { |
975 | m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); | 980 | m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); |
@@ -980,32 +985,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
980 | m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier); | 985 | m_OSSL_Functions.osSetOwnerSpeed(SpeedModifier); |
981 | } | 986 | } |
982 | 987 | ||
983 | public LSL_Float osGetHealth(string avatar) | 988 | public LSL_Float osGetHealth(key avatar) |
984 | { | 989 | { |
985 | return m_OSSL_Functions.osGetHealth(avatar); | 990 | return m_OSSL_Functions.osGetHealth(avatar); |
986 | } | 991 | } |
987 | 992 | ||
988 | public void osCauseDamage(string avatar, double damage) | 993 | public void osCauseDamage(key avatar, LSL_Float damage) |
989 | { | 994 | { |
990 | m_OSSL_Functions.osCauseDamage(avatar, damage); | 995 | m_OSSL_Functions.osCauseDamage(avatar, damage); |
991 | } | 996 | } |
992 | 997 | ||
993 | public void osCauseHealing(string avatar, double healing) | 998 | public void osCauseHealing(key avatar, LSL_Float healing) |
994 | { | 999 | { |
995 | m_OSSL_Functions.osCauseHealing(avatar, healing); | 1000 | m_OSSL_Functions.osCauseHealing(avatar, healing); |
996 | } | 1001 | } |
997 | 1002 | ||
998 | public void osSetHealth(string avatar, double health) | 1003 | public void osSetHealth(key avatar, LSL_Float health) |
999 | { | 1004 | { |
1000 | m_OSSL_Functions.osSetHealth(avatar, health); | 1005 | m_OSSL_Functions.osSetHealth(avatar, health); |
1001 | } | 1006 | } |
1002 | 1007 | ||
1003 | public void osSetHealRate(string avatar, double health) | 1008 | public void osSetHealRate(key avatar, LSL_Float health) |
1004 | { | 1009 | { |
1005 | m_OSSL_Functions.osSetHealRate(avatar, health); | 1010 | m_OSSL_Functions.osSetHealRate(avatar, health); |
1006 | } | 1011 | } |
1007 | 1012 | ||
1008 | public LSL_Float osGetHealRate(string avatar) | 1013 | public LSL_Float osGetHealRate(key avatar) |
1009 | { | 1014 | { |
1010 | return m_OSSL_Functions.osGetHealRate(avatar); | 1015 | return m_OSSL_Functions.osGetHealRate(avatar); |
1011 | } | 1016 | } |
@@ -1055,11 +1060,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1055 | return m_OSSL_Functions.osUnixTimeToTimestamp(time); | 1060 | return m_OSSL_Functions.osUnixTimeToTimestamp(time); |
1056 | } | 1061 | } |
1057 | 1062 | ||
1058 | public LSL_String osGetInventoryDesc(string item) | ||
1059 | { | ||
1060 | return m_OSSL_Functions.osGetInventoryDesc(item); | ||
1061 | } | ||
1062 | |||
1063 | public LSL_Integer osInviteToGroup(LSL_Key agentId) | 1063 | public LSL_Integer osInviteToGroup(LSL_Key agentId) |
1064 | { | 1064 | { |
1065 | return m_OSSL_Functions.osInviteToGroup(agentId); | 1065 | return m_OSSL_Functions.osInviteToGroup(agentId); |
@@ -1361,5 +1361,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
1361 | { | 1361 | { |
1362 | return m_OSSL_Functions.osApproxEquals(ra, rb, margin); | 1362 | return m_OSSL_Functions.osApproxEquals(ra, rb, margin); |
1363 | } | 1363 | } |
1364 | |||
1365 | public LSL_Key osGetInventoryLastOwner(LSL_String itemNameOrId) | ||
1366 | { | ||
1367 | return m_OSSL_Functions.osGetInventoryLastOwner(itemNameOrId); | ||
1368 | } | ||
1369 | |||
1370 | public LSL_String osGetInventoryName(LSL_Key itemId) | ||
1371 | { | ||
1372 | return m_OSSL_Functions.osGetInventoryName(itemId); | ||
1373 | } | ||
1374 | |||
1375 | public LSL_String osGetInventoryDesc(LSL_String itemNameOrId) | ||
1376 | { | ||
1377 | return m_OSSL_Functions.osGetInventoryDesc(itemNameOrId); | ||
1378 | } | ||
1379 | |||
1380 | public LSL_Key osGetLastChangedEventKey() | ||
1381 | { | ||
1382 | return m_OSSL_Functions.osGetLastChangedEventKey(); | ||
1383 | } | ||
1364 | } | 1384 | } |
1365 | } | 1385 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 019a0d9..351fca9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -699,7 +699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
699 | // If min event delay is set then ignore any events untill the time has expired | 699 | // If min event delay is set then ignore any events untill the time has expired |
700 | // This currently only allows 1 event of any type in the given time period. | 700 | // This currently only allows 1 event of any type in the given time period. |
701 | // This may need extending to allow for a time for each individual event type. | 701 | // This may need extending to allow for a time for each individual event type. |
702 | if (m_eventDelayTicks != 0) | 702 | if (m_eventDelayTicks != 0 && |
703 | data.EventName != "state" && data.EventName != "state_entry" && data.EventName != "state_exit" | ||
704 | && data.EventName != "run_time_permissions" && data.EventName != "http_request" && data.EventName != "link_message") | ||
703 | { | 705 | { |
704 | if (DateTime.Now.Ticks < m_nextEventTimeTicks) | 706 | if (DateTime.Now.Ticks < m_nextEventTimeTicks) |
705 | return; | 707 | return; |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index b7fc161..50a95a9 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs | |||
@@ -215,12 +215,25 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
215 | det)); | 215 | det)); |
216 | } | 216 | } |
217 | 217 | ||
218 | public void changed(uint localID, uint change) | 218 | public void changed(uint localID, uint change, object parameter) |
219 | { | 219 | { |
220 | // Add to queue for all scripts in localID, Object pass change. | 220 | // Add to queue for all scripts in localID, Object pass change. |
221 | myScriptEngine.PostObjectEvent(localID, new EventParams( | 221 | if(parameter == null) |
222 | "changed",new object[] { new LSL_Types.LSLInteger(change) }, | 222 | { |
223 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
224 | "changed", new object[] { new LSL_Types.LSLInteger(change) }, | ||
223 | new DetectParams[0])); | 225 | new DetectParams[0])); |
226 | return; | ||
227 | } | ||
228 | if (parameter is UUID) | ||
229 | { | ||
230 | DetectParams det = new DetectParams(); | ||
231 | det.Key = (UUID)parameter; | ||
232 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
233 | "changed", new object[] { new LSL_Types.LSLInteger(change) }, | ||
234 | new DetectParams[] { det })); | ||
235 | return; | ||
236 | } | ||
224 | } | 237 | } |
225 | 238 | ||
226 | // state_entry: not processed here | 239 | // state_entry: not processed here |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs index c00e8d4..3539fa1 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs | |||
@@ -88,10 +88,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
88 | 88 | ||
89 | path_update = 40, | 89 | path_update = 40, |
90 | 90 | ||
91 | // XMRE specific | ||
92 | region_cross = 63, | ||
93 | |||
94 | // marks highest numbered event, ie, number of columns in seht. | 91 | // marks highest numbered event, ie, number of columns in seht. |
95 | Size = 64 | 92 | Size = 41 |
96 | } | 93 | } |
97 | } | 94 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs index 017b294..6acc293 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs | |||
@@ -930,12 +930,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
930 | 930 | ||
931 | public void SetMinEventDelay(UUID itemID, double delay) | 931 | public void SetMinEventDelay(UUID itemID, double delay) |
932 | { | 932 | { |
933 | XMRInstance instance = GetInstance(itemID); | ||
934 | if (instance != null) | ||
935 | instance.MinEventDelay = delay; | ||
933 | } | 936 | } |
934 | 937 | ||
935 | public int GetStartParameter(UUID itemID) | 938 | public int GetStartParameter(UUID itemID) |
936 | { | 939 | { |
937 | XMRInstance instance = GetInstance(itemID); | 940 | XMRInstance instance = GetInstance(itemID); |
938 | if(instance == null) | 941 | if (instance == null) |
939 | return 0; | 942 | return 0; |
940 | return instance.StartParam; | 943 | return instance.StartParam; |
941 | } | 944 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs index 5a8b2a3..65a8aed 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs | |||
@@ -182,13 +182,26 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
182 | new DetectParams[] { det })); | 182 | new DetectParams[] { det })); |
183 | } | 183 | } |
184 | 184 | ||
185 | public void changed(uint localID, uint change) | 185 | public void changed(uint localID, uint change, object parameter) |
186 | { | 186 | { |
187 | int ch = (int)change; | 187 | int ch = (int)change; |
188 | // Add to queue for all scripts in localID, Object pass change. | 188 | // Add to queue for all scripts in localID, Object pass change. |
189 | this.PostObjectEvent(localID, new EventParams( | 189 | if(parameter == null) |
190 | { | ||
191 | PostObjectEvent(localID, new EventParams( | ||
190 | "changed", new object[] { ch }, | 192 | "changed", new object[] { ch }, |
191 | zeroDetectParams)); | 193 | zeroDetectParams)); |
194 | return; | ||
195 | } | ||
196 | if ( parameter is UUID) | ||
197 | { | ||
198 | DetectParams det = new DetectParams(); | ||
199 | det.Key = (UUID)parameter; | ||
200 | PostObjectEvent(localID, new EventParams( | ||
201 | "changed", new object[] { ch }, | ||
202 | new DetectParams[] { det })); | ||
203 | return; | ||
204 | } | ||
192 | } | 205 | } |
193 | 206 | ||
194 | // state_entry: not processed here | 207 | // state_entry: not processed here |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs index 6fe11d8..7fc97e9 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs | |||
@@ -422,9 +422,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
422 | object[] saveEHArgs = this.ehArgs; | 422 | object[] saveEHArgs = this.ehArgs; |
423 | ScriptEventCode saveEventCode = this.eventCode; | 423 | ScriptEventCode saveEventCode = this.eventCode; |
424 | 424 | ||
425 | this.m_DetectParams = evt.DetectParams; | 425 | m_DetectParams = evt.DetectParams; |
426 | this.ehArgs = evt.Params; | 426 | ehArgs = evt.Params; |
427 | this.eventCode = evc; | 427 | eventCode = evc; |
428 | 428 | ||
429 | try | 429 | try |
430 | { | 430 | { |
@@ -432,9 +432,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
432 | } | 432 | } |
433 | finally | 433 | finally |
434 | { | 434 | { |
435 | this.m_DetectParams = saveDetParams; | 435 | m_DetectParams = saveDetParams; |
436 | this.ehArgs = saveEHArgs; | 436 | ehArgs = saveEHArgs; |
437 | this.eventCode = saveEventCode; | 437 | eventCode = saveEventCode; |
438 | } | 438 | } |
439 | 439 | ||
440 | // Keep waiting until we find a returnable event or timeout. | 440 | // Keep waiting until we find a returnable event or timeout. |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs index 9bb894d..5798638 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs | |||
@@ -115,6 +115,15 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
115 | m_RunOnePhase = "GetExecutionState D"; | 115 | m_RunOnePhase = "GetExecutionState D"; |
116 | CheckRunLockInvariants(true); | 116 | CheckRunLockInvariants(true); |
117 | 117 | ||
118 | if (m_minEventDelay != 0.0) | ||
119 | { | ||
120 | XmlElement minEventDelayN = doc.CreateElement("", "mEvtDly", ""); | ||
121 | minEventDelayN.AppendChild(doc.CreateTextNode(m_minEventDelay.ToString())); | ||
122 | scriptStateN.AppendChild(minEventDelayN); | ||
123 | m_RunOnePhase = "GetExecutionState D"; | ||
124 | CheckRunLockInvariants(true); | ||
125 | } | ||
126 | |||
118 | // More misc data. | 127 | // More misc data. |
119 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); | 128 | XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); |
120 | scriptStateN.AppendChild(permissionsN); | 129 | scriptStateN.AppendChild(permissionsN); |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs index b140453..7e13ae4 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs | |||
@@ -527,6 +527,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
527 | XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit"); | 527 | XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit"); |
528 | doGblInit = bool.Parse(doGblInitN.InnerText); | 528 | doGblInit = bool.Parse(doGblInitN.InnerText); |
529 | 529 | ||
530 | double minEventDelay = 0.0; | ||
531 | XmlElement minEventDelayN = (XmlElement)scriptStateN.SelectSingleNode("mEvtDly"); | ||
532 | if(minEventDelayN != null) | ||
533 | minEventDelay = Double.Parse(minEventDelayN.InnerText); | ||
534 | |||
530 | // get values used by stuff like llDetectedGrab, etc. | 535 | // get values used by stuff like llDetectedGrab, etc. |
531 | DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray")); | 536 | DetectParams[] detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray")); |
532 | 537 | ||
@@ -576,6 +581,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
576 | AsyncCommandManager.CreateFromData(m_Engine, | 581 | AsyncCommandManager.CreateFromData(m_Engine, |
577 | m_LocalID, m_ItemID, m_Part.UUID, | 582 | m_LocalID, m_ItemID, m_Part.UUID, |
578 | pluginData); | 583 | pluginData); |
584 | |||
585 | MinEventDelay = minEventDelay; | ||
579 | } | 586 | } |
580 | 587 | ||
581 | private void processXstate(XmlDocument doc) | 588 | private void processXstate(XmlDocument doc) |
@@ -919,6 +926,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
919 | 926 | ||
920 | AsyncCommandManager.CreateFromData(m_Engine, | 927 | AsyncCommandManager.CreateFromData(m_Engine, |
921 | m_LocalID, m_ItemID, m_Part.UUID, pluginData); | 928 | m_LocalID, m_ItemID, m_Part.UUID, pluginData); |
929 | |||
930 | MinEventDelay = minEventDelay; | ||
922 | } | 931 | } |
923 | 932 | ||
924 | private static void getvarNames(Dictionary<int, string> s, Dictionary<string, int> d) | 933 | private static void getvarNames(Dictionary<int, string> s, Dictionary<string, int> d) |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs index 3c0040c..def06b2 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs | |||
@@ -215,5 +215,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
215 | // It's born ready, but will be reset when the detach is posted. | 215 | // It's born ready, but will be reset when the detach is posted. |
216 | // It will then be set again on suspend/completion | 216 | // It will then be set again on suspend/completion |
217 | private ManualResetEvent m_DetachReady = new ManualResetEvent(true); | 217 | private ManualResetEvent m_DetachReady = new ManualResetEvent(true); |
218 | |||
219 | // llmineventdelay support | ||
220 | double m_minEventDelay = 0.0; | ||
221 | double m_nextEventTime = 0.0; | ||
218 | } | 222 | } |
219 | } | 223 | } |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs index 0af3d37..12feb7b 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs | |||
@@ -298,6 +298,24 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | public double MinEventDelay | ||
302 | { | ||
303 | get | ||
304 | { | ||
305 | return m_minEventDelay; | ||
306 | } | ||
307 | set | ||
308 | { | ||
309 | if (value > 0.001) | ||
310 | m_minEventDelay = value; | ||
311 | else | ||
312 | m_minEventDelay = 0.0; | ||
313 | |||
314 | m_nextEventTime = 0.0; // reset it | ||
315 | } | ||
316 | } | ||
317 | |||
318 | |||
301 | public SceneObjectPart SceneObject | 319 | public SceneObjectPart SceneObject |
302 | { | 320 | { |
303 | get | 321 | get |
diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs index 6c969dc..1b735e3 100644 --- a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs | |||
@@ -63,8 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
63 | */ | 63 | */ |
64 | public void PostEvent(EventParams evt) | 64 | public void PostEvent(EventParams evt) |
65 | { | 65 | { |
66 | ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), | 66 | ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName); |
67 | evt.EventName); | ||
68 | 67 | ||
69 | // Put event on end of event queue. | 68 | // Put event on end of event queue. |
70 | bool startIt = false; | 69 | bool startIt = false; |
@@ -86,6 +85,47 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
86 | if(!m_Running && !construct) | 85 | if(!m_Running && !construct) |
87 | return; | 86 | return; |
88 | 87 | ||
88 | if(m_minEventDelay != 0) | ||
89 | { | ||
90 | switch (evc) | ||
91 | { | ||
92 | // ignore some events by time set by llMinEventDelay | ||
93 | case ScriptEventCode.collision: | ||
94 | case ScriptEventCode.land_collision: | ||
95 | case ScriptEventCode.listen: | ||
96 | case ScriptEventCode.not_at_target: | ||
97 | case ScriptEventCode.not_at_rot_target: | ||
98 | case ScriptEventCode.no_sensor: | ||
99 | case ScriptEventCode.sensor: | ||
100 | case ScriptEventCode.timer: | ||
101 | case ScriptEventCode.touch: | ||
102 | { | ||
103 | double now = Util.GetTimeStamp(); | ||
104 | if (now < m_nextEventTime) | ||
105 | return; | ||
106 | m_nextEventTime = now + m_minEventDelay; | ||
107 | break; | ||
108 | } | ||
109 | case ScriptEventCode.changed: | ||
110 | { | ||
111 | const int canignore = ~(CHANGED_SCALE | CHANGED_POSITION); | ||
112 | int change = (int)evt.Params[0]; | ||
113 | if(change == 0) // what? | ||
114 | return; | ||
115 | if((change & canignore) == 0) | ||
116 | { | ||
117 | double now = Util.GetTimeStamp(); | ||
118 | if (now < m_nextEventTime) | ||
119 | return; | ||
120 | m_nextEventTime = now + m_minEventDelay; | ||
121 | } | ||
122 | break; | ||
123 | } | ||
124 | default: | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
89 | // Only so many of each event type allowed to queue. | 129 | // Only so many of each event type allowed to queue. |
90 | if((uint)evc < (uint)m_EventCounts.Length) | 130 | if((uint)evc < (uint)m_EventCounts.Length) |
91 | { | 131 | { |
@@ -124,10 +164,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine | |||
124 | for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) | 164 | for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) |
125 | { | 165 | { |
126 | EventParams evt2 = lln2.Value; | 166 | EventParams evt2 = lln2.Value; |
127 | ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), | 167 | ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt2.EventName); |
128 | evt2.EventName); | 168 | if((evc2 != ScriptEventCode.state_entry) && (evc2 != ScriptEventCode.attach)) |
129 | if((evc2 != ScriptEventCode.state_entry) && | ||
130 | (evc2 != ScriptEventCode.attach)) | ||
131 | break; | 169 | break; |
132 | } | 170 | } |
133 | if(lln2 == null) | 171 | if(lln2 == null) |
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 0438673..22748cc 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs | |||
@@ -757,6 +757,14 @@ namespace OpenSim.Services.LLLoginService | |||
757 | } | 757 | } |
758 | } | 758 | } |
759 | } | 759 | } |
760 | |||
761 | //find a exact match | ||
762 | foreach(GridRegion r in regions) | ||
763 | { | ||
764 | if(string.Equals(regionName, r.RegionName, StringComparison.InvariantCultureIgnoreCase)) | ||
765 | return r; | ||
766 | } | ||
767 | // else, whatever | ||
760 | return regions[0]; | 768 | return regions[0]; |
761 | } | 769 | } |
762 | else | 770 | else |
diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index b7ddd0b..02edd6c 100755 --- a/bin/OpenMetaverse.dll +++ b/bin/OpenMetaverse.dll | |||
Binary files differ | |||
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 3a80dbe..cede84d 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -661,6 +661,25 @@ | |||
661 | ; many simultaneous requests, default is 30 and is currently applied only to assets | 661 | ; many simultaneous requests, default is 30 and is currently applied only to assets |
662 | ;MaxRequestConcurrency = 30 | 662 | ;MaxRequestConcurrency = 30 |
663 | 663 | ||
664 | [ScriptsHttpRequestModule] | ||
665 | ; options for llHttpRequest | ||
666 | |||
667 | ; max number of concurrent connections per instance (all scenes), default 8 | ||
668 | ; MaxPoolThreads = 8 | ||
669 | |||
670 | ; max requests per second for all scripts on a prim, default 1 | ||
671 | ;PrimRequestsPerSec = 1.0 | ||
672 | ; initial unthrottled burst for all scripts on a prim, default 3 | ||
673 | ;PrimRequestsBurst = 3.0 | ||
674 | |||
675 | ; max requests per second for the objects owner (per instance), default 25 | ||
676 | ;PrimOwnerRequestsPerSec = 25.0 | ||
677 | ; initial unthrottled burst for the objects owner (per instance), default 5 | ||
678 | ;PrimOwnerRequestsBurst = 5.0 | ||
679 | |||
680 | ; requests timeout in miliseconds, range 200 to 60000, default 30000 | ||
681 | ;RequestsTimeOut = 30000 | ||
682 | |||
664 | [AccessControl] | 683 | [AccessControl] |
665 | ; Viewer-based access control. |-separated list of allowed viewers. | 684 | ; Viewer-based access control. |-separated list of allowed viewers. |
666 | ; AllowedClients = "" | 685 | ; AllowedClients = "" |
@@ -728,17 +747,6 @@ | |||
728 | ;texture_default = 18500 | 747 | ;texture_default = 18500 |
729 | ;asset_default = 10500 | 748 | ;asset_default = 10500 |
730 | 749 | ||
731 | ; Configures how ObjectUpdates are aggregated. These numbers | ||
732 | ; do not literally mean how many updates will be put in each | ||
733 | ; packet that goes over the wire, as packets are | ||
734 | ; automatically split on a 1400 byte boundary. These control | ||
735 | ; the balance between responsiveness of interest list updates | ||
736 | ; and total throughput. Higher numbers will ensure more full- | ||
737 | ; sized packets and faster sending of data, but more delay in | ||
738 | ; updating interest lists | ||
739 | ; | ||
740 | ;PrimUpdatesPerCallback = 100 | ||
741 | |||
742 | ; TextureSendLimit determines how many packets will be put on | 750 | ; TextureSendLimit determines how many packets will be put on |
743 | ; the outgoing queue each cycle. Like the settings above, this | 751 | ; the outgoing queue each cycle. Like the settings above, this |
744 | ; is a balance between responsiveness to priority updates and | 752 | ; is a balance between responsiveness to priority updates and |
@@ -748,16 +756,6 @@ | |||
748 | ; | 756 | ; |
749 | ;TextureSendLimit = 20 | 757 | ;TextureSendLimit = 20 |
750 | 758 | ||
751 | ; CannibalizeTextureRate allows bandwidth to be moved from the | ||
752 | ; UDP texture throttle to the task throttle. Since most viewers | ||
753 | ; use HTTP textures, this provides a means of using what is largely | ||
754 | ; unused bandwidth in the total throttle. The value is the proportion | ||
755 | ; of the texture rate to move to the task queue. It must be between | ||
756 | ; 0.0 (none of the bandwidth is cannibalized) and 0.9 (90% of the | ||
757 | ; bandwidth is grabbed) | ||
758 | ; | ||
759 | ; CannibalizeTextureRate = 0.5 | ||
760 | |||
761 | ; Quash and remove any light properties from attachments not on the | 759 | ; Quash and remove any light properties from attachments not on the |
762 | ; hands. This allows flashlights and lanterns to function, but kills | 760 | ; hands. This allows flashlights and lanterns to function, but kills |
763 | ; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps | 761 | ; silly vanity "Facelights" dead. Sorry, head mounted miner's lamps |
@@ -802,6 +800,7 @@ | |||
802 | Cap_GetTexture = "localhost" | 800 | Cap_GetTexture = "localhost" |
803 | Cap_GetMesh = "localhost" | 801 | Cap_GetMesh = "localhost" |
804 | Cap_GetMesh2 = "localhost" | 802 | Cap_GetMesh2 = "localhost" |
803 | ; Cap_GetAsset = "localhost" DO not ucoment this line. Some popular viewers still dont do it right for opensim. Here to easy testing | ||
805 | Cap_GetObjectCost = "" | 804 | Cap_GetObjectCost = "" |
806 | Cap_GetObjectPhysicsData = "" | 805 | Cap_GetObjectPhysicsData = "" |
807 | Cap_GroupProposalBallot = "" | 806 | Cap_GroupProposalBallot = "" |
diff --git a/bin/ScriptSyntax.xml b/bin/ScriptSyntax.xml index 862a66d..8f2f6002 100644 --- a/bin/ScriptSyntax.xml +++ b/bin/ScriptSyntax.xml | |||
@@ -1,4 +1,4 @@ | |||
1 | a0b4b514-3c14-6b98-ca98-e18a79e9792f | 1 | 20392e48-fad2-094e-bc5b-cda003a1e940 |
2 | <llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer> | 2 | <llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer> |
3 | <key>controls</key> | 3 | <key>controls</key> |
4 | <map> | 4 | <map> |
@@ -1513,7 +1513,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
1513 | </map> | 1513 | </map> |
1514 | <key>OS_APIVERSION</key><map> | 1514 | <key>OS_APIVERSION</key><map> |
1515 | <key>type</key><string>integer</string> | 1515 | <key>type</key><string>integer</string> |
1516 | <key>value</key><string>2</string> | 1516 | <key>value</key><string>3</string> |
1517 | </map> | 1517 | </map> |
1518 | <key>OS_ATTACH_MSG_ALL</key><map> | 1518 | <key>OS_ATTACH_MSG_ALL</key><map> |
1519 | <key>type</key><string>integer</string> | 1519 | <key>type</key><string>integer</string> |
@@ -6114,34 +6114,34 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6114 | <map> | 6114 | <map> |
6115 | <key>return</key><string>integer</string> | 6115 | <key>return</key><string>integer</string> |
6116 | <key>arguments</key><array> | 6116 | <key>arguments</key><array> |
6117 | <map><key>va</key><map><key>type</key><string>vector</string></map></map> | 6117 | <map><key>a</key><map><key>type</key><string>float</string></map></map> |
6118 | <map><key>vb</key><map><key>type</key><string>vector</string></map></map> | 6118 | <map><key>b</key><map><key>type</key><string>float</string></map></map> |
6119 | <map><key>margin</key><map><key>type</key><string>float</string></map></map> | ||
6120 | </array> | 6119 | </array> |
6121 | </map> | 6120 | </map> |
6122 | <key>osApproxEquals</key> | 6121 | <key>osApproxEquals</key> |
6123 | <map> | 6122 | <map> |
6124 | <key>return</key><string>integer</string> | 6123 | <key>return</key><string>integer</string> |
6125 | <key>arguments</key><array> | 6124 | <key>arguments</key><array> |
6126 | <map><key>va</key><map><key>type</key><string>vector</string></map></map> | 6125 | <map><key>a</key><map><key>type</key><string>float</string></map></map> |
6127 | <map><key>vb</key><map><key>type</key><string>vector</string></map></map> | 6126 | <map><key>b</key><map><key>type</key><string>float</string></map></map> |
6127 | <map><key>margin</key><map><key>type</key><string>float</string></map></map> | ||
6128 | </array> | 6128 | </array> |
6129 | </map> | 6129 | </map> |
6130 | <key>osApproxEquals</key> | 6130 | <key>osApproxEquals</key> |
6131 | <map> | 6131 | <map> |
6132 | <key>return</key><string>integer</string> | 6132 | <key>return</key><string>integer</string> |
6133 | <key>arguments</key><array> | 6133 | <key>arguments</key><array> |
6134 | <map><key>a</key><map><key>type</key><string>float</string></map></map> | 6134 | <map><key>ra</key><map><key>type</key><string>rotation</string></map></map> |
6135 | <map><key>b</key><map><key>type</key><string>float</string></map></map> | 6135 | <map><key>rb</key><map><key>type</key><string>rotation</string></map></map> |
6136 | <map><key>margin</key><map><key>type</key><string>float</string></map></map> | ||
6137 | </array> | 6136 | </array> |
6138 | </map> | 6137 | </map> |
6139 | <key>osApproxEquals</key> | 6138 | <key>osApproxEquals</key> |
6140 | <map> | 6139 | <map> |
6141 | <key>return</key><string>integer</string> | 6140 | <key>return</key><string>integer</string> |
6142 | <key>arguments</key><array> | 6141 | <key>arguments</key><array> |
6143 | <map><key>a</key><map><key>type</key><string>float</string></map></map> | 6142 | <map><key>va</key><map><key>type</key><string>vector</string></map></map> |
6144 | <map><key>b</key><map><key>type</key><string>float</string></map></map> | 6143 | <map><key>vb</key><map><key>type</key><string>vector</string></map></map> |
6144 | <map><key>margin</key><map><key>type</key><string>float</string></map></map> | ||
6145 | </array> | 6145 | </array> |
6146 | </map> | 6146 | </map> |
6147 | <key>osApproxEquals</key> | 6147 | <key>osApproxEquals</key> |
@@ -6157,8 +6157,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6157 | <map> | 6157 | <map> |
6158 | <key>return</key><string>integer</string> | 6158 | <key>return</key><string>integer</string> |
6159 | <key>arguments</key><array> | 6159 | <key>arguments</key><array> |
6160 | <map><key>ra</key><map><key>type</key><string>rotation</string></map></map> | 6160 | <map><key>va</key><map><key>type</key><string>vector</string></map></map> |
6161 | <map><key>rb</key><map><key>type</key><string>rotation</string></map></map> | 6161 | <map><key>vb</key><map><key>type</key><string>vector</string></map></map> |
6162 | </array> | 6162 | </array> |
6163 | </map> | 6163 | </map> |
6164 | <key>osAvatarName2Key</key> | 6164 | <key>osAvatarName2Key</key> |
@@ -6186,14 +6186,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6186 | <key>osCauseDamage</key> | 6186 | <key>osCauseDamage</key> |
6187 | <map> | 6187 | <map> |
6188 | <key>arguments</key><array> | 6188 | <key>arguments</key><array> |
6189 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 6189 | <map><key>avatar</key><map><key>type</key><string>key</string></map></map> |
6190 | <map><key>damage</key><map><key>type</key><string>float</string></map></map> | 6190 | <map><key>damage</key><map><key>type</key><string>float</string></map></map> |
6191 | </array> | 6191 | </array> |
6192 | </map> | 6192 | </map> |
6193 | <key>osCauseHealing</key> | 6193 | <key>osCauseHealing</key> |
6194 | <map> | 6194 | <map> |
6195 | <key>arguments</key><array> | 6195 | <key>arguments</key><array> |
6196 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 6196 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> |
6197 | <map><key>healing</key><map><key>type</key><string>float</string></map></map> | 6197 | <map><key>healing</key><map><key>type</key><string>float</string></map></map> |
6198 | </array> | 6198 | </array> |
6199 | </map> | 6199 | </map> |
@@ -6284,8 +6284,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6284 | <key>return</key><string>string</string> | 6284 | <key>return</key><string>string</string> |
6285 | <key>arguments</key><array> | 6285 | <key>arguments</key><array> |
6286 | <map><key>drawList</key><map><key>type</key><string>string</string></map></map> | 6286 | <map><key>drawList</key><map><key>type</key><string>string</string></map></map> |
6287 | <map><key>startX</key><map><key>type</key><string>integer</string></map></map> | ||
6288 | <map><key>startY</key><map><key>type</key><string>integer</string></map></map> | ||
6289 | <map><key>endX</key><map><key>type</key><string>integer</string></map></map> | 6287 | <map><key>endX</key><map><key>type</key><string>integer</string></map></map> |
6290 | <map><key>endY</key><map><key>type</key><string>integer</string></map></map> | 6288 | <map><key>endY</key><map><key>type</key><string>integer</string></map></map> |
6291 | </array> | 6289 | </array> |
@@ -6295,6 +6293,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6295 | <key>return</key><string>string</string> | 6293 | <key>return</key><string>string</string> |
6296 | <key>arguments</key><array> | 6294 | <key>arguments</key><array> |
6297 | <map><key>drawList</key><map><key>type</key><string>string</string></map></map> | 6295 | <map><key>drawList</key><map><key>type</key><string>string</string></map></map> |
6296 | <map><key>startX</key><map><key>type</key><string>integer</string></map></map> | ||
6297 | <map><key>startY</key><map><key>type</key><string>integer</string></map></map> | ||
6298 | <map><key>endX</key><map><key>type</key><string>integer</string></map></map> | 6298 | <map><key>endX</key><map><key>type</key><string>integer</string></map></map> |
6299 | <map><key>endY</key><map><key>type</key><string>integer</string></map></map> | 6299 | <map><key>endY</key><map><key>type</key><string>integer</string></map></map> |
6300 | </array> | 6300 | </array> |
@@ -6539,14 +6539,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6539 | <map> | 6539 | <map> |
6540 | <key>return</key><string>float</string> | 6540 | <key>return</key><string>float</string> |
6541 | <key>arguments</key><array> | 6541 | <key>arguments</key><array> |
6542 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 6542 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> |
6543 | </array> | 6543 | </array> |
6544 | </map> | 6544 | </map> |
6545 | <key>osGetHealth</key> | 6545 | <key>osGetHealth</key> |
6546 | <map> | 6546 | <map> |
6547 | <key>return</key><string>float</string> | 6547 | <key>return</key><string>float</string> |
6548 | <key>arguments</key><array> | 6548 | <key>arguments</key><array> |
6549 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 6549 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> |
6550 | </array> | 6550 | </array> |
6551 | </map> | 6551 | </map> |
6552 | <key>osGetInertiaData</key> | 6552 | <key>osGetInertiaData</key> |
@@ -6558,9 +6558,28 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6558 | <map> | 6558 | <map> |
6559 | <key>return</key><string>string</string> | 6559 | <key>return</key><string>string</string> |
6560 | <key>arguments</key><array> | 6560 | <key>arguments</key><array> |
6561 | <map><key>item</key><map><key>type</key><string>string</string></map></map> | 6561 | <map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map> |
6562 | </array> | ||
6563 | </map> | ||
6564 | <key>osGetInventoryLastOwner</key> | ||
6565 | <map> | ||
6566 | <key>return</key><string>key</string> | ||
6567 | <key>arguments</key><array> | ||
6568 | <map><key>itemNameOrId</key><map><key>type</key><string>string</string></map></map> | ||
6562 | </array> | 6569 | </array> |
6563 | </map> | 6570 | </map> |
6571 | <key>osGetInventoryName</key> | ||
6572 | <map> | ||
6573 | <key>return</key><string>string</string> | ||
6574 | <key>arguments</key><array> | ||
6575 | <map><key>itemId</key><map><key>type</key><string>key</string></map></map> | ||
6576 | </array> | ||
6577 | </map> | ||
6578 | <key>osGetLastChangedEventKey</key> | ||
6579 | <map> | ||
6580 | <key>return</key><string>key</string> | ||
6581 | <key>arguments</key><undef/> | ||
6582 | </map> | ||
6564 | <key>osGetLinkNumber</key> | 6583 | <key>osGetLinkNumber</key> |
6565 | <map> | 6584 | <map> |
6566 | <key>return</key><string>integer</string> | 6585 | <key>return</key><string>integer</string> |
@@ -6735,6 +6754,13 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6735 | <map><key>alert</key><map><key>type</key><string>string</string></map></map> | 6754 | <map><key>alert</key><map><key>type</key><string>string</string></map></map> |
6736 | </array> | 6755 | </array> |
6737 | </map> | 6756 | </map> |
6757 | <key>osKickAvatar</key> | ||
6758 | <map> | ||
6759 | <key>arguments</key><array> | ||
6760 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> | ||
6761 | <map><key>alert</key><map><key>type</key><string>string</string></map></map> | ||
6762 | </array> | ||
6763 | </map> | ||
6738 | <key>osLoadedCreationDate</key> | 6764 | <key>osLoadedCreationDate</key> |
6739 | <map> | 6765 | <map> |
6740 | <key>return</key><string>string</string> | 6766 | <key>return</key><string>string</string> |
@@ -6839,7 +6865,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6839 | <map><key>name</key><map><key>type</key><string>string</string></map></map> | 6865 | <map><key>name</key><map><key>type</key><string>string</string></map></map> |
6840 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 6866 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
6841 | <map><key>notecard</key><map><key>type</key><string>string</string></map></map> | 6867 | <map><key>notecard</key><map><key>type</key><string>string</string></map></map> |
6842 | <map><key>options</key><map><key>type</key><string>integer</string></map></map> | ||
6843 | </array> | 6868 | </array> |
6844 | </map> | 6869 | </map> |
6845 | <key>osNpcCreate</key> | 6870 | <key>osNpcCreate</key> |
@@ -6850,6 +6875,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
6850 | <map><key>name</key><map><key>type</key><string>string</string></map></map> | 6875 | <map><key>name</key><map><key>type</key><string>string</string></map></map> |
6851 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 6876 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
6852 | <map><key>notecard</key><map><key>type</key><string>string</string></map></map> | 6877 | <map><key>notecard</key><map><key>type</key><string>string</string></map></map> |
6878 | <map><key>options</key><map><key>type</key><string>integer</string></map></map> | ||
6853 | </array> | 6879 | </array> |
6854 | </map> | 6880 | </map> |
6855 | <key>osNpcGetOwner</key> | 6881 | <key>osNpcGetOwner</key> |
@@ -7089,7 +7115,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7089 | <key>return</key><string>integer</string> | 7115 | <key>return</key><string>integer</string> |
7090 | <key>arguments</key><array> | 7116 | <key>arguments</key><array> |
7091 | <map><key>seconds</key><map><key>type</key><string>float</string></map></map> | 7117 | <map><key>seconds</key><map><key>type</key><string>float</string></map></map> |
7092 | <map><key>msg</key><map><key>type</key><string>string</string></map></map> | ||
7093 | </array> | 7118 | </array> |
7094 | </map> | 7119 | </map> |
7095 | <key>osRegionRestart</key> | 7120 | <key>osRegionRestart</key> |
@@ -7097,6 +7122,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7097 | <key>return</key><string>integer</string> | 7122 | <key>return</key><string>integer</string> |
7098 | <key>arguments</key><array> | 7123 | <key>arguments</key><array> |
7099 | <map><key>seconds</key><map><key>type</key><string>float</string></map></map> | 7124 | <map><key>seconds</key><map><key>type</key><string>float</string></map></map> |
7125 | <map><key>msg</key><map><key>type</key><string>string</string></map></map> | ||
7100 | </array> | 7126 | </array> |
7101 | </map> | 7127 | </map> |
7102 | <key>osReplaceString</key> | 7128 | <key>osReplaceString</key> |
@@ -7199,14 +7225,14 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7199 | <key>osSetHealRate</key> | 7225 | <key>osSetHealRate</key> |
7200 | <map> | 7226 | <map> |
7201 | <key>arguments</key><array> | 7227 | <key>arguments</key><array> |
7202 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 7228 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> |
7203 | <map><key>health</key><map><key>type</key><string>float</string></map></map> | 7229 | <map><key>health</key><map><key>type</key><string>float</string></map></map> |
7204 | </array> | 7230 | </array> |
7205 | </map> | 7231 | </map> |
7206 | <key>osSetHealth</key> | 7232 | <key>osSetHealth</key> |
7207 | <map> | 7233 | <map> |
7208 | <key>arguments</key><array> | 7234 | <key>arguments</key><array> |
7209 | <map><key>avatar</key><map><key>type</key><string>string</string></map></map> | 7235 | <map><key>agentId</key><map><key>type</key><string>key</string></map></map> |
7210 | <map><key>health</key><map><key>type</key><string>float</string></map></map> | 7236 | <map><key>health</key><map><key>type</key><string>float</string></map></map> |
7211 | </array> | 7237 | </array> |
7212 | </map> | 7238 | </map> |
@@ -7432,6 +7458,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7432 | <key>arguments</key><array> | 7458 | <key>arguments</key><array> |
7433 | <map><key>src</key><map><key>type</key><string>string</string></map></map> | 7459 | <map><key>src</key><map><key>type</key><string>string</string></map></map> |
7434 | <map><key>value</key><map><key>type</key><string>string</string></map></map> | 7460 | <map><key>value</key><map><key>type</key><string>string</string></map></map> |
7461 | <map><key>start</key><map><key>type</key><string>integer</string></map></map> | ||
7462 | <map><key>count</key><map><key>type</key><string>integer</string></map></map> | ||
7435 | <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map> | 7463 | <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map> |
7436 | </array> | 7464 | </array> |
7437 | </map> | 7465 | </map> |
@@ -7441,8 +7469,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7441 | <key>arguments</key><array> | 7469 | <key>arguments</key><array> |
7442 | <map><key>src</key><map><key>type</key><string>string</string></map></map> | 7470 | <map><key>src</key><map><key>type</key><string>string</string></map></map> |
7443 | <map><key>value</key><map><key>type</key><string>string</string></map></map> | 7471 | <map><key>value</key><map><key>type</key><string>string</string></map></map> |
7444 | <map><key>start</key><map><key>type</key><string>integer</string></map></map> | ||
7445 | <map><key>count</key><map><key>type</key><string>integer</string></map></map> | ||
7446 | <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map> | 7472 | <map><key>ignorecase</key><map><key>type</key><string>integer</string></map></map> |
7447 | </array> | 7473 | </array> |
7448 | </map> | 7474 | </map> |
@@ -7528,7 +7554,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7528 | <map> | 7554 | <map> |
7529 | <key>arguments</key><array> | 7555 | <key>arguments</key><array> |
7530 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> | 7556 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> |
7531 | <map><key>regionName</key><map><key>type</key><string>string</string></map></map> | 7557 | <map><key>regionX</key><map><key>type</key><string>integer</string></map></map> |
7558 | <map><key>regionY</key><map><key>type</key><string>integer</string></map></map> | ||
7532 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 7559 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
7533 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> | 7560 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> |
7534 | </array> | 7561 | </array> |
@@ -7537,8 +7564,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7537 | <map> | 7564 | <map> |
7538 | <key>arguments</key><array> | 7565 | <key>arguments</key><array> |
7539 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> | 7566 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> |
7540 | <map><key>regionX</key><map><key>type</key><string>integer</string></map></map> | ||
7541 | <map><key>regionY</key><map><key>type</key><string>integer</string></map></map> | ||
7542 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 7567 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
7543 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> | 7568 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> |
7544 | </array> | 7569 | </array> |
@@ -7547,6 +7572,7 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7547 | <map> | 7572 | <map> |
7548 | <key>arguments</key><array> | 7573 | <key>arguments</key><array> |
7549 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> | 7574 | <map><key>agent</key><map><key>type</key><string>string</string></map></map> |
7575 | <map><key>regionName</key><map><key>type</key><string>string</string></map></map> | ||
7550 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 7576 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
7551 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> | 7577 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> |
7552 | </array> | 7578 | </array> |
@@ -7564,8 +7590,6 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7564 | <key>osTeleportOwner</key> | 7590 | <key>osTeleportOwner</key> |
7565 | <map> | 7591 | <map> |
7566 | <key>arguments</key><array> | 7592 | <key>arguments</key><array> |
7567 | <map><key>regionX</key><map><key>type</key><string>integer</string></map></map> | ||
7568 | <map><key>regionY</key><map><key>type</key><string>integer</string></map></map> | ||
7569 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 7593 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
7570 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> | 7594 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> |
7571 | </array> | 7595 | </array> |
@@ -7581,6 +7605,8 @@ a0b4b514-3c14-6b98-ca98-e18a79e9792f | |||
7581 | <key>osTeleportOwner</key> | 7605 | <key>osTeleportOwner</key> |
7582 | <map> | 7606 | <map> |
7583 | <key>arguments</key><array> | 7607 | <key>arguments</key><array> |
7608 | <map><key>regionX</key><map><key>type</key><string>integer</string></map></map> | ||
7609 | <map><key>regionY</key><map><key>type</key><string>integer</string></map></map> | ||
7584 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> | 7610 | <map><key>position</key><map><key>type</key><string>vector</string></map></map> |
7585 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> | 7611 | <map><key>lookat</key><map><key>type</key><string>vector</string></map></map> |
7586 | </array> | 7612 | </array> |
diff --git a/bin/config-include/osslEnable.ini b/bin/config-include/osslEnable.ini index a96459a..f127b1f 100644 --- a/bin/config-include/osslEnable.ini +++ b/bin/config-include/osslEnable.ini | |||
@@ -155,7 +155,6 @@ | |||
155 | Allow_osForceDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER | 155 | Allow_osForceDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER |
156 | Allow_osGetLinkPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER | 156 | Allow_osGetLinkPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER |
157 | Allow_osGetPhysicsEngineType = true | 157 | Allow_osGetPhysicsEngineType = true |
158 | Allow_osGetPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER | ||
159 | Allow_osGetRegionMapTexture = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER | 158 | Allow_osGetRegionMapTexture = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER |
160 | Allow_osGetScriptEngineName = true | 159 | Allow_osGetScriptEngineName = true |
161 | Allow_osGetSimulatorVersion = true | 160 | Allow_osGetSimulatorVersion = true |
@@ -185,7 +184,6 @@ | |||
185 | Allow_osParcelSubdivide = ESTATE_MANAGER,ESTATE_OWNER | 184 | Allow_osParcelSubdivide = ESTATE_MANAGER,ESTATE_OWNER |
186 | Allow_osRegionRestart = ESTATE_MANAGER,ESTATE_OWNER | 185 | Allow_osRegionRestart = ESTATE_MANAGER,ESTATE_OWNER |
187 | Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER | 186 | Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER |
188 | Allow_osSetPrimitiveParams = false | ||
189 | Allow_osSetProjectionParams = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER | 187 | Allow_osSetProjectionParams = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER |
190 | Allow_osSetRegionWaterHeight = ESTATE_MANAGER,ESTATE_OWNER | 188 | Allow_osSetRegionWaterHeight = ESTATE_MANAGER,ESTATE_OWNER |
191 | Allow_osSetStateEvents = false ; deprecated | 189 | Allow_osSetStateEvents = false ; deprecated |
@@ -250,6 +248,7 @@ | |||
250 | ; Allow_osGetLinkNumber = true | 248 | ; Allow_osGetLinkNumber = true |
251 | ; Allow_osGetMapTexture = true | 249 | ; Allow_osGetMapTexture = true |
252 | ; Allow_osGetPhysicsEngineName = true | 250 | ; Allow_osGetPhysicsEngineName = true |
251 | ; Allow_osGetPrimitiveParams = true | ||
253 | ; Allow_osGetRegionSize = true | 252 | ; Allow_osGetRegionSize = true |
254 | ; Allow_osGetSunParam = true | 253 | ; Allow_osGetSunParam = true |
255 | ; Allow_osGetTerrainHeight = true | 254 | ; Allow_osGetTerrainHeight = true |
@@ -275,6 +274,7 @@ | |||
275 | ; Allow_osSetPenCap = true | 274 | ; Allow_osSetPenCap = true |
276 | ; Allow_osSetPenColor = true | 275 | ; Allow_osSetPenColor = true |
277 | ; Allow_osSetPenSize = true | 276 | ; Allow_osSetPenSize = true |
277 | ; Allow_osSetPrimitiveParams = true | ||
278 | ; Allow_osSetSoundRadius = true | 278 | ; Allow_osSetSoundRadius = true |
279 | ; Allow_osStopSound = true | 279 | ; Allow_osStopSound = true |
280 | ; Allow_osStringSubString = true | 280 | ; Allow_osStringSubString = true |