aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/IClientNetworkServer.cs15
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs139
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs23
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs106
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs27
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs26
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs44
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs104
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs582
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs96
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs340
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs72
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs4
18 files changed, 1160 insertions, 441 deletions
diff --git a/OpenSim/Region/ClientStack/IClientNetworkServer.cs b/OpenSim/Region/ClientStack/IClientNetworkServer.cs
index 54a441b..bb7e6d0 100644
--- a/OpenSim/Region/ClientStack/IClientNetworkServer.cs
+++ b/OpenSim/Region/ClientStack/IClientNetworkServer.cs
@@ -38,11 +38,22 @@ namespace OpenSim.Region.ClientStack
38 IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, 38 IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource,
39 AgentCircuitManager authenticateClass); 39 AgentCircuitManager authenticateClass);
40 40
41 void NetworkStop();
42 bool HandlesRegion(Location x); 41 bool HandlesRegion(Location x);
43 void AddScene(IScene x);
44 42
43 /// <summary>
44 /// Add the given scene to be handled by this IClientNetworkServer.
45 /// </summary>
46 /// <param name='scene'></param>
47 void AddScene(IScene scene);
48
49 /// <summary>
50 /// Start sending and receiving data.
51 /// </summary>
45 void Start(); 52 void Start();
53
54 /// <summary>
55 /// Stop sending and receiving data.
56 /// </summary>
46 void Stop(); 57 void Stop();
47 } 58 }
48} 59}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
new file mode 100644
index 0000000..9f2aed0
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
@@ -0,0 +1,139 @@
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
28using System;
29using System.Collections;
30using System.Collections.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Services.Interfaces;
47using Caps = OpenSim.Framework.Capabilities.Caps;
48using OpenSim.Capabilities.Handlers;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AvatarPickerSearchModule")]
54 public class AvatarPickerSearchModule : INonSharedRegionModule
55 {
56 private static readonly ILog m_log =
57 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58
59 private Scene m_scene;
60 private IPeople m_People;
61 private bool m_Enabled = false;
62
63 private string m_URL;
64
65 #region ISharedRegionModule Members
66
67 public void Initialise(IConfigSource source)
68 {
69 IConfig config = source.Configs["ClientStack.LindenCaps"];
70 if (config == null)
71 return;
72
73 m_URL = config.GetString("Cap_AvatarPickerSearch", string.Empty);
74 // Cap doesn't exist
75 if (m_URL != string.Empty)
76 m_Enabled = true;
77 }
78
79 public void AddRegion(Scene s)
80 {
81 if (!m_Enabled)
82 return;
83
84 m_scene = s;
85 }
86
87 public void RemoveRegion(Scene s)
88 {
89 if (!m_Enabled)
90 return;
91
92 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
93 m_scene = null;
94 }
95
96 public void RegionLoaded(Scene s)
97 {
98 if (!m_Enabled)
99 return;
100
101 m_People = m_scene.RequestModuleInterface<IPeople>();
102 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
103 }
104
105 public void PostInitialise()
106 {
107 }
108
109 public void Close() { }
110
111 public string Name { get { return "AvatarPickerSearchModule"; } }
112
113 public Type ReplaceableInterface
114 {
115 get { return null; }
116 }
117
118 #endregion
119
120 public void RegisterCaps(UUID agentID, Caps caps)
121 {
122 UUID capID = UUID.Random();
123
124 if (m_URL == "localhost")
125 {
126 m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
127 caps.RegisterHandler(
128 "AvatarPickerSearch",
129 new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name"));
130 }
131 else
132 {
133 // m_log.DebugFormat("[AVATAR PICKER SEARCH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
134 caps.RegisterHandler("AvatarPickerSearch", m_URL);
135 }
136 }
137
138 }
139}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 8241e07..762e22a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -282,13 +282,19 @@ namespace OpenSim.Region.ClientStack.Linden
282 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 282 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
283 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 283 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
284 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 284 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
285 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData); 285
286 IRequestHandler getObjectPhysicsDataHandler
287 = new RestStreamHandler(
288 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
286 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); 289 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
287 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost); 290 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
288 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler); 291 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
289 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected); 292 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
290 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler); 293 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
291 IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation); 294
295 IRequestHandler UpdateAgentInformationHandler
296 = new RestStreamHandler(
297 "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null);
292 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); 298 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
293 299
294 m_HostCapsObj.RegisterHandler( 300 m_HostCapsObj.RegisterHandler(
@@ -361,18 +367,7 @@ namespace OpenSim.Region.ClientStack.Linden
361 foreach (OSD c in capsRequested) 367 foreach (OSD c in capsRequested)
362 validCaps.Add(c.AsString()); 368 validCaps.Add(c.AsString());
363 369
364 Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true, validCaps); 370 string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps));
365
366 // Add the external too
367 foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
368 {
369 if (!validCaps.Contains(kvp.Key))
370 continue;
371
372 caps[kvp.Key] = kvp.Value;
373 }
374
375 string result = LLSDHelpers.SerialiseLLSDReply(caps);
376 371
377 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result); 372 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
378 373
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index eb40eb1..4272375 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -65,6 +65,13 @@ namespace OpenSim.Region.ClientStack.Linden
65 /// </value> 65 /// </value>
66 public int DebugLevel { get; set; } 66 public int DebugLevel { get; set; }
67 67
68 // Viewer post requests timeout in 60 secs
69 // https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
70 //
71 private const int VIEWER_TIMEOUT = 60 * 1000;
72 // Just to be safe, we work on a 10 sec shorter cycle
73 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
74
68 protected Scene m_scene; 75 protected Scene m_scene;
69 76
70 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 77 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
@@ -84,7 +91,6 @@ namespace OpenSim.Region.ClientStack.Linden
84 scene.RegisterModuleInterface<IEventQueue>(this); 91 scene.RegisterModuleInterface<IEventQueue>(this);
85 92
86 scene.EventManager.OnClientClosed += ClientClosed; 93 scene.EventManager.OnClientClosed += ClientClosed;
87 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
88 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 94 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
89 95
90 MainConsole.Instance.Commands.AddCommand( 96 MainConsole.Instance.Commands.AddCommand(
@@ -113,7 +119,6 @@ namespace OpenSim.Region.ClientStack.Linden
113 return; 119 return;
114 120
115 scene.EventManager.OnClientClosed -= ClientClosed; 121 scene.EventManager.OnClientClosed -= ClientClosed;
116 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
117 scene.EventManager.OnRegisterCaps -= OnRegisterCaps; 122 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
118 123
119 scene.UnregisterModuleInterface<IEventQueue>(this); 124 scene.UnregisterModuleInterface<IEventQueue>(this);
@@ -182,14 +187,12 @@ namespace OpenSim.Region.ClientStack.Linden
182 { 187 {
183 if (!queues.ContainsKey(agentId)) 188 if (!queues.ContainsKey(agentId))
184 { 189 {
185 /*
186 m_log.DebugFormat( 190 m_log.DebugFormat(
187 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", 191 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
188 agentId, m_scene.RegionInfo.RegionName); 192 agentId, m_scene.RegionInfo.RegionName);
189 */
190 queues[agentId] = new Queue<OSD>(); 193 queues[agentId] = new Queue<OSD>();
191 } 194 }
192 195
193 return queues[agentId]; 196 return queues[agentId];
194 } 197 }
195 } 198 }
@@ -221,8 +224,12 @@ namespace OpenSim.Region.ClientStack.Linden
221 { 224 {
222 Queue<OSD> queue = GetQueue(avatarID); 225 Queue<OSD> queue = GetQueue(avatarID);
223 if (queue != null) 226 if (queue != null)
227 {
224 lock (queue) 228 lock (queue)
225 queue.Enqueue(ev); 229 queue.Enqueue(ev);
230 }
231 else
232 m_log.WarnFormat("[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
226 } 233 }
227 catch (NullReferenceException e) 234 catch (NullReferenceException e)
228 { 235 {
@@ -237,44 +244,14 @@ namespace OpenSim.Region.ClientStack.Linden
237 244
238 private void ClientClosed(UUID agentID, Scene scene) 245 private void ClientClosed(UUID agentID, Scene scene)
239 { 246 {
240// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 247 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
241
242 int count = 0;
243 while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
244 {
245 Thread.Sleep(1000);
246 }
247 248
248 lock (queues) 249 lock (queues)
249 {
250 queues.Remove(agentID); 250 queues.Remove(agentID);
251 }
252 251
253 List<UUID> removeitems = new List<UUID>(); 252 List<UUID> removeitems = new List<UUID>();
254 lock (m_AvatarQueueUUIDMapping) 253 lock (m_AvatarQueueUUIDMapping)
255 { 254 m_AvatarQueueUUIDMapping.Remove(agentID);
256 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
257 {
258// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
259 if (ky == agentID)
260 {
261 removeitems.Add(ky);
262 }
263 }
264
265 foreach (UUID ky in removeitems)
266 {
267 UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
268 m_AvatarQueueUUIDMapping.Remove(ky);
269
270 string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
271 MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
272
273// m_log.DebugFormat(
274// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
275// eqgPath, agentID, m_scene.RegionInfo.RegionName);
276 }
277 }
278 255
279 UUID searchval = UUID.Zero; 256 UUID searchval = UUID.Zero;
280 257
@@ -295,19 +272,9 @@ namespace OpenSim.Region.ClientStack.Linden
295 foreach (UUID ky in removeitems) 272 foreach (UUID ky in removeitems)
296 m_QueueUUIDAvatarMapping.Remove(ky); 273 m_QueueUUIDAvatarMapping.Remove(ky);
297 } 274 }
298 }
299 275
300 private void MakeChildAgent(ScenePresence avatar) 276 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
301 { 277
302 //m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
303 //lock (m_ids)
304 // {
305 //if (m_ids.ContainsKey(avatar.UUID))
306 //{
307 // close the event queue.
308 //m_ids[avatar.UUID] = -1;
309 //}
310 //}
311 } 278 }
312 279
313 /// <summary> 280 /// <summary>
@@ -359,28 +326,9 @@ namespace OpenSim.Region.ClientStack.Linden
359 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); 326 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
360 } 327 }
361 328
362 string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); 329 caps.RegisterPollHandler(
363 330 "EventQueueGet",
364 // Register this as a caps handler 331 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
365 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
366 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
367 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
368 // really it should be possible to directly register the poll handler as a capability.
369 caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
370// delegate(Hashtable m_dhttpMethod)
371// {
372// return ProcessQueue(m_dhttpMethod, agentID, caps);
373// }));
374
375 // This will persist this beyond the expiry of the caps handlers
376 // TODO: Add EventQueueGet name/description for diagnostics
377 MainServer.Instance.AddPollServiceHTTPHandler(
378 eventQueueGetPath,
379 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 40000));
380
381// m_log.DebugFormat(
382// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
383// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
384 332
385 Random rnd = new Random(Environment.TickCount); 333 Random rnd = new Random(Environment.TickCount);
386 lock (m_ids) 334 lock (m_ids)
@@ -398,7 +346,10 @@ namespace OpenSim.Region.ClientStack.Linden
398 Queue<OSD> queue = GetQueue(agentID); 346 Queue<OSD> queue = GetQueue(agentID);
399 if (queue != null) 347 if (queue != null)
400 lock (queue) 348 lock (queue)
349 {
350 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
401 return queue.Count > 0; 351 return queue.Count > 0;
352 }
402 353
403 return false; 354 return false;
404 } 355 }
@@ -421,9 +372,14 @@ namespace OpenSim.Region.ClientStack.Linden
421 public Hashtable GetEvents(UUID requestID, UUID pAgentId) 372 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
422 { 373 {
423 if (DebugLevel >= 2) 374 if (DebugLevel >= 2)
424 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); 375 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
376
377 Queue<OSD> queue = GetQueue(pAgentId);
378 if (queue == null)
379 {
380 return NoEvents(requestID, pAgentId);
381 }
425 382
426 Queue<OSD> queue = TryGetQueue(pAgentId);
427 OSD element; 383 OSD element;
428 lock (queue) 384 lock (queue)
429 { 385 {
@@ -794,12 +750,12 @@ namespace OpenSim.Region.ClientStack.Linden
794 750
795 } 751 }
796 752
797 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 753 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
798 bool isModerator, bool textMute) 754 bool isModerator, bool textMute)
799 { 755 {
800 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 756 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
801 isModerator, textMute); 757 isModerator, textMute);
802 Enqueue(item, toAgent); 758 Enqueue(item, fromAgent);
803 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 759 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
804 } 760 }
805 761
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 6ec1115..7b15284 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -246,8 +246,8 @@ namespace OpenSim.Region.ClientStack.Linden
246 246
247 private Scene m_scene; 247 private Scene m_scene;
248 private MeshCapsDataThrottler m_throttler; 248 private MeshCapsDataThrottler m_throttler;
249 public PollServiceMeshEventArgs(UUID pId, Scene scene) : 249 public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
250 base(null, null, null, null, pId, int.MaxValue) 250 base(null, uri, null, null, null, pId, int.MaxValue)
251 { 251 {
252 m_scene = scene; 252 m_scene = scene;
253 m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); 253 m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId);
@@ -361,7 +361,7 @@ namespace OpenSim.Region.ClientStack.Linden
361 string capUrl = "/CAPS/" + UUID.Random() + "/"; 361 string capUrl = "/CAPS/" + UUID.Random() + "/";
362 362
363 // Register this as a poll service 363 // Register this as a poll service
364 PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(agentID, m_scene); 364 PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
365 365
366 args.Type = PollServiceEventArgs.EventType.Mesh; 366 args.Type = PollServiceEventArgs.EventType.Mesh;
367 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); 367 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index a42c96c..c8e1e83 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -82,6 +82,8 @@ namespace OpenSim.Region.ClientStack.Linden
82 82
83 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); 83 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
84 84
85 private string m_URL;
86
85 #region ISharedRegionModule Members 87 #region ISharedRegionModule Members
86 88
87 public void Initialise(IConfigSource source) 89 public void Initialise(IConfigSource source)
@@ -210,7 +212,7 @@ namespace OpenSim.Region.ClientStack.Linden
210 private Scene m_scene; 212 private Scene m_scene;
211 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); 213 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
212 public PollServiceTextureEventArgs(UUID pId, Scene scene) : 214 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
213 base(null, null, null, null, pId, int.MaxValue) 215 base(null, "", null, null, null, pId, int.MaxValue)
214 { 216 {
215 m_scene = scene; 217 m_scene = scene;
216 // x is request id, y is userid 218 // x is request id, y is userid
@@ -343,13 +345,13 @@ namespace OpenSim.Region.ClientStack.Linden
343 345
344 private void RegisterCaps(UUID agentID, Caps caps) 346 private void RegisterCaps(UUID agentID, Caps caps)
345 { 347 {
346 string capUrl = "/CAPS/" + UUID.Random() + "/"; 348 m_URL = "/CAPS/" + UUID.Random() + "/";
347 349
348 // Register this as a poll service 350 // Register this as a poll service
349 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene); 351 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
350 352
351 args.Type = PollServiceEventArgs.EventType.Texture; 353 args.Type = PollServiceEventArgs.EventType.Texture;
352 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); 354 MainServer.Instance.AddPollServiceHTTPHandler(m_URL, args);
353 355
354 string hostName = m_scene.RegionInfo.ExternalHostName; 356 string hostName = m_scene.RegionInfo.ExternalHostName;
355 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port; 357 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
@@ -361,20 +363,23 @@ namespace OpenSim.Region.ClientStack.Linden
361 port = MainServer.Instance.SSLPort; 363 port = MainServer.Instance.SSLPort;
362 protocol = "https"; 364 protocol = "https";
363 } 365 }
364 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); 366
367 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
368 if (handler != null)
369 handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", m_URL);
370 else
371 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, m_URL));
365 m_pollservices[agentID] = args; 372 m_pollservices[agentID] = args;
366 m_capsDict[agentID] = capUrl; 373 m_capsDict[agentID] = m_URL;
367 } 374 }
368 375
369 private void DeregisterCaps(UUID agentID, Caps caps) 376 private void DeregisterCaps(UUID agentID, Caps caps)
370 { 377 {
371 string capUrl;
372 PollServiceTextureEventArgs args; 378 PollServiceTextureEventArgs args;
373 if (m_capsDict.TryGetValue(agentID, out capUrl)) 379
374 { 380 MainServer.Instance.RemoveHTTPHandler("", m_URL);
375 MainServer.Instance.RemoveHTTPHandler("", capUrl); 381 m_capsDict.Remove(agentID);
376 m_capsDict.Remove(agentID); 382
377 }
378 if (m_pollservices.TryGetValue(agentID, out args)) 383 if (m_pollservices.TryGetValue(agentID, out args))
379 { 384 {
380 m_pollservices.Remove(agentID); 385 m_pollservices.Remove(agentID);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 79d56c4..5196368 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -183,7 +183,7 @@ namespace OpenSim.Region.ClientStack.Linden
183 m_isGod = m_scene.Permissions.IsGod(agentID); 183 m_isGod = m_scene.Permissions.IsGod(agentID);
184 } 184 }
185 185
186 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 186 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
187 { 187 {
188 StreamReader reader = new StreamReader(request); 188 StreamReader reader = new StreamReader(request);
189 string message = reader.ReadToEnd(); 189 string message = reader.ReadToEnd();
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index 7d9f935..e4d8a20 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -68,7 +68,6 @@ namespace OpenSim.Region.ClientStack.Linden
68 /// </summary> 68 /// </summary>
69 private OSDMap m_features = new OSDMap(); 69 private OSDMap m_features = new OSDMap();
70 70
71 private string m_MapImageServerURL = string.Empty;
72 private string m_SearchURL = string.Empty; 71 private string m_SearchURL = string.Empty;
73 private bool m_ExportSupported = false; 72 private bool m_ExportSupported = false;
74 73
@@ -78,15 +77,7 @@ namespace OpenSim.Region.ClientStack.Linden
78 { 77 {
79 IConfig config = source.Configs["SimulatorFeatures"]; 78 IConfig config = source.Configs["SimulatorFeatures"];
80 if (config != null) 79 if (config != null)
81 { 80 {
82 m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
83 if (m_MapImageServerURL != string.Empty)
84 {
85 m_MapImageServerURL = m_MapImageServerURL.Trim();
86 if (!m_MapImageServerURL.EndsWith("/"))
87 m_MapImageServerURL = m_MapImageServerURL + "/";
88 }
89
90 m_SearchURL = config.GetString("SearchServerURI", string.Empty); 81 m_SearchURL = config.GetString("SearchServerURI", string.Empty);
91 82
92 m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported); 83 m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
@@ -149,15 +140,16 @@ namespace OpenSim.Region.ClientStack.Linden
149 m_features["PhysicsShapeTypes"] = typesMap; 140 m_features["PhysicsShapeTypes"] = typesMap;
150 141
151 // Extra information for viewers that want to use it 142 // Extra information for viewers that want to use it
152 OSDMap gridServicesMap = new OSDMap(); 143 // TODO: Take these out of here into their respective modules, like map-server-url
153 if (m_MapImageServerURL != string.Empty) 144 OSDMap extrasMap = new OSDMap();
154 gridServicesMap["map-server-url"] = m_MapImageServerURL;
155 if (m_SearchURL != string.Empty) 145 if (m_SearchURL != string.Empty)
156 gridServicesMap["search"] = m_SearchURL; 146 extrasMap["search-server-url"] = m_SearchURL;
157 m_features["GridServices"] = gridServicesMap;
158
159 if (m_ExportSupported) 147 if (m_ExportSupported)
160 m_features["ExportSupported"] = true; 148 extrasMap["ExportSupported"] = true;
149
150 if (extrasMap.Count > 0)
151 m_features["OpenSimExtras"] = extrasMap;
152
161 } 153 }
162 } 154 }
163 155
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index eca576d..cf95463 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -64,11 +64,18 @@ namespace OpenSim.Region.ClientStack.Linden
64 64
65 private Scene m_scene; 65 private Scene m_scene;
66 private bool m_persistBakedTextures; 66 private bool m_persistBakedTextures;
67 private string m_URL;
67 68
68 private IBakedTextureModule m_BakedTextureModule; 69 private IBakedTextureModule m_BakedTextureModule;
69 70
70 public void Initialise(IConfigSource source) 71 public void Initialise(IConfigSource source)
71 { 72 {
73 IConfig config = source.Configs["ClientStack.LindenCaps"];
74 if (config == null)
75 return;
76
77 m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty);
78
72 IConfig appearanceConfig = source.Configs["Appearance"]; 79 IConfig appearanceConfig = source.Configs["Appearance"];
73 if (appearanceConfig != null) 80 if (appearanceConfig != null)
74 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); 81 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
@@ -280,23 +287,28 @@ namespace OpenSim.Region.ClientStack.Linden
280 287
281 public void RegisterCaps(UUID agentID, Caps caps) 288 public void RegisterCaps(UUID agentID, Caps caps)
282 { 289 {
283 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( 290 UUID capID = UUID.Random();
284 caps, m_scene.AssetService, m_persistBakedTextures);
285 291
286 292 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
287 293 if (m_URL == "localhost")
288 caps.RegisterHandler( 294 {
289 "UploadBakedTexture", 295 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
290 new RestStreamHandler( 296 caps, m_scene.AssetService, m_persistBakedTextures);
291 "POST",
292 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
293 avatarhandler.UploadBakedTexture,
294 "UploadBakedTexture",
295 agentID.ToString()));
296
297
298
299 297
298 caps.RegisterHandler(
299 "UploadBakedTexture",
300 new RestStreamHandler(
301 "POST",
302 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
303 avatarhandler.UploadBakedTexture,
304 "UploadBakedTexture",
305 agentID.ToString()));
306
307 }
308 else
309 {
310 caps.RegisterHandler("UploadBakedTexture", m_URL);
311 }
300 } 312 }
301 } 313 }
302} \ No newline at end of file 314}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 707cc93..f816ad3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -71,9 +71,13 @@ namespace OpenSim.Region.ClientStack.Linden
71 private IInventoryService m_InventoryService; 71 private IInventoryService m_InventoryService;
72 private ILibraryService m_LibraryService; 72 private ILibraryService m_LibraryService;
73 73
74 private bool m_Enabled;
75
76 private string m_fetchInventoryDescendents2Url;
77 private string m_webFetchInventoryDescendentsUrl;
78
74 private static WebFetchInvDescHandler m_webFetchHandler; 79 private static WebFetchInvDescHandler m_webFetchHandler;
75 80
76 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
77 private static Thread[] m_workerThreads = null; 81 private static Thread[] m_workerThreads = null;
78 82
79 private static DoubleQueue<aPollRequest> m_queue = 83 private static DoubleQueue<aPollRequest> m_queue =
@@ -83,22 +87,45 @@ namespace OpenSim.Region.ClientStack.Linden
83 87
84 public void Initialise(IConfigSource source) 88 public void Initialise(IConfigSource source)
85 { 89 {
90 IConfig config = source.Configs["ClientStack.LindenCaps"];
91 if (config == null)
92 return;
93
94 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
95 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
96
97 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
98 {
99 m_Enabled = true;
100 }
86 } 101 }
87 102
88 public void AddRegion(Scene s) 103 public void AddRegion(Scene s)
89 { 104 {
105 if (!m_Enabled)
106 return;
107
90 m_scene = s; 108 m_scene = s;
91 } 109 }
92 110
93 public void RemoveRegion(Scene s) 111 public void RemoveRegion(Scene s)
94 { 112 {
113 if (!m_Enabled)
114 return;
115
95 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 116 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
96 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; 117
118 foreach (Thread t in m_workerThreads)
119 Watchdog.AbortThread(t.ManagedThreadId);
120
97 m_scene = null; 121 m_scene = null;
98 } 122 }
99 123
100 public void RegionLoaded(Scene s) 124 public void RegionLoaded(Scene s)
101 { 125 {
126 if (!m_Enabled)
127 return;
128
102 m_InventoryService = m_scene.InventoryService; 129 m_InventoryService = m_scene.InventoryService;
103 m_LibraryService = m_scene.LibraryService; 130 m_LibraryService = m_scene.LibraryService;
104 131
@@ -106,7 +133,6 @@ namespace OpenSim.Region.ClientStack.Linden
106 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); 133 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
107 134
108 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 135 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
109 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
110 136
111 if (m_workerThreads == null) 137 if (m_workerThreads == null)
112 { 138 {
@@ -140,12 +166,6 @@ namespace OpenSim.Region.ClientStack.Linden
140 166
141 #endregion 167 #endregion
142 168
143 ~WebFetchInvDescModule()
144 {
145 foreach (Thread t in m_workerThreads)
146 Watchdog.AbortThread(t.ManagedThreadId);
147 }
148
149 private class PollServiceInventoryEventArgs : PollServiceEventArgs 169 private class PollServiceInventoryEventArgs : PollServiceEventArgs
150 { 170 {
151 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 171 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -155,8 +175,8 @@ namespace OpenSim.Region.ClientStack.Linden
155 175
156 private Scene m_scene; 176 private Scene m_scene;
157 177
158 public PollServiceInventoryEventArgs(Scene scene, UUID pId) : 178 public PollServiceInventoryEventArgs(Scene scene, string url, UUID pId) :
159 base(null, null, null, null, pId, int.MaxValue) 179 base(null, url, null, null, null, pId, int.MaxValue)
160 { 180 {
161 m_scene = scene; 181 m_scene = scene;
162 182
@@ -284,47 +304,53 @@ namespace OpenSim.Region.ClientStack.Linden
284 304
285 private void RegisterCaps(UUID agentID, Caps caps) 305 private void RegisterCaps(UUID agentID, Caps caps)
286 { 306 {
287 string capUrl = "/CAPS/" + UUID.Random() + "/"; 307 if (m_fetchInventoryDescendents2Url == "")
308 return;
288 309
289 // Register this as a poll service 310 // Register this as a poll service
290 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID); 311 PollServiceInventoryEventArgs args
291 312 = new PollServiceInventoryEventArgs(m_scene, "/CAPS/" + UUID.Random() + "/", agentID);
292 args.Type = PollServiceEventArgs.EventType.Inventory; 313 args.Type = PollServiceEventArgs.EventType.Inventory;
293 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
294
295 string hostName = m_scene.RegionInfo.ExternalHostName;
296 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
297 string protocol = "http";
298
299 if (MainServer.Instance.UseSSL)
300 {
301 hostName = MainServer.Instance.SSLCommonName;
302 port = MainServer.Instance.SSLPort;
303 protocol = "https";
304 }
305 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
306 314
307 m_capsDict[agentID] = capUrl; 315 caps.RegisterPollHandler("FetchInventoryDescendents2", args);
316
317// MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
318//
319// string hostName = m_scene.RegionInfo.ExternalHostName;
320// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
321// string protocol = "http";
322//
323// if (MainServer.Instance.UseSSL)
324// {
325// hostName = MainServer.Instance.SSLCommonName;
326// port = MainServer.Instance.SSLPort;
327// protocol = "https";
328// }
329//
330// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
308 } 331 }
309 332
310 private void DeregisterCaps(UUID agentID, Caps caps) 333// private void DeregisterCaps(UUID agentID, Caps caps)
311 { 334// {
312 string capUrl; 335// string capUrl;
313 336//
314 if (m_capsDict.TryGetValue(agentID, out capUrl)) 337// if (m_capsDict.TryGetValue(agentID, out capUrl))
315 { 338// {
316 MainServer.Instance.RemoveHTTPHandler("", capUrl); 339// MainServer.Instance.RemoveHTTPHandler("", capUrl);
317 m_capsDict.Remove(agentID); 340// m_capsDict.Remove(agentID);
318 } 341// }
319 } 342// }
320 343
321 private void DoInventoryRequests() 344 private void DoInventoryRequests()
322 { 345 {
323 while (true) 346 while (true)
324 { 347 {
348 Watchdog.UpdateThread();
349
325 aPollRequest poolreq = m_queue.Dequeue(); 350 aPollRequest poolreq = m_queue.Dequeue();
326 351
327 poolreq.thepoll.Process(poolreq); 352 if (poolreq != null && poolreq.thepoll != null)
353 poolreq.thepoll.Process(poolreq);
328 } 354 }
329 } 355 }
330 } 356 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index 3995620..15d6f7f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -424,12 +424,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
424 // foreign user is visiting, we need to try again after the first fail to the local 424 // foreign user is visiting, we need to try again after the first fail to the local
425 // asset service. 425 // asset service.
426 string assetServerURL = string.Empty; 426 string assetServerURL = string.Empty;
427 if (InventoryAccessModule.IsForeignUser(AgentID, out assetServerURL)) 427 if (InventoryAccessModule.IsForeignUser(AgentID, out assetServerURL) && !string.IsNullOrEmpty(assetServerURL))
428 { 428 {
429 if (!assetServerURL.EndsWith("/") && !assetServerURL.EndsWith("=")) 429 if (!assetServerURL.EndsWith("/") && !assetServerURL.EndsWith("="))
430 assetServerURL = assetServerURL + "/"; 430 assetServerURL = assetServerURL + "/";
431 431
432 m_log.DebugFormat("[J2KIMAGE]: texture {0} not found in local asset storage. Trying user's storage.", assetServerURL + id); 432// m_log.DebugFormat("[J2KIMAGE]: texture {0} not found in local asset storage. Trying user's storage.", assetServerURL + id);
433 AssetService.Get(assetServerURL + id, InventoryAccessModule, AssetReceived); 433 AssetService.Get(assetServerURL + id, InventoryAccessModule, AssetReceived);
434 return; 434 return;
435 } 435 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index eebb8ae..0e20e38 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -84,6 +84,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 public event ModifyTerrain OnModifyTerrain; 84 public event ModifyTerrain OnModifyTerrain;
85 public event Action<IClientAPI> OnRegionHandShakeReply; 85 public event Action<IClientAPI> OnRegionHandShakeReply;
86 public event GenericCall1 OnRequestWearables; 86 public event GenericCall1 OnRequestWearables;
87 public event CachedTextureRequest OnCachedTextureRequest;
87 public event SetAppearance OnSetAppearance; 88 public event SetAppearance OnSetAppearance;
88 public event AvatarNowWearing OnAvatarNowWearing; 89 public event AvatarNowWearing OnAvatarNowWearing;
89 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; 90 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
95 public event Action<IClientAPI, bool> OnCompleteMovementToRegion; 96 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
96 public event UpdateAgent OnPreAgentUpdate; 97 public event UpdateAgent OnPreAgentUpdate;
97 public event UpdateAgent OnAgentUpdate; 98 public event UpdateAgent OnAgentUpdate;
99 public event UpdateAgent OnAgentCameraUpdate;
98 public event AgentRequestSit OnAgentRequestSit; 100 public event AgentRequestSit OnAgentRequestSit;
99 public event AgentSit OnAgentSit; 101 public event AgentSit OnAgentSit;
100 public event AvatarPickerRequest OnAvatarPickerRequest; 102 public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -367,7 +369,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
367 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods 369 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
368 /// cannot retain a reference to it outside of that method. 370 /// cannot retain a reference to it outside of that method.
369 /// </remarks> 371 /// </remarks>
370 private AgentUpdateArgs m_lastAgentUpdateArgs; 372 private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
371 373
372 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 374 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
373 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 375 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -504,6 +506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 m_udpServer = udpServer; 506 m_udpServer = udpServer;
505 m_udpClient = udpClient; 507 m_udpClient = udpClient;
506 m_udpClient.OnQueueEmpty += HandleQueueEmpty; 508 m_udpClient.OnQueueEmpty += HandleQueueEmpty;
509 m_udpClient.HasUpdates += HandleHasUpdates;
507 m_udpClient.OnPacketStats += PopulateStats; 510 m_udpClient.OnPacketStats += PopulateStats;
508 511
509 m_prioritizer = new Prioritizer(m_scene); 512 m_prioritizer = new Prioritizer(m_scene);
@@ -709,12 +712,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
709 //there is a local handler for this packet type 712 //there is a local handler for this packet type
710 if (pprocessor.Async) 713 if (pprocessor.Async)
711 { 714 {
715 ClientInfo cinfo = UDPClient.GetClientInfo();
716 if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString()))
717 cinfo.AsyncRequests[packet.Type.ToString()] = 0;
718 cinfo.AsyncRequests[packet.Type.ToString()]++;
719
712 object obj = new AsyncPacketProcess(this, pprocessor.method, packet); 720 object obj = new AsyncPacketProcess(this, pprocessor.method, packet);
713 Util.FireAndForget(ProcessSpecificPacketAsync, obj); 721 Util.FireAndForget(ProcessSpecificPacketAsync, obj);
714 result = true; 722 result = true;
715 } 723 }
716 else 724 else
717 { 725 {
726 ClientInfo cinfo = UDPClient.GetClientInfo();
727 if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString()))
728 cinfo.SyncRequests[packet.Type.ToString()] = 0;
729 cinfo.SyncRequests[packet.Type.ToString()]++;
730
718 result = pprocessor.method(this, packet); 731 result = pprocessor.method(this, packet);
719 } 732 }
720 } 733 }
@@ -729,6 +742,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
729 } 742 }
730 if (found) 743 if (found)
731 { 744 {
745 ClientInfo cinfo = UDPClient.GetClientInfo();
746 if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString()))
747 cinfo.GenericRequests[packet.Type.ToString()] = 0;
748 cinfo.GenericRequests[packet.Type.ToString()]++;
749
732 result = method(this, packet); 750 result = method(this, packet);
733 } 751 }
734 } 752 }
@@ -820,12 +838,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
820 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); 838 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
821 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 839 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
822 840
823 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0]; 841 handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[1];
824// OutPacket(handshake, ThrottleOutPacketType.Task); 842 handshake.RegionInfo4[0] = new RegionHandshakePacket.RegionInfo4Block();
825 // use same as MoveAgentIntoRegion (both should be task ) 843 handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
844 handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
845
826 OutPacket(handshake, ThrottleOutPacketType.Unknown); 846 OutPacket(handshake, ThrottleOutPacketType.Unknown);
827 } 847 }
828 848
849
829 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 850 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
830 { 851 {
831 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 852 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -1580,7 +1601,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1580 OutPacket(pc, ThrottleOutPacketType.Unknown); 1601 OutPacket(pc, ThrottleOutPacketType.Unknown);
1581 } 1602 }
1582 1603
1583 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1604 public void SendKillObject(List<uint> localIDs)
1584 { 1605 {
1585// foreach (uint id in localIDs) 1606// foreach (uint id in localIDs)
1586// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); 1607// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
@@ -3797,6 +3818,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3797 ResendPrimUpdate(update); 3818 ResendPrimUpdate(update);
3798 } 3819 }
3799 3820
3821// OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3822// OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3823// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3824// OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3825//
3826// OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3827// OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3828// OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3829// OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3830
3831
3800 private void ProcessEntityUpdates(int maxUpdates) 3832 private void ProcessEntityUpdates(int maxUpdates)
3801 { 3833 {
3802 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); 3834 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
@@ -3809,6 +3841,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3809 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3841 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3810 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 3842 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
3811 3843
3844// objectUpdateBlocks.Value.Clear();
3845// compressedUpdateBlocks.Value.Clear();
3846// terseUpdateBlocks.Value.Clear();
3847// terseAgentUpdateBlocks.Value.Clear();
3848// objectUpdates.Value.Clear();
3849// compressedUpdates.Value.Clear();
3850// terseUpdates.Value.Clear();
3851// terseAgentUpdates.Value.Clear();
3852
3812 // Check to see if this is a flush 3853 // Check to see if this is a flush
3813 if (maxUpdates <= 0) 3854 if (maxUpdates <= 0)
3814 { 3855 {
@@ -4125,8 +4166,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4125 4166
4126 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 4167 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4127 { 4168 {
4169// if (!m_udpServer.IsRunningOutbound)
4170// return;
4171
4128 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 4172 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4129 { 4173 {
4174// if (!m_udpServer.IsRunningOutbound)
4175// return;
4176
4130 if (m_maxUpdates == 0 || m_LastQueueFill == 0) 4177 if (m_maxUpdates == 0 || m_LastQueueFill == 0)
4131 { 4178 {
4132 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; 4179 m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
@@ -4152,6 +4199,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4152 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 4199 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
4153 } 4200 }
4154 4201
4202 internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
4203 {
4204 bool hasUpdates = false;
4205
4206 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4207 {
4208 if (m_entityUpdates.Count > 0)
4209 hasUpdates = true;
4210 else if (m_entityProps.Count > 0)
4211 hasUpdates = true;
4212 }
4213
4214 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
4215 {
4216 if (ImageManager.HasUpdates())
4217 hasUpdates = true;
4218 }
4219
4220 return hasUpdates;
4221 }
4222
4155 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 4223 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
4156 { 4224 {
4157 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 4225 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -4862,7 +4930,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4862 4930
4863 public void SendForceClientSelectObjects(List<uint> ObjectIDs) 4931 public void SendForceClientSelectObjects(List<uint> ObjectIDs)
4864 { 4932 {
4865 m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); 4933// m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
4866 4934
4867 bool firstCall = true; 4935 bool firstCall = true;
4868 const int MAX_OBJECTS_PER_PACKET = 251; 4936 const int MAX_OBJECTS_PER_PACKET = 251;
@@ -5019,7 +5087,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5019 SceneObjectPart part = (SceneObjectPart)entity; 5087 SceneObjectPart part = (SceneObjectPart)entity;
5020 5088
5021 attachPoint = part.ParentGroup.AttachmentPoint; 5089 attachPoint = part.ParentGroup.AttachmentPoint;
5022 5090 attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
5023// m_log.DebugFormat( 5091// m_log.DebugFormat(
5024// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}", 5092// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
5025// attachPoint, part.Name, part.LocalId, Name); 5093// attachPoint, part.Name, part.LocalId, Name);
@@ -5047,7 +5115,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5047 pos += 4; 5115 pos += 4;
5048 5116
5049 // Avatar/CollisionPlane 5117 // Avatar/CollisionPlane
5050 data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ; 5118 data[pos++] = (byte) attachPoint;
5051 if (avatar) 5119 if (avatar)
5052 { 5120 {
5053 data[pos++] = 1; 5121 data[pos++] = 1;
@@ -5372,7 +5440,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5372 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); 5440 AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
5373 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); 5441 AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
5374 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); 5442 AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
5375 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); 5443 AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
5376 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); 5444 AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
5377 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); 5445 AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
5378 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); 5446 AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
@@ -5433,8 +5501,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5433 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); 5501 AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
5434 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); 5502 AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
5435 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); 5503 AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
5436 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); 5504 AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
5437 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); 5505 AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
5438 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); 5506 AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
5439 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); 5507 AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
5440 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); 5508 AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@@ -5466,7 +5534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5466 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5534 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5467 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5535 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
5468 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); 5536 AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
5469 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); 5537 AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
5470 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); 5538 AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
5471 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); 5539 AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
5472 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); 5540 AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
@@ -5579,83 +5647,137 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5579 5647
5580 #region Packet Handlers 5648 #region Packet Handlers
5581 5649
5650 public int TotalAgentUpdates { get; set; }
5651
5582 #region Scene/Avatar 5652 #region Scene/Avatar
5583 5653
5584 private bool HandleAgentUpdate(IClientAPI sener, Packet packet) 5654 // Threshold for body rotation to be a significant agent update
5655 private const float QDELTA = 0.000001f;
5656 // Threshold for camera rotation to be a significant agent update
5657 private const float VDELTA = 0.01f;
5658
5659 /// <summary>
5660 /// This checks the update significance against the last update made.
5661 /// </summary>
5662 /// <remarks>Can only be called by one thread at a time</remarks>
5663 /// <returns></returns>
5664 /// <param name='x'></param>
5665 public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5585 { 5666 {
5586 if (OnAgentUpdate != null) 5667 return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
5587 { 5668 }
5588 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5589 5669
5590 #region Packet Session and User Check 5670 /// <summary>
5591 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId) 5671 /// This checks the movement/state update significance against the last update made.
5592 { 5672 /// </summary>
5593 PacketPool.Instance.ReturnPacket(packet); 5673 /// <remarks>Can only be called by one thread at a time</remarks>
5594 return false; 5674 /// <returns></returns>
5595 } 5675 /// <param name='x'></param>
5596 #endregion 5676 private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5677 {
5678 float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
5679 //qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
5680
5681 bool movementSignificant =
5682 (qdelta1 > QDELTA) // significant if body rotation above threshold
5683 // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
5684 // || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold
5685 || (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
5686 || (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands
5687 || (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed
5688 || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
5689 || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
5690 ;
5691 //if (movementSignificant)
5692 //{
5693 //m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
5694 // qdelta1, qdelta2);
5695 //m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
5696 // x.ControlFlags, x.Flags, x.Far, x.State);
5697 //}
5698 return movementSignificant;
5699 }
5597 5700
5598 bool update = false; 5701 /// <summary>
5599 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; 5702 /// This checks the camera update significance against the last update made.
5600 5703 /// </summary>
5601 if (m_lastAgentUpdateArgs != null) 5704 /// <remarks>Can only be called by one thread at a time</remarks>
5602 { 5705 /// <returns></returns>
5603 // These should be ordered from most-likely to 5706 /// <param name='x'></param>
5604 // least likely to change. I've made an initial 5707 private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
5605 // guess at that. 5708 {
5606 update = 5709 float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
5607 ( 5710 float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
5608 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) || 5711 float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
5609 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) || 5712 float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
5610 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5611 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5612 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5613 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5614 (x.ControlFlags != 0) ||
5615 (x.Far != m_lastAgentUpdateArgs.Far) ||
5616 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5617 (x.State != m_lastAgentUpdateArgs.State) ||
5618 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5619 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5620 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5621 );
5622 }
5623 else
5624 {
5625 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5626 update = true;
5627 }
5628 5713
5629 if (update) 5714 bool cameraSignificant =
5630 { 5715 (vdelta1 > VDELTA) ||
5631// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5716 (vdelta2 > VDELTA) ||
5717 (vdelta3 > VDELTA) ||
5718 (vdelta4 > VDELTA)
5719 ;
5632 5720
5633 m_lastAgentUpdateArgs.AgentID = x.AgentID; 5721 //if (cameraSignificant)
5634 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation; 5722 //{
5635 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis; 5723 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
5636 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter; 5724 // x.CameraAtAxis, x.CameraCenter);
5637 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; 5725 //m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
5638 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; 5726 // x.CameraLeftAxis, x.CameraUpAxis);
5639 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags; 5727 //}
5640 m_lastAgentUpdateArgs.Far = x.Far;
5641 m_lastAgentUpdateArgs.Flags = x.Flags;
5642 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5643 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5644 m_lastAgentUpdateArgs.State = x.State;
5645 5728
5646 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5729 return cameraSignificant;
5647 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5730 }
5648 5731
5649 if (handlerPreAgentUpdate != null) 5732 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5650 OnPreAgentUpdate(this, m_lastAgentUpdateArgs); 5733 {
5734 // We got here, which means that something in agent update was significant
5651 5735
5652 if (handlerAgentUpdate != null) 5736 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5653 OnAgentUpdate(this, m_lastAgentUpdateArgs); 5737 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5654 5738
5655 handlerAgentUpdate = null; 5739 if (x.AgentID != AgentId || x.SessionID != SessionId)
5656 handlerPreAgentUpdate = null; 5740 return false;
5657 } 5741
5658 } 5742 // Before we update the current m_thisAgentUpdateArgs, let's check this again
5743 // to see what exactly changed
5744 bool movement = CheckAgentMovementUpdateSignificance(x);
5745 bool camera = CheckAgentCameraUpdateSignificance(x);
5746
5747 m_thisAgentUpdateArgs.AgentID = x.AgentID;
5748 m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
5749 m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5750 m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
5751 m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5752 m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5753 m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
5754 m_thisAgentUpdateArgs.Far = x.Far;
5755 m_thisAgentUpdateArgs.Flags = x.Flags;
5756 m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
5757 m_thisAgentUpdateArgs.SessionID = x.SessionID;
5758 m_thisAgentUpdateArgs.State = x.State;
5759
5760 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5761 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5762 UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
5763
5764 // Was there a significant movement/state change?
5765 if (movement)
5766 {
5767 if (handlerPreAgentUpdate != null)
5768 OnPreAgentUpdate(this, m_thisAgentUpdateArgs);
5769
5770 if (handlerAgentUpdate != null)
5771 OnAgentUpdate(this, m_thisAgentUpdateArgs);
5772 }
5773 // Was there a significant camera(s) change?
5774 if (camera)
5775 if (handlerAgentCameraUpdate != null)
5776 handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
5777
5778 handlerAgentUpdate = null;
5779 handlerPreAgentUpdate = null;
5780 handlerAgentCameraUpdate = null;
5659 5781
5660 PacketPool.Instance.ReturnPacket(packet); 5782 PacketPool.Instance.ReturnPacket(packet);
5661 5783
@@ -7864,129 +7986,145 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7864 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); 7986 //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
7865 7987
7866 TransferRequestPacket transfer = (TransferRequestPacket)Pack; 7988 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
7867 //m_log.Debug("Transfer Request: " + transfer.ToString());
7868 // Validate inventory transfers
7869 // Has to be done here, because AssetCache can't do it
7870 //
7871 UUID taskID = UUID.Zero; 7989 UUID taskID = UUID.Zero;
7872 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) 7990 if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
7873 { 7991 {
7874 taskID = new UUID(transfer.TransferInfo.Params, 48);
7875 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7876 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7877
7878// m_log.DebugFormat(
7879// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7880// requestID, itemID, taskID, Name);
7881
7882 if (!(((Scene)m_scene).Permissions.BypassPermissions())) 7992 if (!(((Scene)m_scene).Permissions.BypassPermissions()))
7883 { 7993 {
7884 if (taskID != UUID.Zero) // Prim 7994 // We're spawning a thread because the permissions check can block this thread
7995 Util.FireAndForget(delegate
7885 { 7996 {
7886 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); 7997 // This requests the asset if needed
7998 HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
7999 });
8000 return true;
8001 }
8002 }
8003 else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
8004 {
8005 //TransferRequestPacket does not include covenant uuid?
8006 //get scene covenant uuid
8007 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
8008 }
7887 8009
7888 if (part == null) 8010 // This is non-blocking
7889 { 8011 MakeAssetRequest(transfer, taskID);
7890 m_log.WarnFormat(
7891 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7892 Name, requestID, itemID, taskID);
7893 return true;
7894 }
7895 8012
7896 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); 8013 return true;
7897 if (tii == null) 8014 }
7898 {
7899 m_log.WarnFormat(
7900 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7901 Name, requestID, itemID, taskID);
7902 return true;
7903 }
7904 8015
7905 if (tii.Type == (int)AssetType.LSLText) 8016 private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
7906 { 8017 {
7907 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) 8018 UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
7908 return true; 8019 UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
7909 } 8020 UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
7910 else if (tii.Type == (int)AssetType.Notecard)
7911 {
7912 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
7913 return true;
7914 }
7915 else
7916 {
7917 // TODO: Change this code to allow items other than notecards and scripts to be successfully
7918 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
7919 if (part.OwnerID != AgentId)
7920 {
7921 m_log.WarnFormat(
7922 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
7923 Name, requestID, itemID, taskID, part.OwnerID);
7924 return true;
7925 }
7926 8021
7927 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) 8022 //m_log.DebugFormat(
7928 { 8023 // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
7929 m_log.WarnFormat( 8024 // requestID, itemID, taskID, Name);
7930 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7931 Name, requestID, itemID, taskID);
7932 return true;
7933 }
7934 8025
7935 if (tii.OwnerID != AgentId) 8026 //m_log.Debug("Transfer Request: " + transfer.ToString());
7936 { 8027 // Validate inventory transfers
7937 m_log.WarnFormat( 8028 // Has to be done here, because AssetCache can't do it
7938 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", 8029 //
7939 Name, requestID, itemID, taskID, tii.OwnerID); 8030 if (taskID != UUID.Zero) // Prim
7940 return true; 8031 {
7941 } 8032 SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
7942 8033
7943 if (( 8034 if (part == null)
7944 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8035 {
7945 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) 8036 m_log.WarnFormat(
7946 { 8037 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
7947 m_log.WarnFormat( 8038 Name, requestID, itemID, taskID);
7948 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", 8039 return;
7949 Name, requestID, itemID, taskID); 8040 }
7950 return true;
7951 }
7952 8041
7953 if (tii.AssetID != requestID) 8042 TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
7954 { 8043 if (tii == null)
7955 m_log.WarnFormat( 8044 {
7956 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", 8045 m_log.WarnFormat(
7957 Name, requestID, itemID, taskID, tii.AssetID); 8046 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
7958 return true; 8047 Name, requestID, itemID, taskID);
7959 } 8048 return;
7960 } 8049 }
8050
8051 if (tii.Type == (int)AssetType.LSLText)
8052 {
8053 if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
8054 return;
8055 }
8056 else if (tii.Type == (int)AssetType.Notecard)
8057 {
8058 if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
8059 return;
8060 }
8061 else
8062 {
8063 // TODO: Change this code to allow items other than notecards and scripts to be successfully
8064 // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
8065 if (part.OwnerID != AgentId)
8066 {
8067 m_log.WarnFormat(
8068 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
8069 Name, requestID, itemID, taskID, part.OwnerID);
8070 return;
7961 } 8071 }
7962 else // Agent 8072
8073 if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
7963 { 8074 {
7964 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 8075 m_log.WarnFormat(
7965 if (invAccess != null) 8076 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
7966 { 8077 Name, requestID, itemID, taskID);
7967 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) 8078 return;
7968 return false; 8079 }
7969 } 8080
7970 else 8081 if (tii.OwnerID != AgentId)
7971 { 8082 {
7972 return false; 8083 m_log.WarnFormat(
7973 } 8084 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
8085 Name, requestID, itemID, taskID, tii.OwnerID);
8086 return;
8087 }
8088
8089 if ((
8090 tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8091 != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
8092 {
8093 m_log.WarnFormat(
8094 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
8095 Name, requestID, itemID, taskID);
8096 return;
8097 }
8098
8099 if (tii.AssetID != requestID)
8100 {
8101 m_log.WarnFormat(
8102 "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
8103 Name, requestID, itemID, taskID, tii.AssetID);
8104 return;
7974 } 8105 }
7975 } 8106 }
7976 } 8107 }
7977 else 8108 else // Agent
7978 if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) 8109 {
8110 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
8111 if (invAccess != null)
7979 { 8112 {
7980 //TransferRequestPacket does not include covenant uuid? 8113 if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
7981 //get scene covenant uuid 8114 return;
7982 taskID = m_scene.RegionInfo.RegionSettings.Covenant;
7983 } 8115 }
8116 else
8117 {
8118 return;
8119 }
8120 }
7984 8121
8122 // Permissions out of the way, let's request the asset
7985 MakeAssetRequest(transfer, taskID); 8123 MakeAssetRequest(transfer, taskID);
7986 8124
7987 return true;
7988 } 8125 }
7989 8126
8127
7990 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) 8128 private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
7991 { 8129 {
7992 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; 8130 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
@@ -11717,8 +11855,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11717 } 11855 }
11718 11856
11719 /// <summary> 11857 /// <summary>
11720 /// Send a response back to a client when it asks the asset server (via the region server) if it has
11721 /// its appearance texture cached.
11722 /// </summary> 11858 /// </summary>
11723 /// <remarks> 11859 /// <remarks>
11724 /// At the moment, we always reply that there is no cached texture. 11860 /// At the moment, we always reply that there is no cached texture.
@@ -11726,6 +11862,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11726 /// <param name="simclient"></param> 11862 /// <param name="simclient"></param>
11727 /// <param name="packet"></param> 11863 /// <param name="packet"></param>
11728 /// <returns></returns> 11864 /// <returns></returns>
11865 // TODO: Convert old handler to use new method
11866 /*protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11867 {
11868 AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
11869
11870 if (cachedtex.AgentData.SessionID != SessionId)
11871 return false;
11872
11873
11874 List<CachedTextureRequestArg> requestArgs = new List<CachedTextureRequestArg>();
11875
11876 for (int i = 0; i < cachedtex.WearableData.Length; i++)
11877 {
11878 CachedTextureRequestArg arg = new CachedTextureRequestArg();
11879 arg.BakedTextureIndex = cachedtex.WearableData[i].TextureIndex;
11880 arg.WearableHashID = cachedtex.WearableData[i].ID;
11881
11882 requestArgs.Add(arg);
11883 }
11884
11885 CachedTextureRequest handlerCachedTextureRequest = OnCachedTextureRequest;
11886 if (handlerCachedTextureRequest != null)
11887 {
11888 handlerCachedTextureRequest(simclient,cachedtex.AgentData.SerialNum,requestArgs);
11889 }
11890
11891 return true;
11892 }*/
11893
11729 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet) 11894 protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
11730 { 11895 {
11731 //m_log.Debug("texture cached: " + packet.ToString()); 11896 //m_log.Debug("texture cached: " + packet.ToString());
@@ -11884,6 +12049,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11884 return true; 12049 return true;
11885 } 12050 }
11886 12051
12052 /// <summary>
12053 /// Send a response back to a client when it asks the asset server (via the region server) if it has
12054 /// its appearance texture cached.
12055 /// </summary>
12056 /// <param name="avatar"></param>
12057 /// <param name="serial"></param>
12058 /// <param name="cachedTextures"></param>
12059 /// <returns></returns>
12060 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
12061 {
12062 ScenePresence presence = avatar as ScenePresence;
12063 if (presence == null)
12064 return;
12065
12066 AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
12067
12068 // TODO: don't create new blocks if recycling an old packet
12069 cachedresp.AgentData.AgentID = m_agentId;
12070 cachedresp.AgentData.SessionID = m_sessionId;
12071 cachedresp.AgentData.SerialNum = serial;
12072 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedTextures.Count];
12073
12074 for (int i = 0; i < cachedTextures.Count; i++)
12075 {
12076 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
12077 cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
12078 cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
12079 cachedresp.WearableData[i].HostName = new byte[0];
12080 }
12081
12082 cachedresp.Header.Zerocoded = true;
12083 OutPacket(cachedresp, ThrottleOutPacketType.Task);
12084 }
12085
11887 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet) 12086 protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
11888 { 12087 {
11889 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; 12088 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
@@ -11909,8 +12108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11909 if (part == null) 12108 if (part == null)
11910 { 12109 {
11911 // It's a ghost! tell the client to delete it from view. 12110 // It's a ghost! tell the client to delete it from view.
11912 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 12111 simClient.SendKillObject(new List<uint> { localId });
11913 new List<uint> { localId });
11914 } 12112 }
11915 else 12113 else
11916 { 12114 {
@@ -12314,7 +12512,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12314 ClientInfo info = m_udpClient.GetClientInfo(); 12512 ClientInfo info = m_udpClient.GetClientInfo();
12315 12513
12316 info.proxyEP = null; 12514 info.proxyEP = null;
12317 info.agentcircuit = RequestClientInfo(); 12515 if (info.agentcircuit == null)
12516 info.agentcircuit = RequestClientInfo();
12318 12517
12319 return info; 12518 return info;
12320 } 12519 }
@@ -12697,7 +12896,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12697 OutPacket(dialog, ThrottleOutPacketType.Task); 12896 OutPacket(dialog, ThrottleOutPacketType.Task);
12698 } 12897 }
12699 12898
12700 public void StopFlying(ISceneEntity p) 12899 public void SendAgentTerseUpdate(ISceneEntity p)
12701 { 12900 {
12702 if (p is ScenePresence) 12901 if (p is ScenePresence)
12703 { 12902 {
@@ -12711,25 +12910,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12711 12910
12712 Vector3 pos = presence.AbsolutePosition; 12911 Vector3 pos = presence.AbsolutePosition;
12713 12912
12714 if (presence.Appearance.AvatarHeight != 127.0f)
12715 pos += new Vector3(0f, 0f, (presence.Appearance.AvatarHeight/6f));
12716 else
12717 pos += new Vector3(0f, 0f, (1.56f/6f));
12718
12719 presence.AbsolutePosition = pos;
12720
12721 // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
12722 // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
12723 // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
12724 // certain amount.. because the LLClient wouldn't land in that situation anyway.
12725
12726 // why are we still testing for this really old height value default???
12727 if (presence.Appearance.AvatarHeight != 127.0f)
12728 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - presence.Appearance.AvatarHeight/6f);
12729 else
12730 presence.CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f/6f));
12731
12732
12733 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = 12913 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block =
12734 CreateImprovedTerseBlock(p, false); 12914 CreateImprovedTerseBlock(p, false);
12735 12915
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
index 073c357..41dd4d1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
@@ -206,6 +206,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
206 } 206 }
207 } 207 }
208 208
209 public bool HasUpdates()
210 {
211 J2KImage image = GetHighestPriorityImage();
212
213 return image != null && image.IsDecoded;
214 }
215
209 public bool ProcessImageQueue(int packetsToSend) 216 public bool ProcessImageQueue(int packetsToSend)
210 { 217 {
211 int packetsSent = 0; 218 int packetsSent = 0;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index e52ac37..d52ad7e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -31,6 +31,7 @@ using System.Net;
31using System.Threading; 31using System.Threading;
32using log4net; 32using log4net;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Monitoring;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenMetaverse.Packets; 36using OpenMetaverse.Packets;
36 37
@@ -81,6 +82,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
81 /// hooked to put more data on the empty queue</summary> 82 /// hooked to put more data on the empty queue</summary>
82 public event QueueEmpty OnQueueEmpty; 83 public event QueueEmpty OnQueueEmpty;
83 84
85 public event Func<ThrottleOutPacketTypeFlags, bool> HasUpdates;
86
84 /// <summary>AgentID for this client</summary> 87 /// <summary>AgentID for this client</summary>
85 public readonly UUID AgentID; 88 public readonly UUID AgentID;
86 /// <summary>The remote address of the connected client</summary> 89 /// <summary>The remote address of the connected client</summary>
@@ -160,6 +163,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
160 private int m_maxRTO = 60000; 163 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true; 164 public bool m_deliverPackets = true;
162 165
166 private ClientInfo m_info = new ClientInfo();
167
163 /// <summary> 168 /// <summary>
164 /// Default constructor 169 /// Default constructor
165 /// </summary> 170 /// </summary>
@@ -241,20 +246,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists 246 // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists
242 // of pending and needed ACKs for every client every time some method wants information about 247 // of pending and needed ACKs for every client every time some method wants information about
243 // this connection is a recipe for poor performance 248 // this connection is a recipe for poor performance
244 ClientInfo info = new ClientInfo(); 249
245 info.pendingAcks = new Dictionary<uint, uint>(); 250 m_info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate;
246 info.needAck = new Dictionary<uint, byte[]>(); 251 m_info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate;
247 252 m_info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate;
248 info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; 253 m_info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate;
249 info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; 254 m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate;
250 info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; 255 m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
251 info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; 256 m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
252 info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; 257 m_info.totalThrottle = (int)m_throttleCategory.DripRate;
253 info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; 258
254 info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; 259 return m_info;
255 info.totalThrottle = (int)m_throttleCategory.DripRate;
256
257 return info;
258 } 260 }
259 261
260 /// <summary> 262 /// <summary>
@@ -646,15 +648,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
646 /// <param name="categories">Throttle categories to fire the callback for</param> 648 /// <param name="categories">Throttle categories to fire the callback for</param>
647 private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories) 649 private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories)
648 { 650 {
649 if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty) 651// if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
652 if (!m_isQueueEmptyRunning && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
650 { 653 {
654 m_isQueueEmptyRunning = true;
655
656 int start = Environment.TickCount & Int32.MaxValue;
657 const int MIN_CALLBACK_MS = 30;
658
659 m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
660 if (m_nextOnQueueEmpty == 0)
661 m_nextOnQueueEmpty = 1;
662
651 // Use a value of 0 to signal that FireQueueEmpty is running 663 // Use a value of 0 to signal that FireQueueEmpty is running
652 m_nextOnQueueEmpty = 0; 664// m_nextOnQueueEmpty = 0;
653 // Asynchronously run the callback 665
654 Util.FireAndForget(FireQueueEmpty, categories); 666 m_categories = categories;
667
668 if (HasUpdates(m_categories))
669 {
670 // Asynchronously run the callback
671 Util.FireAndForget(FireQueueEmpty, categories);
672 }
673 else
674 {
675 m_isQueueEmptyRunning = false;
676 }
655 } 677 }
656 } 678 }
657 679
680 private bool m_isQueueEmptyRunning;
681 private ThrottleOutPacketTypeFlags m_categories = 0;
682
658 /// <summary> 683 /// <summary>
659 /// Fires the OnQueueEmpty callback and sets the minimum time that it 684 /// Fires the OnQueueEmpty callback and sets the minimum time that it
660 /// can be called again 685 /// can be called again
@@ -664,22 +689,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
664 /// signature</param> 689 /// signature</param>
665 private void FireQueueEmpty(object o) 690 private void FireQueueEmpty(object o)
666 { 691 {
667 const int MIN_CALLBACK_MS = 30; 692// int start = Environment.TickCount & Int32.MaxValue;
693// const int MIN_CALLBACK_MS = 30;
668 694
669 ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o; 695// if (m_udpServer.IsRunningOutbound)
670 QueueEmpty callback = OnQueueEmpty; 696// {
671 697 ThrottleOutPacketTypeFlags categories = (ThrottleOutPacketTypeFlags)o;
672 int start = Environment.TickCount & Int32.MaxValue; 698 QueueEmpty callback = OnQueueEmpty;
673 699
674 if (callback != null) 700 if (callback != null)
675 { 701 {
676 try { callback(categories); } 702// if (m_udpServer.IsRunningOutbound)
677 catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); } 703// {
678 } 704 try { callback(categories); }
705 catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + categories + ") threw an exception: " + e.Message, e); }
706// }
707 }
708// }
709
710// m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
711// if (m_nextOnQueueEmpty == 0)
712// m_nextOnQueueEmpty = 1;
713
714// }
679 715
680 m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; 716 m_isQueueEmptyRunning = false;
681 if (m_nextOnQueueEmpty == 0)
682 m_nextOnQueueEmpty = 1;
683 } 717 }
684 internal void ForceThrottleSetting(int throttle, int setting) 718 internal void ForceThrottleSetting(int throttle, int setting)
685 { 719 {
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 4154ef2..71b464b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -34,6 +34,7 @@ using System.Net.Sockets;
34using System.Reflection; 34using System.Reflection;
35using System.Threading; 35using System.Threading;
36using log4net; 36using log4net;
37using NDesk.Options;
37using Nini.Config; 38using Nini.Config;
38using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
39using OpenSim.Framework; 40using OpenSim.Framework;
@@ -62,20 +63,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
62 m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager); 63 m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager);
63 } 64 }
64 65
65 public void NetworkStop()
66 {
67 m_udpServer.Stop();
68 }
69
70 public void AddScene(IScene scene) 66 public void AddScene(IScene scene)
71 { 67 {
72 m_udpServer.AddScene(scene); 68 m_udpServer.AddScene(scene);
73 69
74 StatsManager.RegisterStat( 70 StatsManager.RegisterStat(
75 new Stat( 71 new Stat(
72 "ClientLogoutsDueToNoReceives",
73 "Number of times a client has been logged out because no packets were received before the timeout.",
74 "",
75 "",
76 "clientstack",
77 scene.Name,
78 StatType.Pull,
79 MeasuresOfInterest.None,
80 stat => stat.Value = m_udpServer.ClientLogoutsDueToNoReceives,
81 StatVerbosity.Debug));
82
83 StatsManager.RegisterStat(
84 new Stat(
85 "IncomingUDPReceivesCount",
86 "Number of UDP receives performed",
87 "",
88 "",
89 "clientstack",
90 scene.Name,
91 StatType.Pull,
92 MeasuresOfInterest.AverageChangeOverTime,
93 stat => stat.Value = m_udpServer.UdpReceives,
94 StatVerbosity.Debug));
95
96 StatsManager.RegisterStat(
97 new Stat(
76 "IncomingPacketsProcessedCount", 98 "IncomingPacketsProcessedCount",
77 "Number of inbound UDP packets processed", 99 "Number of inbound LL protocol packets processed",
78 "Number of inbound UDP packets processed", 100 "",
79 "", 101 "",
80 "clientstack", 102 "clientstack",
81 scene.Name, 103 scene.Name,
@@ -83,6 +105,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
83 MeasuresOfInterest.AverageChangeOverTime, 105 MeasuresOfInterest.AverageChangeOverTime,
84 stat => stat.Value = m_udpServer.IncomingPacketsProcessed, 106 stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
85 StatVerbosity.Debug)); 107 StatVerbosity.Debug));
108
109 StatsManager.RegisterStat(
110 new Stat(
111 "OutgoingUDPSendsCount",
112 "Number of UDP sends performed",
113 "",
114 "",
115 "clientstack",
116 scene.Name,
117 StatType.Pull,
118 MeasuresOfInterest.AverageChangeOverTime,
119 stat => stat.Value = m_udpServer.UdpSends,
120 StatVerbosity.Debug));
121
122 StatsManager.RegisterStat(
123 new Stat(
124 "AverageUDPProcessTime",
125 "Average number of milliseconds taken to process each incoming UDP packet in a sample.",
126 "This is for initial receive processing which is separate from the later client LL packet processing stage.",
127 "ms",
128 "clientstack",
129 scene.Name,
130 StatType.Pull,
131 MeasuresOfInterest.None,
132 stat => stat.Value = m_udpServer.AverageReceiveTicksForLastSamplePeriod / TimeSpan.TicksPerMillisecond,
133// stat =>
134// stat.Value = Math.Round(m_udpServer.AverageReceiveTicksForLastSamplePeriod / TimeSpan.TicksPerMillisecond, 7),
135 StatVerbosity.Debug));
86 } 136 }
87 137
88 public bool HandlesRegion(Location x) 138 public bool HandlesRegion(Location x)
@@ -107,10 +157,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
107 /// </summary> 157 /// </summary>
108 public class LLUDPServer : OpenSimUDPBase 158 public class LLUDPServer : OpenSimUDPBase
109 { 159 {
160 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
161
110 /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> 162 /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
111 public const int MTU = 1400; 163 public const int MTU = 1400;
112 164
113 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 165 /// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
166 public int ClientLogoutsDueToNoReceives { get; private set; }
167
168 /// <summary>
169 /// Default packet debug level given to new clients
170 /// </summary>
171 public int DefaultClientPacketDebugLevel { get; set; }
114 172
115 /// <summary>The measured resolution of Environment.TickCount</summary> 173 /// <summary>The measured resolution of Environment.TickCount</summary>
116 public readonly float TickCountResolution; 174 public readonly float TickCountResolution;
@@ -184,6 +242,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
184 protected bool m_sendPing; 242 protected bool m_sendPing;
185 243
186 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); 244 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
245
246 /// <summary>
247 /// Event used to signal when queued packets are available for sending.
248 /// </summary>
249 /// <remarks>
250 /// This allows the outbound loop to only operate when there is data to send rather than continuously polling.
251 /// Some data is sent immediately and not queued. That data would not trigger this event.
252 /// </remarks>
253 private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
254
187 private Pool<IncomingPacket> m_incomingPacketPool; 255 private Pool<IncomingPacket> m_incomingPacketPool;
188 256
189 /// <summary> 257 /// <summary>
@@ -461,6 +529,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
461 m_scene = (Scene)scene; 529 m_scene = (Scene)scene;
462 m_location = new Location(m_scene.RegionInfo.RegionHandle); 530 m_location = new Location(m_scene.RegionInfo.RegionHandle);
463 531
532 StatsManager.RegisterStat(
533 new Stat(
534 "InboxPacketsCount",
535 "Number of LL protocol packets waiting for the second stage of processing after initial receive.",
536 "Number of LL protocol packets waiting for the second stage of processing after initial receive.",
537 "",
538 "clientstack",
539 scene.Name,
540 StatType.Pull,
541 MeasuresOfInterest.AverageChangeOverTime,
542 stat => stat.Value = packetInbox.Count,
543 StatVerbosity.Debug));
544
464 // XXX: These stats are also pool stats but we register them separately since they are currently not 545 // XXX: These stats are also pool stats but we register them separately since they are currently not
465 // turned on and off by EnablePools()/DisablePools() 546 // turned on and off by EnablePools()/DisablePools()
466 StatsManager.RegisterStat( 547 StatsManager.RegisterStat(
@@ -521,6 +602,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 EnablePoolStats(); 602 EnablePoolStats();
522 603
523 MainConsole.Instance.Commands.AddCommand( 604 MainConsole.Instance.Commands.AddCommand(
605 "Debug", false, "debug lludp packet",
606 "debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]",
607 "Turn on packet debugging",
608 "If level > 255 then all incoming and outgoing packets are logged.\n"
609 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
610 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
611 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
612 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
613 + "If level <= 0 then no packets are logged.\n"
614 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
615 + "In this case, you cannot also specify an avatar name.\n"
616 + "If an avatar name is given then only packets from that avatar are logged.",
617 HandlePacketCommand);
618
619 MainConsole.Instance.Commands.AddCommand(
524 "Debug", 620 "Debug",
525 false, 621 false,
526 "debug lludp start", 622 "debug lludp start",
@@ -559,10 +655,78 @@ namespace OpenSim.Region.ClientStack.LindenUDP
559 "debug lludp status", 655 "debug lludp status",
560 "Return status of LLUDP packet processing.", 656 "Return status of LLUDP packet processing.",
561 HandleStatusCommand); 657 HandleStatusCommand);
658
659 MainConsole.Instance.Commands.AddCommand(
660 "Debug",
661 false,
662 "debug lludp toggle agentupdate",
663 "debug lludp toggle agentupdate",
664 "Toggle whether agentupdate packets are processed or simply discarded.",
665 HandleAgentUpdateCommand);
666 }
667
668 private void HandlePacketCommand(string module, string[] args)
669 {
670 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
671 return;
672
673 bool setAsDefaultLevel = false;
674 OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null);
675 List<string> filteredArgs = optionSet.Parse(args);
676
677 string name = null;
678
679 if (filteredArgs.Count == 6)
680 {
681 if (!setAsDefaultLevel)
682 {
683 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
684 }
685 else
686 {
687 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level");
688 return;
689 }
690 }
691
692 if (filteredArgs.Count > 3)
693 {
694 int newDebug;
695 if (int.TryParse(filteredArgs[3], out newDebug))
696 {
697 if (setAsDefaultLevel)
698 {
699 DefaultClientPacketDebugLevel = newDebug;
700 MainConsole.Instance.OutputFormat(
701 "Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name);
702 }
703 else
704 {
705 m_scene.ForEachScenePresence(sp =>
706 {
707 if (name == null || sp.Name == name)
708 {
709 MainConsole.Instance.OutputFormat(
710 "Packet debug for {0} ({1}) set to {2} in {3}",
711 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
712
713 sp.ControllingClient.DebugPacketLevel = newDebug;
714 }
715 });
716 }
717 }
718 else
719 {
720 MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]");
721 }
722 }
562 } 723 }
563 724
564 private void HandleStartCommand(string module, string[] args) 725 private void HandleStartCommand(string module, string[] args)
565 { 726 {
727 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
728 return;
729
566 if (args.Length != 4) 730 if (args.Length != 4)
567 { 731 {
568 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>"); 732 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
@@ -580,6 +744,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
580 744
581 private void HandleStopCommand(string module, string[] args) 745 private void HandleStopCommand(string module, string[] args)
582 { 746 {
747 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
748 return;
749
583 if (args.Length != 4) 750 if (args.Length != 4)
584 { 751 {
585 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>"); 752 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
@@ -597,6 +764,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
597 764
598 private void HandlePoolCommand(string module, string[] args) 765 private void HandlePoolCommand(string module, string[] args)
599 { 766 {
767 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
768 return;
769
600 if (args.Length != 4) 770 if (args.Length != 4)
601 { 771 {
602 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>"); 772 MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
@@ -627,8 +797,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
627 } 797 }
628 } 798 }
629 799
800 bool m_discardAgentUpdates;
801
802 private void HandleAgentUpdateCommand(string module, string[] args)
803 {
804 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
805 return;
806
807 m_discardAgentUpdates = !m_discardAgentUpdates;
808
809 MainConsole.Instance.OutputFormat(
810 "Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name);
811 }
812
630 private void HandleStatusCommand(string module, string[] args) 813 private void HandleStatusCommand(string module, string[] args)
631 { 814 {
815 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
816 return;
817
632 MainConsole.Instance.OutputFormat( 818 MainConsole.Instance.OutputFormat(
633 "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled"); 819 "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
634 820
@@ -636,6 +822,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
636 "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); 822 "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
637 823
638 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off"); 824 MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
825
826 MainConsole.Instance.OutputFormat(
827 "Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
639 } 828 }
640 829
641 public bool HandlesRegion(Location x) 830 public bool HandlesRegion(Location x)
@@ -721,6 +910,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
721 } 910 }
722 911
723 PacketPool.Instance.ReturnPacket(packet); 912 PacketPool.Instance.ReturnPacket(packet);
913
914 m_dataPresentEvent.Set();
724 } 915 }
725 916
726 /// <summary> 917 /// <summary>
@@ -883,7 +1074,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
883 // Fire this out on a different thread so that we don't hold up outgoing packet processing for 1074 // Fire this out on a different thread so that we don't hold up outgoing packet processing for
884 // everybody else if this is being called due to an ack timeout. 1075 // everybody else if this is being called due to an ack timeout.
885 // This is the same as processing as the async process of a logout request. 1076 // This is the same as processing as the async process of a logout request.
886 Util.FireAndForget(o => DeactivateClientDueToTimeout(client)); 1077 Util.FireAndForget(o => DeactivateClientDueToTimeout(client, timeoutTicks));
887 1078
888 return; 1079 return;
889 } 1080 }
@@ -1127,6 +1318,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1127 queue.Enqueue(buffer); 1318 queue.Enqueue(buffer);
1128 return; 1319 return;
1129 } 1320 }
1321 else if (packet.Type == PacketType.CompleteAgentMovement)
1322 {
1323 // Send ack straight away to let the viewer know that we got it.
1324 SendAckImmediate(endPoint, packet.Header.Sequence);
1325
1326 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1327 // buffer.
1328 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1329
1330 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1331
1332 return;
1333 }
1130 } 1334 }
1131 1335
1132 // Determine which agent this packet came from 1336 // Determine which agent this packet came from
@@ -1233,6 +1437,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1233 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); 1437 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
1234 #endregion BinaryStats 1438 #endregion BinaryStats
1235 1439
1440 if (packet.Type == PacketType.AgentUpdate)
1441 {
1442 if (m_discardAgentUpdates)
1443 return;
1444
1445 ((LLClientView)client).TotalAgentUpdates++;
1446
1447 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
1448
1449 LLClientView llClient = client as LLClientView;
1450 if (agentUpdate.AgentData.SessionID != client.SessionId
1451 || agentUpdate.AgentData.AgentID != client.AgentId
1452 || !(llClient == null || llClient.CheckAgentUpdateSignificance(agentUpdate.AgentData)) )
1453 {
1454 PacketPool.Instance.ReturnPacket(packet);
1455 return;
1456 }
1457 }
1458
1236 #region Ping Check Handling 1459 #region Ping Check Handling
1237 1460
1238 if (packet.Type == PacketType.StartPingCheck) 1461 if (packet.Type == PacketType.StartPingCheck)
@@ -1421,7 +1644,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1421 1644
1422 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1645 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1423 if (client != null) 1646 if (client != null)
1424 client.SceneAgent.SendInitialDataToMe(); 1647 {
1648 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1649 bool tp = (aCircuit.teleportFlags > 0);
1650 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
1651 if (!tp)
1652 client.SceneAgent.SendInitialDataToMe();
1653 }
1425 1654
1426 // Now we know we can handle more data 1655 // Now we know we can handle more data
1427 Thread.Sleep(200); 1656 Thread.Sleep(200);
@@ -1476,6 +1705,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1476 } 1705 }
1477 } 1706 }
1478 1707
1708 private void HandleCompleteMovementIntoRegion(object o)
1709 {
1710 IPEndPoint endPoint = null;
1711 IClientAPI client = null;
1712
1713 try
1714 {
1715 object[] array = (object[])o;
1716 endPoint = (IPEndPoint)array[0];
1717 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
1718
1719 // Determine which agent this packet came from
1720 int count = 20;
1721 bool ready = false;
1722 while (!ready && count-- > 0)
1723 {
1724 if (m_scene.TryGetClient(endPoint, out client) && client.IsActive && client.SceneAgent != null)
1725 {
1726 LLClientView llClientView = (LLClientView)client;
1727 LLUDPClient udpClient = llClientView.UDPClient;
1728 if (udpClient != null && udpClient.IsConnected)
1729 ready = true;
1730 else
1731 {
1732 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)");
1733 Thread.Sleep(200);
1734 }
1735 }
1736 else
1737 {
1738 m_log.Debug("[LLUDPSERVER]: Received a CompleteMovementIntoRegion in " + m_scene.RegionInfo.RegionName + " (not ready yet)");
1739 Thread.Sleep(200);
1740 }
1741 }
1742
1743 if (client == null)
1744 return;
1745
1746 IncomingPacket incomingPacket1;
1747
1748 // Inbox insertion
1749 if (UsePools)
1750 {
1751 incomingPacket1 = m_incomingPacketPool.GetObject();
1752 incomingPacket1.Client = (LLClientView)client;
1753 incomingPacket1.Packet = packet;
1754 }
1755 else
1756 {
1757 incomingPacket1 = new IncomingPacket((LLClientView)client, packet);
1758 }
1759
1760 packetInbox.Enqueue(incomingPacket1);
1761 }
1762 catch (Exception e)
1763 {
1764 m_log.ErrorFormat(
1765 "[LLUDPSERVER]: CompleteMovementIntoRegion handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1766 endPoint != null ? endPoint.ToString() : "n/a",
1767 client != null ? client.Name : "unknown",
1768 client != null ? client.AgentId.ToString() : "unknown",
1769 e.Message,
1770 e.StackTrace);
1771 }
1772 }
1773
1479 /// <summary> 1774 /// <summary>
1480 /// Send an ack immediately to the given endpoint. 1775 /// Send an ack immediately to the given endpoint.
1481 /// </summary> 1776 /// </summary>
@@ -1544,6 +1839,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1544 1839
1545 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 1840 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
1546 client.OnLogout += LogoutHandler; 1841 client.OnLogout += LogoutHandler;
1842 client.DebugPacketLevel = DefaultClientPacketDebugLevel;
1547 1843
1548 ((LLClientView)client).DisableFacelights = m_disableFacelights; 1844 ((LLClientView)client).DisableFacelights = m_disableFacelights;
1549 1845
@@ -1562,18 +1858,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1562 /// regular client pings. 1858 /// regular client pings.
1563 /// </remarks> 1859 /// </remarks>
1564 /// <param name='client'></param> 1860 /// <param name='client'></param>
1565 private void DeactivateClientDueToTimeout(LLClientView client) 1861 /// <param name='timeoutTicks'></param>
1862 private void DeactivateClientDueToTimeout(LLClientView client, int timeoutTicks)
1566 { 1863 {
1567 lock (client.CloseSyncLock) 1864 lock (client.CloseSyncLock)
1568 { 1865 {
1866 ClientLogoutsDueToNoReceives++;
1867
1569 m_log.WarnFormat( 1868 m_log.WarnFormat(
1570 "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", 1869 "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
1571 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); 1870 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name);
1572
1573 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
1574 1871
1575 if (!client.SceneAgent.IsChildAgent) 1872 if (!client.SceneAgent.IsChildAgent)
1576 client.Kick("Simulator logged you out due to connection timeout"); 1873 client.Kick("Simulator logged you out due to connection timeout.");
1577 1874
1578 client.CloseWithoutChecks(true); 1875 client.CloseWithoutChecks(true);
1579 } 1876 }
@@ -1592,6 +1889,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1592 { 1889 {
1593 IncomingPacket incomingPacket = null; 1890 IncomingPacket incomingPacket = null;
1594 1891
1892 /*
1595 // HACK: This is a test to try and rate limit packet handling on Mono. 1893 // HACK: This is a test to try and rate limit packet handling on Mono.
1596 // If it works, a more elegant solution can be devised 1894 // If it works, a more elegant solution can be devised
1597 if (Util.FireAndForgetCount() < 2) 1895 if (Util.FireAndForgetCount() < 2)
@@ -1599,6 +1897,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1599 //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping"); 1897 //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping");
1600 Thread.Sleep(30); 1898 Thread.Sleep(30);
1601 } 1899 }
1900 */
1602 1901
1603 if (packetInbox.Dequeue(100, ref incomingPacket)) 1902 if (packetInbox.Dequeue(100, ref incomingPacket))
1604 { 1903 {
@@ -1694,8 +1993,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1694 1993
1695 // If nothing was sent, sleep for the minimum amount of time before a 1994 // If nothing was sent, sleep for the minimum amount of time before a
1696 // token bucket could get more tokens 1995 // token bucket could get more tokens
1996 //if (!m_packetSent)
1997 // Thread.Sleep((int)TickCountResolution);
1998 //
1999 // Instead, now wait for data present to be explicitly signalled. Evidence so far is that with
2000 // modern mono it reduces CPU base load since there is no more continuous polling.
1697 if (!m_packetSent) 2001 if (!m_packetSent)
1698 Thread.Sleep((int)TickCountResolution); 2002 m_dataPresentEvent.WaitOne(100);
1699 2003
1700 Watchdog.UpdateThread(); 2004 Watchdog.UpdateThread();
1701 } 2005 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 7035e38..48c5b37 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -78,6 +78,36 @@ namespace OpenMetaverse
78 public bool IsRunningOutbound { get; private set; } 78 public bool IsRunningOutbound { get; private set; }
79 79
80 /// <summary> 80 /// <summary>
81 /// Number of UDP receives.
82 /// </summary>
83 public int UdpReceives { get; private set; }
84
85 /// <summary>
86 /// Number of UDP sends
87 /// </summary>
88 public int UdpSends { get; private set; }
89
90 /// <summary>
91 /// Number of receives over which to establish a receive time average.
92 /// </summary>
93 private readonly static int s_receiveTimeSamples = 500;
94
95 /// <summary>
96 /// Current number of samples taken to establish a receive time average.
97 /// </summary>
98 private int m_currentReceiveTimeSamples;
99
100 /// <summary>
101 /// Cumulative receive time for the sample so far.
102 /// </summary>
103 private int m_receiveTicksInCurrentSamplePeriod;
104
105 /// <summary>
106 /// The average time taken for each require receive in the last sample.
107 /// </summary>
108 public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
109
110 /// <summary>
81 /// Default constructor 111 /// Default constructor
82 /// </summary> 112 /// </summary>
83 /// <param name="bindAddress">Local IP address to bind the server to</param> 113 /// <param name="bindAddress">Local IP address to bind the server to</param>
@@ -111,6 +141,8 @@ namespace OpenMetaverse
111 141
112 if (!IsRunningInbound) 142 if (!IsRunningInbound)
113 { 143 {
144 m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop");
145
114 const int SIO_UDP_CONNRESET = -1744830452; 146 const int SIO_UDP_CONNRESET = -1744830452;
115 147
116 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 148 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
@@ -151,6 +183,8 @@ namespace OpenMetaverse
151 /// </summary> 183 /// </summary>
152 public void StartOutbound() 184 public void StartOutbound()
153 { 185 {
186 m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
187
154 IsRunningOutbound = true; 188 IsRunningOutbound = true;
155 } 189 }
156 190
@@ -158,10 +192,8 @@ namespace OpenMetaverse
158 { 192 {
159 if (IsRunningInbound) 193 if (IsRunningInbound)
160 { 194 {
161 // wait indefinitely for a writer lock. Once this is called, the .NET runtime 195 m_log.DebugFormat("[UDPBASE]: Stopping inbound UDP loop");
162 // will deny any more reader locks, in effect blocking all other send/receive 196
163 // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
164 // threads that the socket is closed.
165 IsRunningInbound = false; 197 IsRunningInbound = false;
166 m_udpSocket.Close(); 198 m_udpSocket.Close();
167 } 199 }
@@ -169,6 +201,8 @@ namespace OpenMetaverse
169 201
170 public void StopOutbound() 202 public void StopOutbound()
171 { 203 {
204 m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
205
172 IsRunningOutbound = false; 206 IsRunningOutbound = false;
173 } 207 }
174 208
@@ -267,6 +301,8 @@ namespace OpenMetaverse
267 // to AsyncBeginReceive 301 // to AsyncBeginReceive
268 if (IsRunningInbound) 302 if (IsRunningInbound)
269 { 303 {
304 UdpReceives++;
305
270 // Asynchronous mode will start another receive before the 306 // Asynchronous mode will start another receive before the
271 // callback for this packet is even fired. Very parallel :-) 307 // callback for this packet is even fired. Very parallel :-)
272 if (m_asyncPacketHandling) 308 if (m_asyncPacketHandling)
@@ -278,6 +314,8 @@ namespace OpenMetaverse
278 314
279 try 315 try
280 { 316 {
317 int startTick = Util.EnvironmentTickCount();
318
281 // get the length of data actually read from the socket, store it with the 319 // get the length of data actually read from the socket, store it with the
282 // buffer 320 // buffer
283 buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint); 321 buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
@@ -285,6 +323,23 @@ namespace OpenMetaverse
285 // call the abstract method PacketReceived(), passing the buffer that 323 // call the abstract method PacketReceived(), passing the buffer that
286 // has just been filled from the socket read. 324 // has just been filled from the socket read.
287 PacketReceived(buffer); 325 PacketReceived(buffer);
326
327 // If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
328 // then a particular stat may be inaccurate due to a race condition. We won't worry about this
329 // since this should be rare and won't cause a runtime problem.
330 if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
331 {
332 AverageReceiveTicksForLastSamplePeriod
333 = (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
334
335 m_receiveTicksInCurrentSamplePeriod = 0;
336 m_currentReceiveTimeSamples = 0;
337 }
338 else
339 {
340 m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
341 m_currentReceiveTimeSamples++;
342 }
288 } 343 }
289 catch (SocketException) { } 344 catch (SocketException) { }
290 catch (ObjectDisposedException) { } 345 catch (ObjectDisposedException) { }
@@ -298,14 +353,13 @@ namespace OpenMetaverse
298 if (!m_asyncPacketHandling) 353 if (!m_asyncPacketHandling)
299 AsyncBeginReceive(); 354 AsyncBeginReceive();
300 } 355 }
301
302 } 356 }
303 } 357 }
304 358
305 public void AsyncBeginSend(UDPPacketBuffer buf) 359 public void AsyncBeginSend(UDPPacketBuffer buf)
306 { 360 {
307 if (IsRunningOutbound) 361// if (IsRunningOutbound)
308 { 362// {
309 try 363 try
310 { 364 {
311 m_udpSocket.BeginSendTo( 365 m_udpSocket.BeginSendTo(
@@ -319,7 +373,7 @@ namespace OpenMetaverse
319 } 373 }
320 catch (SocketException) { } 374 catch (SocketException) { }
321 catch (ObjectDisposedException) { } 375 catch (ObjectDisposedException) { }
322 } 376// }
323 } 377 }
324 378
325 void AsyncEndSend(IAsyncResult result) 379 void AsyncEndSend(IAsyncResult result)
@@ -328,6 +382,8 @@ namespace OpenMetaverse
328 { 382 {
329// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; 383// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
330 m_udpSocket.EndSendTo(result); 384 m_udpSocket.EndSendTo(result);
385
386 UdpSends++;
331 } 387 }
332 catch (SocketException) { } 388 catch (SocketException) { }
333 catch (ObjectDisposedException) { } 389 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 556df30..b47ff54 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -33,6 +33,7 @@ using NUnit.Framework;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.Packets; 34using OpenMetaverse.Packets;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common; 38using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock; 39using OpenSim.Tests.Common.Mock;
@@ -69,6 +70,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
69 { 70 {
70 base.SetUp(); 71 base.SetUp();
71 m_scene = new SceneHelpers().SetupScene(); 72 m_scene = new SceneHelpers().SetupScene();
73 StatsManager.SimExtraStats = new SimExtraStatsCollector();
72 } 74 }
73 75
74 /// <summary> 76 /// <summary>
@@ -210,8 +212,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
210 212
211 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); 213 ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
212 Assert.That(spAfterAckTimeout, Is.Null); 214 Assert.That(spAfterAckTimeout, Is.Null);
213
214// TestHelpers.DisableLogging();
215 } 215 }
216 216
217// /// <summary> 217// /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
index 7d9f581..83144e3 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -73,8 +73,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
73 } 73 }
74 74
75 [SetUp] 75 [SetUp]
76 public void SetUp() 76 public override void SetUp()
77 { 77 {
78 base.SetUp();
79
78 UUID userId = TestHelpers.ParseTail(0x3); 80 UUID userId = TestHelpers.ParseTail(0x3);
79 81
80 J2KDecoderModule j2kdm = new J2KDecoderModule(); 82 J2KDecoderModule j2kdm = new J2KDecoderModule();