aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs136
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs27
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs618
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs36
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs20
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs2
-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.cs166
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs115
14 files changed, 549 insertions, 618 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
new file mode 100644
index 0000000..bbadc55
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
@@ -0,0 +1,136 @@
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 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AvatarPickerSearchModule")]
53 public class AvatarPickerSearchModule : INonSharedRegionModule
54 {
55// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private Scene m_scene;
58 private IPeople m_People;
59 private bool m_Enabled = false;
60
61 private string m_URL;
62
63 #region ISharedRegionModule Members
64
65 public void Initialise(IConfigSource source)
66 {
67 IConfig config = source.Configs["ClientStack.LindenCaps"];
68 if (config == null)
69 return;
70
71 m_URL = config.GetString("Cap_AvatarPickerSearch", string.Empty);
72 // Cap doesn't exist
73 if (m_URL != string.Empty)
74 m_Enabled = true;
75 }
76
77 public void AddRegion(Scene s)
78 {
79 if (!m_Enabled)
80 return;
81
82 m_scene = s;
83 }
84
85 public void RemoveRegion(Scene s)
86 {
87 if (!m_Enabled)
88 return;
89
90 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
91 m_scene = null;
92 }
93
94 public void RegionLoaded(Scene s)
95 {
96 if (!m_Enabled)
97 return;
98
99 m_People = m_scene.RequestModuleInterface<IPeople>();
100 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
101 }
102
103 public void PostInitialise()
104 {
105 }
106
107 public void Close() { }
108
109 public string Name { get { return "AvatarPickerSearchModule"; } }
110
111 public Type ReplaceableInterface
112 {
113 get { return null; }
114 }
115
116 #endregion
117
118 public void RegisterCaps(UUID agentID, Caps caps)
119 {
120 UUID capID = UUID.Random();
121
122 if (m_URL == "localhost")
123 {
124// m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
125 caps.RegisterHandler(
126 "AvatarPickerSearch",
127 new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name"));
128 }
129 else
130 {
131 // m_log.DebugFormat("[AVATAR PICKER SEARCH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
132 caps.RegisterHandler("AvatarPickerSearch", m_URL);
133 }
134 }
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 8241e07..613bc24 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
@@ -748,6 +743,10 @@ namespace OpenSim.Region.ClientStack.Linden
748 inType = (sbyte)InventoryType.Sound; 743 inType = (sbyte)InventoryType.Sound;
749 assType = (sbyte)AssetType.Sound; 744 assType = (sbyte)AssetType.Sound;
750 } 745 }
746 else if (inventoryType == "snapshot")
747 {
748 inType = (sbyte)InventoryType.Snapshot;
749 }
751 else if (inventoryType == "animation") 750 else if (inventoryType == "animation")
752 { 751 {
753 inType = (sbyte)InventoryType.Animation; 752 inType = (sbyte)InventoryType.Animation;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index eb40eb1..ca6c3ca 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -65,12 +65,18 @@ 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>();
71 78
72 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); 79 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
73 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
74 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); 80 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
75 81
76 #region INonSharedRegionModule methods 82 #region INonSharedRegionModule methods
@@ -84,7 +90,6 @@ namespace OpenSim.Region.ClientStack.Linden
84 scene.RegisterModuleInterface<IEventQueue>(this); 90 scene.RegisterModuleInterface<IEventQueue>(this);
85 91
86 scene.EventManager.OnClientClosed += ClientClosed; 92 scene.EventManager.OnClientClosed += ClientClosed;
87 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
88 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 93 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
89 94
90 MainConsole.Instance.Commands.AddCommand( 95 MainConsole.Instance.Commands.AddCommand(
@@ -113,7 +118,6 @@ namespace OpenSim.Region.ClientStack.Linden
113 return; 118 return;
114 119
115 scene.EventManager.OnClientClosed -= ClientClosed; 120 scene.EventManager.OnClientClosed -= ClientClosed;
116 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
117 scene.EventManager.OnRegisterCaps -= OnRegisterCaps; 121 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
118 122
119 scene.UnregisterModuleInterface<IEventQueue>(this); 123 scene.UnregisterModuleInterface<IEventQueue>(this);
@@ -172,29 +176,6 @@ namespace OpenSim.Region.ClientStack.Linden
172 } 176 }
173 177
174 /// <summary> 178 /// <summary>
175 /// Always returns a valid queue
176 /// </summary>
177 /// <param name="agentId"></param>
178 /// <returns></returns>
179 private Queue<OSD> TryGetQueue(UUID agentId)
180 {
181 lock (queues)
182 {
183 if (!queues.ContainsKey(agentId))
184 {
185 /*
186 m_log.DebugFormat(
187 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
188 agentId, m_scene.RegionInfo.RegionName);
189 */
190 queues[agentId] = new Queue<OSD>();
191 }
192
193 return queues[agentId];
194 }
195 }
196
197 /// <summary>
198 /// May return a null queue 179 /// May return a null queue
199 /// </summary> 180 /// </summary>
200 /// <param name="agentId"></param> 181 /// <param name="agentId"></param>
@@ -221,8 +202,17 @@ namespace OpenSim.Region.ClientStack.Linden
221 { 202 {
222 Queue<OSD> queue = GetQueue(avatarID); 203 Queue<OSD> queue = GetQueue(avatarID);
223 if (queue != null) 204 if (queue != null)
205 {
224 lock (queue) 206 lock (queue)
225 queue.Enqueue(ev); 207 queue.Enqueue(ev);
208 }
209 else
210 {
211 OSDMap evMap = (OSDMap)ev;
212 m_log.WarnFormat(
213 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}",
214 avatarID, evMap["message"], m_scene.Name);
215 }
226 } 216 }
227 catch (NullReferenceException e) 217 catch (NullReferenceException e)
228 { 218 {
@@ -237,77 +227,22 @@ namespace OpenSim.Region.ClientStack.Linden
237 227
238 private void ClientClosed(UUID agentID, Scene scene) 228 private void ClientClosed(UUID agentID, Scene scene)
239 { 229 {
240// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 230 //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 231
248 lock (queues) 232 lock (queues)
249 {
250 queues.Remove(agentID); 233 queues.Remove(agentID);
251 }
252 234
253 List<UUID> removeitems = new List<UUID>();
254 lock (m_AvatarQueueUUIDMapping) 235 lock (m_AvatarQueueUUIDMapping)
255 { 236 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 237
270 string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); 238 lock (m_ids)
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
279 UUID searchval = UUID.Zero;
280
281 removeitems.Clear();
282
283 lock (m_QueueUUIDAvatarMapping)
284 { 239 {
285 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys) 240 if (!m_ids.ContainsKey(agentID))
286 { 241 m_ids.Remove(agentID);
287 searchval = m_QueueUUIDAvatarMapping[ky];
288
289 if (searchval == agentID)
290 {
291 removeitems.Add(ky);
292 }
293 }
294
295 foreach (UUID ky in removeitems)
296 m_QueueUUIDAvatarMapping.Remove(ky);
297 } 242 }
298 }
299 243
300 private void MakeChildAgent(ScenePresence avatar) 244 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
301 { 245
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 } 246 }
312 247
313 /// <summary> 248 /// <summary>
@@ -322,85 +257,109 @@ namespace OpenSim.Region.ClientStack.Linden
322 public void OnRegisterCaps(UUID agentID, Caps caps) 257 public void OnRegisterCaps(UUID agentID, Caps caps)
323 { 258 {
324 // Register an event queue for the client 259 // Register an event queue for the client
325 260 m_log.DebugFormat(
326 //m_log.DebugFormat( 261 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
327 // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 262 agentID, caps, m_scene.RegionInfo.RegionName);
328 // agentID, caps, m_scene.RegionInfo.RegionName);
329
330 // Let's instantiate a Queue for this agent right now
331 TryGetQueue(agentID);
332 263
333 UUID eventQueueGetUUID; 264 UUID eventQueueGetUUID;
265 Queue<OSD> queue;
266 Random rnd = new Random(Environment.TickCount);
267 int nrnd = rnd.Next(30000000);
268 if (nrnd < 0)
269 nrnd = -nrnd;
334 270
335 lock (m_AvatarQueueUUIDMapping) 271 lock (queues)
336 { 272 {
337 // Reuse open queues. The client does! 273 if (queues.ContainsKey(agentID))
338 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 274 queue = queues[agentID];
275 else
276 queue = null;
277
278 if (queue == null)
339 { 279 {
340 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 280 queue = new Queue<OSD>();
341 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 281 queues[agentID] = queue;
282
283 // push markers to handle old responses still waiting
284 // this will cost at most viewer getting two forced noevents
285 // even being a new queue better be safe
286 queue.Enqueue(null);
287 queue.Enqueue(null); // one should be enough
288
289 lock (m_AvatarQueueUUIDMapping)
290 {
291 eventQueueGetUUID = UUID.Random();
292 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
293 {
294 // oops this should not happen ?
295 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
296 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
297 }
298 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
299 }
300 lock (m_ids)
301 {
302 if (!m_ids.ContainsKey(agentID))
303 m_ids.Add(agentID, nrnd);
304 else
305 m_ids[agentID] = nrnd;
306 }
342 } 307 }
343 else 308 else
344 { 309 {
345 eventQueueGetUUID = UUID.Random(); 310 // push markers to handle old responses still waiting
346 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 311 // this will cost at most viewer getting two forced noevents
312 // even being a new queue better be safe
313 queue.Enqueue(null);
314 queue.Enqueue(null); // one should be enough
315
316 // reuse or not to reuse TODO FIX
317 lock (m_AvatarQueueUUIDMapping)
318 {
319 // Reuse open queues. The client does!
320 // Its reuse caps path not queues those are been reused already
321 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
322 {
323 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
324 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
325 }
326 else
327 {
328 eventQueueGetUUID = UUID.Random();
329 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
330 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
331 }
332 }
333 lock (m_ids)
334 {
335 // change to negative numbers so they are changed at end of sending first marker
336 // old data on a queue may be sent on a response for a new caps
337 // but at least will be sent with coerent IDs
338 if (!m_ids.ContainsKey(agentID))
339 m_ids.Add(agentID, -nrnd); // should not happen
340 else
341 m_ids[agentID] = -m_ids[agentID];
342 }
347 } 343 }
348 } 344 }
349 345
350 lock (m_QueueUUIDAvatarMapping) 346 caps.RegisterPollHandler(
351 { 347 "EventQueueGet",
352 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) 348 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
353 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
354 }
355
356 lock (m_AvatarQueueUUIDMapping)
357 {
358 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
359 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
360 }
361
362 string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
363
364 // Register this as a caps handler
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
385 Random rnd = new Random(Environment.TickCount);
386 lock (m_ids)
387 {
388 if (!m_ids.ContainsKey(agentID))
389 m_ids.Add(agentID, rnd.Next(30000000));
390 }
391 } 349 }
392 350
393 public bool HasEvents(UUID requestID, UUID agentID) 351 public bool HasEvents(UUID requestID, UUID agentID)
394 { 352 {
395 // Don't use this, because of race conditions at agent closing time
396 //Queue<OSD> queue = TryGetQueue(agentID);
397
398 Queue<OSD> queue = GetQueue(agentID); 353 Queue<OSD> queue = GetQueue(agentID);
399 if (queue != null) 354 if (queue != null)
400 lock (queue) 355 lock (queue)
356 {
357 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
401 return queue.Count > 0; 358 return queue.Count > 0;
359 }
402 360
403 return false; 361 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
362 return true;
404 } 363 }
405 364
406 /// <summary> 365 /// <summary>
@@ -414,65 +373,80 @@ namespace OpenSim.Region.ClientStack.Linden
414 OSDMap ev = (OSDMap)element; 373 OSDMap ev = (OSDMap)element;
415 m_log.DebugFormat( 374 m_log.DebugFormat(
416 "Eq OUT {0,-30} to {1,-20} {2,-20}", 375 "Eq OUT {0,-30} to {1,-20} {2,-20}",
417 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); 376 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
418 } 377 }
419 } 378 }
420 379
421 public Hashtable GetEvents(UUID requestID, UUID pAgentId) 380 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
422 { 381 {
423 if (DebugLevel >= 2) 382 if (DebugLevel >= 2)
424 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); 383 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
425 384
426 Queue<OSD> queue = TryGetQueue(pAgentId); 385 Queue<OSD> queue = GetQueue(pAgentId);
427 OSD element; 386 if (queue == null)
428 lock (queue)
429 { 387 {
430 if (queue.Count == 0) 388 return NoEvents(requestID, pAgentId);
431 return NoEvents(requestID, pAgentId);
432 element = queue.Dequeue(); // 15s timeout
433 } 389 }
434 390
391 OSD element = null;;
392 OSDArray array = new OSDArray();
435 int thisID = 0; 393 int thisID = 0;
436 lock (m_ids) 394 bool negativeID = false;
437 thisID = m_ids[pAgentId];
438 395
439 OSDArray array = new OSDArray(); 396 lock (queue)
440 if (element == null) // didn't have an event in 15s
441 {
442 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
443 array.Add(EventQueueHelper.KeepAliveEvent());
444 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
445 }
446 else
447 { 397 {
448 if (DebugLevel > 0) 398 if (queue.Count == 0)
449 LogOutboundDebugMessage(element, pAgentId); 399 return NoEvents(requestID, pAgentId);
450 400
451 array.Add(element); 401 lock (m_ids)
402 thisID = m_ids[pAgentId];
452 403
453 lock (queue) 404 if (thisID < 0)
454 { 405 {
455 while (queue.Count > 0) 406 negativeID = true;
456 { 407 thisID = -thisID;
457 element = queue.Dequeue(); 408 }
409
410 while (queue.Count > 0)
411 {
412 element = queue.Dequeue();
413 // add elements until a marker is found
414 // so they get into a response
415 if (element == null)
416 break;
417 if (DebugLevel > 0)
418 LogOutboundDebugMessage(element, pAgentId);
419 array.Add(element);
420 thisID++;
421 }
422 }
458 423
459 if (DebugLevel > 0) 424 OSDMap events = null;
460 LogOutboundDebugMessage(element, pAgentId);
461 425
462 array.Add(element); 426 if (array.Count > 0)
463 thisID++; 427 {
464 } 428 events = new OSDMap();
465 } 429 events.Add("events", array);
430 events.Add("id", new OSDInteger(thisID));
466 } 431 }
467 432
468 OSDMap events = new OSDMap(); 433 if (negativeID && element == null)
469 events.Add("events", array); 434 {
435 Random rnd = new Random(Environment.TickCount);
436 thisID = rnd.Next(30000000);
437 if (thisID < 0)
438 thisID = -thisID;
439 }
470 440
471 events.Add("id", new OSDInteger(thisID));
472 lock (m_ids) 441 lock (m_ids)
473 { 442 {
474 m_ids[pAgentId] = thisID + 1; 443 m_ids[pAgentId] = thisID + 1;
475 } 444 }
445
446 // if there where no elements before a marker send a NoEvents
447 if (array.Count == 0)
448 return NoEvents(requestID, pAgentId);
449
476 Hashtable responsedata = new Hashtable(); 450 Hashtable responsedata = new Hashtable();
477 responsedata["int_response_code"] = 200; 451 responsedata["int_response_code"] = 200;
478 responsedata["content_type"] = "application/xml"; 452 responsedata["content_type"] = "application/xml";
@@ -495,289 +469,53 @@ namespace OpenSim.Region.ClientStack.Linden
495 responsedata["http_protocol_version"] = "HTTP/1.0"; 469 responsedata["http_protocol_version"] = "HTTP/1.0";
496 return responsedata; 470 return responsedata;
497 } 471 }
498 472
499// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
500// {
501// // TODO: this has to be redone to not busy-wait (and block the thread),
502// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
503//
504//// if (m_log.IsDebugEnabled)
505//// {
506//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
507//// foreach (object key in request.Keys)
508//// {
509//// debug += key.ToString() + "=" + request[key].ToString() + " ";
510//// }
511//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
512//// }
513//
514// Queue<OSD> queue = TryGetQueue(agentID);
515// OSD element;
516//
517// lock (queue)
518// element = queue.Dequeue(); // 15s timeout
519//
520// Hashtable responsedata = new Hashtable();
521//
522// int thisID = 0;
523// lock (m_ids)
524// thisID = m_ids[agentID];
525//
526// if (element == null)
527// {
528// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
529// if (thisID == -1) // close-request
530// {
531// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
532// responsedata["int_response_code"] = 404; //501; //410; //404;
533// responsedata["content_type"] = "text/plain";
534// responsedata["keepalive"] = false;
535// responsedata["str_response_string"] = "Closed EQG";
536// return responsedata;
537// }
538// responsedata["int_response_code"] = 502;
539// responsedata["content_type"] = "text/plain";
540// responsedata["keepalive"] = false;
541// responsedata["str_response_string"] = "Upstream error: ";
542// responsedata["error_status_text"] = "Upstream error:";
543// responsedata["http_protocol_version"] = "HTTP/1.0";
544// return responsedata;
545// }
546//
547// OSDArray array = new OSDArray();
548// if (element == null) // didn't have an event in 15s
549// {
550// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
551// array.Add(EventQueueHelper.KeepAliveEvent());
552// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
553// }
554// else
555// {
556// array.Add(element);
557//
558// if (element is OSDMap)
559// {
560// OSDMap ev = (OSDMap)element;
561// m_log.DebugFormat(
562// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
563// ev["message"], m_scene.GetScenePresence(agentID).Name);
564// }
565//
566// lock (queue)
567// {
568// while (queue.Count > 0)
569// {
570// element = queue.Dequeue();
571//
572// if (element is OSDMap)
573// {
574// OSDMap ev = (OSDMap)element;
575// m_log.DebugFormat(
576// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
577// ev["message"], m_scene.GetScenePresence(agentID).Name);
578// }
579//
580// array.Add(element);
581// thisID++;
582// }
583// }
584// }
585//
586// OSDMap events = new OSDMap();
587// events.Add("events", array);
588//
589// events.Add("id", new OSDInteger(thisID));
590// lock (m_ids)
591// {
592// m_ids[agentID] = thisID + 1;
593// }
594//
595// responsedata["int_response_code"] = 200;
596// responsedata["content_type"] = "application/xml";
597// responsedata["keepalive"] = false;
598// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
599//
600// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
601//
602// return responsedata;
603// }
604
605// public Hashtable EventQueuePath2(Hashtable request)
606// {
607// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
608// // pull off the last "/" in the path.
609// Hashtable responsedata = new Hashtable();
610// capuuid = capuuid.Substring(0, capuuid.Length - 1);
611// capuuid = capuuid.Replace("/CAPS/EQG/", "");
612// UUID AvatarID = UUID.Zero;
613// UUID capUUID = UUID.Zero;
614//
615// // parse the path and search for the avatar with it registered
616// if (UUID.TryParse(capuuid, out capUUID))
617// {
618// lock (m_QueueUUIDAvatarMapping)
619// {
620// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
621// {
622// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
623// }
624// }
625//
626// if (AvatarID != UUID.Zero)
627// {
628// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
629// }
630// else
631// {
632// responsedata["int_response_code"] = 404;
633// responsedata["content_type"] = "text/plain";
634// responsedata["keepalive"] = false;
635// responsedata["str_response_string"] = "Not Found";
636// responsedata["error_status_text"] = "Not Found";
637// responsedata["http_protocol_version"] = "HTTP/1.0";
638// return responsedata;
639// // return 404
640// }
641// }
642// else
643// {
644// responsedata["int_response_code"] = 404;
645// responsedata["content_type"] = "text/plain";
646// responsedata["keepalive"] = false;
647// responsedata["str_response_string"] = "Not Found";
648// responsedata["error_status_text"] = "Not Found";
649// responsedata["http_protocol_version"] = "HTTP/1.0";
650// return responsedata;
651// // return 404
652// }
653// }
654
655 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
656 {
657 // This is a fallback element to keep the client from loosing EventQueueGet
658 // Why does CAPS fail sometimes!?
659 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
660 string capuuid = path.Replace("/CAPS/EQG/","");
661 capuuid = capuuid.Substring(0, capuuid.Length - 1);
662
663// UUID AvatarID = UUID.Zero;
664 UUID capUUID = UUID.Zero;
665 if (UUID.TryParse(capuuid, out capUUID))
666 {
667/* Don't remove this yet code cleaners!
668 * Still testing this!
669 *
670 lock (m_QueueUUIDAvatarMapping)
671 {
672 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
673 {
674 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
675 }
676 }
677
678
679 if (AvatarID != UUID.Zero)
680 {
681 // Repair the CAP!
682 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
683 //string capsBase = "/CAPS/EQG/";
684 //caps.RegisterHandler("EventQueueGet",
685 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
686 //delegate(Hashtable m_dhttpMethod)
687 //{
688 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
689 //}));
690 // start new ID sequence.
691 Random rnd = new Random(System.Environment.TickCount);
692 lock (m_ids)
693 {
694 if (!m_ids.ContainsKey(AvatarID))
695 m_ids.Add(AvatarID, rnd.Next(30000000));
696 }
697
698
699 int thisID = 0;
700 lock (m_ids)
701 thisID = m_ids[AvatarID];
702
703 BlockingLLSDQueue queue = GetQueue(AvatarID);
704 OSDArray array = new OSDArray();
705 LLSD element = queue.Dequeue(15000); // 15s timeout
706 if (element == null)
707 {
708
709 array.Add(EventQueueHelper.KeepAliveEvent());
710 }
711 else
712 {
713 array.Add(element);
714 while (queue.Count() > 0)
715 {
716 array.Add(queue.Dequeue(1));
717 thisID++;
718 }
719 }
720 OSDMap events = new OSDMap();
721 events.Add("events", array);
722
723 events.Add("id", new LLSDInteger(thisID));
724
725 lock (m_ids)
726 {
727 m_ids[AvatarID] = thisID + 1;
728 }
729
730 return events;
731 }
732 else
733 {
734 return new LLSD();
735 }
736*
737*/
738 }
739 else
740 {
741 //return new LLSD();
742 }
743
744 return new OSDString("shutdown404!");
745 }
746
747 public void DisableSimulator(ulong handle, UUID avatarID) 473 public void DisableSimulator(ulong handle, UUID avatarID)
748 { 474 {
749 OSD item = EventQueueHelper.DisableSimulator(handle); 475 OSD item = EventQueueHelper.DisableSimulator(handle);
750 Enqueue(item, avatarID); 476 Enqueue(item, avatarID);
751 } 477 }
752 478
753 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID) 479 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
754 { 480 {
755 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint); 481 m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
482 "[EVENT QUEUE GET MODULE]", handle, avatarID, regionSizeX, regionSizeY);
483
484 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
756 Enqueue(item, avatarID); 485 Enqueue(item, avatarID);
757 } 486 }
758 487
759 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath) 488 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
489 ulong regionHandle, int regionSizeX, int regionSizeY)
760 { 490 {
761 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath); 491 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
492 "[EVENT QUEUE GET MODULE]", regionHandle, avatarID, regionSizeX, regionSizeY);
493 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
762 Enqueue(item, avatarID); 494 Enqueue(item, avatarID);
763 } 495 }
764 496
765 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, 497 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
766 IPEndPoint regionExternalEndPoint, 498 IPEndPoint regionExternalEndPoint,
767 uint locationID, uint flags, string capsURL, 499 uint locationID, uint flags, string capsURL,
768 UUID avatarID) 500 UUID avatarID, int regionSizeX, int regionSizeY)
769 { 501 {
502 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize={3},{4}>",
503 "[EVENT QUEUE GET MODULE]", regionHandle, avatarID, regionSizeX, regionSizeY);
504
770 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint, 505 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
771 locationID, flags, capsURL, avatarID); 506 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
772 Enqueue(item, avatarID); 507 Enqueue(item, avatarID);
773 } 508 }
774 509
775 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, 510 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
776 IPEndPoint newRegionExternalEndPoint, 511 IPEndPoint newRegionExternalEndPoint,
777 string capsURL, UUID avatarID, UUID sessionID) 512 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
778 { 513 {
514 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
515 "[EVENT QUEUE GET MODULE]", handle, avatarID, regionSizeX, regionSizeY);
516
779 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint, 517 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
780 capsURL, avatarID, sessionID); 518 capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
781 Enqueue(item, avatarID); 519 Enqueue(item, avatarID);
782 } 520 }
783 521
@@ -794,12 +532,12 @@ namespace OpenSim.Region.ClientStack.Linden
794 532
795 } 533 }
796 534
797 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 535 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
798 bool isModerator, bool textMute) 536 bool isModerator, bool textMute)
799 { 537 {
800 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 538 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
801 isModerator, textMute); 539 isModerator, textMute);
802 Enqueue(item, toAgent); 540 Enqueue(item, fromAgent);
803 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 541 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
804 } 542 }
805 543
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 7dcf137..3fb7de2 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -70,13 +70,15 @@ namespace OpenSim.Region.ClientStack.Linden
70 return llsdEvent; 70 return llsdEvent;
71 } 71 }
72 72
73 public static OSD EnableSimulator(ulong handle, IPEndPoint endPoint) 73 public static OSD EnableSimulator(ulong handle, IPEndPoint endPoint, int regionSizeX, int regionSizeY)
74 { 74 {
75 OSDMap llsdSimInfo = new OSDMap(3); 75 OSDMap llsdSimInfo = new OSDMap(5);
76 76
77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle))); 77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes())); 78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port)); 79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
80 llsdSimInfo.Add("RegionSizeX", new OSDInteger(regionSizeX));
81 llsdSimInfo.Add("RegionSizeY", new OSDInteger(regionSizeY));
80 82
81 OSDArray arr = new OSDArray(1); 83 OSDArray arr = new OSDArray(1);
82 arr.Add(llsdSimInfo); 84 arr.Add(llsdSimInfo);
@@ -104,7 +106,8 @@ namespace OpenSim.Region.ClientStack.Linden
104 106
105 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, 107 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
106 IPEndPoint newRegionExternalEndPoint, 108 IPEndPoint newRegionExternalEndPoint,
107 string capsURL, UUID agentID, UUID sessionID) 109 string capsURL, UUID agentID, UUID sessionID,
110 int regionSizeX, int regionSizeY)
108 { 111 {
109 OSDArray lookAtArr = new OSDArray(3); 112 OSDArray lookAtArr = new OSDArray(3);
110 lookAtArr.Add(OSD.FromReal(lookAt.X)); 113 lookAtArr.Add(OSD.FromReal(lookAt.X));
@@ -130,11 +133,13 @@ namespace OpenSim.Region.ClientStack.Linden
130 OSDArray agentDataArr = new OSDArray(1); 133 OSDArray agentDataArr = new OSDArray(1);
131 agentDataArr.Add(agentDataMap); 134 agentDataArr.Add(agentDataMap);
132 135
133 OSDMap regionDataMap = new OSDMap(4); 136 OSDMap regionDataMap = new OSDMap(6);
134 regionDataMap.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(handle))); 137 regionDataMap.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(handle)));
135 regionDataMap.Add("SeedCapability", OSD.FromString(capsURL)); 138 regionDataMap.Add("SeedCapability", OSD.FromString(capsURL));
136 regionDataMap.Add("SimIP", OSD.FromBinary(newRegionExternalEndPoint.Address.GetAddressBytes())); 139 regionDataMap.Add("SimIP", OSD.FromBinary(newRegionExternalEndPoint.Address.GetAddressBytes()));
137 regionDataMap.Add("SimPort", OSD.FromInteger(newRegionExternalEndPoint.Port)); 140 regionDataMap.Add("SimPort", OSD.FromInteger(newRegionExternalEndPoint.Port));
141 regionDataMap.Add("RegionSizeX", new OSDInteger(regionSizeX));
142 regionDataMap.Add("RegionSizeY", new OSDInteger(regionSizeY));
138 143
139 OSDArray regionDataArr = new OSDArray(1); 144 OSDArray regionDataArr = new OSDArray(1);
140 regionDataArr.Add(regionDataMap); 145 regionDataArr.Add(regionDataMap);
@@ -148,8 +153,9 @@ namespace OpenSim.Region.ClientStack.Linden
148 } 153 }
149 154
150 public static OSD TeleportFinishEvent( 155 public static OSD TeleportFinishEvent(
151 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, 156 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
152 uint locationID, uint flags, string capsURL, UUID agentID) 157 uint locationID, uint flags, string capsURL, UUID agentID,
158 int regionSizeX, int regionSizeY)
153 { 159 {
154 // not sure why flags get overwritten here 160 // not sure why flags get overwritten here
155 if ((flags & (uint)TeleportFlags.IsFlying) != 0) 161 if ((flags & (uint)TeleportFlags.IsFlying) != 0)
@@ -167,6 +173,8 @@ namespace OpenSim.Region.ClientStack.Linden
167 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); 173 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
168// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation 174// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
169 info.Add("TeleportFlags", OSD.FromUInteger(flags)); 175 info.Add("TeleportFlags", OSD.FromUInteger(flags));
176 info.Add("RegionSizeX", new OSDInteger(regionSizeX));
177 info.Add("RegionSizeY", new OSDInteger(regionSizeY));
170 178
171 OSDArray infoArr = new OSDArray(); 179 OSDArray infoArr = new OSDArray();
172 infoArr.Add(info); 180 infoArr.Add(info);
@@ -194,12 +202,18 @@ namespace OpenSim.Region.ClientStack.Linden
194 return BuildEvent("ScriptRunningReply", body); 202 return BuildEvent("ScriptRunningReply", body);
195 } 203 }
196 204
197 public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap) 205 public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap,
206 ulong regionHandle, int regionSizeX, int regionSizeY)
198 { 207 {
199 OSDMap body = new OSDMap(3); 208 OSDMap body = new OSDMap(6)
200 body.Add("agent-id", new OSDUUID(agentID)); 209 {
201 body.Add("sim-ip-and-port", new OSDString(simIpAndPort)); 210 {"agent-id", new OSDUUID(agentID)},
202 body.Add("seed-capability", new OSDString(seedcap)); 211 {"sim-ip-and-port", new OSDString(simIpAndPort)},
212 {"seed-capability", new OSDString(seedcap)},
213 {"region-handle", OSD.FromULong(regionHandle)},
214 {"region-size-x", OSD.FromInteger(regionSizeX)},
215 {"region-size-y", OSD.FromInteger(regionSizeY)}
216 };
203 217
204 return BuildEvent("EstablishAgentCommunication", body); 218 return BuildEvent("EstablishAgentCommunication", body);
205 } 219 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index 141af8a..9e24bce 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
76 } 76 }
77 77
78 [Test] 78 [Test]
79 public void AddForClient() 79 public void TestAddForClient()
80 { 80 {
81 TestHelpers.InMethod(); 81 TestHelpers.InMethod();
82// log4net.Config.XmlConfigurator.Configure(); 82// log4net.Config.XmlConfigurator.Configure();
@@ -88,15 +88,15 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
88 } 88 }
89 89
90 [Test] 90 [Test]
91 public void RemoveForClient() 91 public void TestRemoveForClient()
92 { 92 {
93 TestHelpers.InMethod(); 93 TestHelpers.InMethod();
94// log4net.Config.XmlConfigurator.Configure(); 94// TestHelpers.EnableLogging();
95 95
96 UUID spId = TestHelpers.ParseTail(0x1); 96 UUID spId = TestHelpers.ParseTail(0x1);
97 97
98 SceneHelpers.AddScenePresence(m_scene, spId); 98 SceneHelpers.AddScenePresence(m_scene, spId);
99 m_scene.IncomingCloseAgent(spId, false); 99 m_scene.CloseAgent(spId, false);
100 100
101 // TODO: Add more assertions for the other aspects of event queues 101 // TODO: Add more assertions for the other aspects of event queues
102 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 102 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
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 0570144..e053054 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -84,6 +84,8 @@ namespace OpenSim.Region.ClientStack.Linden
84 84
85 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>(); 85 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
86 86
87 private string m_URL;
88
87 #region ISharedRegionModule Members 89 #region ISharedRegionModule Members
88 90
89 public void Initialise(IConfigSource source) 91 public void Initialise(IConfigSource source)
@@ -215,7 +217,7 @@ namespace OpenSim.Region.ClientStack.Linden
215 private Scene m_scene; 217 private Scene m_scene;
216 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); 218 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000);
217 public PollServiceTextureEventArgs(UUID pId, Scene scene) : 219 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
218 base(null, null, null, null, pId, int.MaxValue) 220 base(null, "", null, null, null, pId, int.MaxValue)
219 { 221 {
220 m_scene = scene; 222 m_scene = scene;
221 // x is request id, y is userid 223 // x is request id, y is userid
@@ -368,7 +370,11 @@ namespace OpenSim.Region.ClientStack.Linden
368 port = MainServer.Instance.SSLPort; 370 port = MainServer.Instance.SSLPort;
369 protocol = "https"; 371 protocol = "https";
370 } 372 }
371 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); 373 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
374 if (handler != null)
375 handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", capUrl);
376 else
377 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
372 m_pollservices[agentID] = args; 378 m_pollservices[agentID] = args;
373 m_capsDict[agentID] = capUrl; 379 m_capsDict[agentID] = capUrl;
374 } 380 }
@@ -380,13 +386,11 @@ namespace OpenSim.Region.ClientStack.Linden
380 386
381 private void DeregisterCaps(UUID agentID, Caps caps) 387 private void DeregisterCaps(UUID agentID, Caps caps)
382 { 388 {
383 string capUrl;
384 PollServiceTextureEventArgs args; 389 PollServiceTextureEventArgs args;
385 if (m_capsDict.TryGetValue(agentID, out capUrl)) 390
386 { 391 MainServer.Instance.RemoveHTTPHandler("", m_URL);
387 MainServer.Instance.RemoveHTTPHandler("", capUrl); 392 m_capsDict.Remove(agentID);
388 m_capsDict.Remove(agentID); 393
389 }
390 if (m_pollservices.TryGetValue(agentID, out args)) 394 if (m_pollservices.TryGetValue(agentID, out args))
391 { 395 {
392 m_pollservices.Remove(agentID); 396 m_pollservices.Remove(agentID);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 92805e2..94f8bc1 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.Linden
155 Quaternion rotation = Quaternion.Identity; 155 Quaternion rotation = Quaternion.Identity;
156 Vector3 scale = Vector3.Zero; 156 Vector3 scale = Vector3.Zero;
157 int state = 0; 157 int state = 0;
158 int lastattach = 0;
158 159
159 if (r.Type != OSDType.Map) // not a proper req 160 if (r.Type != OSDType.Map) // not a proper req
160 return responsedata; 161 return responsedata;
@@ -224,6 +225,7 @@ namespace OpenSim.Region.ClientStack.Linden
224 225
225 ray_target_id = ObjMap["RayTargetId"].AsUUID(); 226 ray_target_id = ObjMap["RayTargetId"].AsUUID();
226 state = ObjMap["State"].AsInteger(); 227 state = ObjMap["State"].AsInteger();
228 lastattach = ObjMap["LastAttachPoint"].AsInteger();
227 try 229 try
228 { 230 {
229 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3(); 231 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3();
@@ -290,6 +292,7 @@ namespace OpenSim.Region.ClientStack.Linden
290 292
291 //session_id = rm["session_id"].AsUUID(); 293 //session_id = rm["session_id"].AsUUID();
292 state = rm["state"].AsInteger(); 294 state = rm["state"].AsInteger();
295 lastattach = rm["last_attach_point"].AsInteger();
293 try 296 try
294 { 297 {
295 ray_end = ((OSDArray)rm["ray_end"]).AsVector3(); 298 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
@@ -331,6 +334,7 @@ namespace OpenSim.Region.ClientStack.Linden
331 pbs.ProfileEnd = (ushort)profile_end; 334 pbs.ProfileEnd = (ushort)profile_end;
332 pbs.Scale = scale; 335 pbs.Scale = scale;
333 pbs.State = (byte)state; 336 pbs.State = (byte)state;
337 pbs.LastAttachPoint = (byte)lastattach;
334 338
335 SceneObjectGroup obj = null; ; 339 SceneObjectGroup obj = null; ;
336 340
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 55a503e..769fe28 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -277,6 +277,7 @@ namespace OpenSim.Region.ClientStack.Linden
277 pbs.ProfileEnd = (ushort) obj.ProfileEnd; 277 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
278 pbs.Scale = obj.Scale; 278 pbs.Scale = obj.Scale;
279 pbs.State = (byte) 0; 279 pbs.State = (byte) 0;
280 pbs.LastAttachPoint = (byte) 0;
280 SceneObjectPart prim = new SceneObjectPart(); 281 SceneObjectPart prim = new SceneObjectPart();
281 prim.UUID = UUID.Random(); 282 prim.UUID = UUID.Random();
282 prim.CreatorID = AgentId; 283 prim.CreatorID = AgentId;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
index 595d01a..112608b 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.6.*")] 32[assembly: AssemblyVersion("0.8.0.*")]
33 33
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..50e9275 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);
@@ -89,9 +96,7 @@ namespace OpenSim.Region.ClientStack.Linden
89 s.EventManager.OnRemovePresence -= DeRegisterPresence; 96 s.EventManager.OnRemovePresence -= DeRegisterPresence;
90 m_BakedTextureModule = null; 97 m_BakedTextureModule = null;
91 m_scene = null; 98 m_scene = null;
92 } 99 }
93
94
95 100
96 public void RegionLoaded(Scene s) 101 public void RegionLoaded(Scene s)
97 { 102 {
@@ -103,44 +108,58 @@ namespace OpenSim.Region.ClientStack.Linden
103 108
104 private void DeRegisterPresence(UUID agentId) 109 private void DeRegisterPresence(UUID agentId)
105 { 110 {
106 ScenePresence presence = null; 111// ScenePresence presence = null;
107 if (m_scene.TryGetScenePresence(agentId, out presence)) 112// if (m_scene.TryGetScenePresence(agentId, out presence))
108 { 113 {
109 presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings; 114// presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
110 } 115 }
111 116
112 } 117 }
113 118
114 private void RegisterNewPresence(ScenePresence presence) 119 private void RegisterNewPresence(ScenePresence presence)
115 { 120 {
116 presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; 121// presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
117
118 } 122 }
119 123
120 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) 124/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache()
121 { 125 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
122 int maxCacheitemsLoop = cacheItems.Length;
123 if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES)
124 {
125 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
126 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
127 }
128
129 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
130 if (cacheItems.Length > 0)
131 {
132 m_log.Debug("[Cacheitems]: " + cacheItems.Length);
133 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
134 {
135 m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
136 cacheItems[iter].TextureID);
137 }
138
139 ScenePresence p = null;
140 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
141 { 126 {
127 // if cacheItems.Length > 0 viewer is giving us current textures information.
128 // baked ones should had been uploaded and in assets cache as local itens
129
130
131 if (cacheItems.Length == 0)
132 return; // no textures information, nothing to do
133
134 ScenePresence p = null;
135 if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
136 return; // what are we doing if there is no presence to cache for?
137
138 if (p.IsDeleted)
139 return; // does this really work?
140
141 int maxCacheitemsLoop = cacheItems.Length;
142 if (maxCacheitemsLoop > 20)
143 {
144 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
145 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
146 }
147
148 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
149
150
151 // some nice debug
152 m_log.Debug("[Cacheitems]: " + cacheItems.Length);
153 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
154 {
155 m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
156 cacheItems[iter].TextureID);
157 }
158
159 // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper
142 160
143 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; 161 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
162
144 if (existingitems == null) 163 if (existingitems == null)
145 { 164 {
146 if (m_BakedTextureModule != null) 165 if (m_BakedTextureModule != null)
@@ -154,38 +173,22 @@ namespace OpenSim.Region.ClientStack.Linden
154 p.Appearance.WearableCacheItems = savedcache; 173 p.Appearance.WearableCacheItems = savedcache;
155 p.Appearance.WearableCacheItemsDirty = false; 174 p.Appearance.WearableCacheItemsDirty = false;
156 } 175 }
157
158 }
159 /*
160 * The following Catch types DO NOT WORK with m_BakedTextureModule.Get
161 * it jumps to the General Packet Exception Handler if you don't catch Exception!
162 *
163 catch (System.Net.Sockets.SocketException)
164 {
165 cacheItems = null;
166 }
167 catch (WebException)
168 {
169 cacheItems = null;
170 } 176 }
171 catch (InvalidOperationException) 177
172 {
173 cacheItems = null;
174 } */
175 catch (Exception) 178 catch (Exception)
176 { 179 {
177 // The service logs a sufficient error message. 180 // The service logs a sufficient error message.
178 } 181 }
179 182
180 183
181 if (savedcache != null) 184 if (savedcache != null)
182 existingitems = savedcache; 185 existingitems = savedcache;
183 } 186 }
184 } 187 }
188
185 // Existing items null means it's a fully new appearance 189 // Existing items null means it's a fully new appearance
186 if (existingitems == null) 190 if (existingitems == null)
187 { 191 {
188
189 for (int i = 0; i < maxCacheitemsLoop; i++) 192 for (int i = 0; i < maxCacheitemsLoop; i++)
190 { 193 {
191 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) 194 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
@@ -198,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden
198 AppearanceManager.DEFAULT_AVATAR_TEXTURE; 201 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
199 continue; 202 continue;
200 } 203 }
201 cacheItems[i].TextureID =face.TextureID; 204 cacheItems[i].TextureID = face.TextureID;
202 if (m_scene.AssetService != null) 205 if (m_scene.AssetService != null)
203 cacheItems[i].TextureAsset = 206 cacheItems[i].TextureAsset =
204 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); 207 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
@@ -207,15 +210,10 @@ namespace OpenSim.Region.ClientStack.Linden
207 { 210 {
208 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); 211 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
209 } 212 }
210
211
212 } 213 }
213 } 214 }
214 else 215 else
215 216 {
216
217 {
218 // for each uploaded baked texture
219 for (int i = 0; i < maxCacheitemsLoop; i++) 217 for (int i = 0; i < maxCacheitemsLoop; i++)
220 { 218 {
221 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) 219 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
@@ -246,23 +244,24 @@ namespace OpenSim.Region.ClientStack.Linden
246 } 244 }
247 } 245 }
248 } 246 }
249
250
251
252 p.Appearance.WearableCacheItems = cacheItems; 247 p.Appearance.WearableCacheItems = cacheItems;
253
254
255 248
256 if (m_BakedTextureModule != null) 249 if (m_BakedTextureModule != null)
257 { 250 {
258 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); 251 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
259 p.Appearance.WearableCacheItemsDirty = true; 252 p.Appearance.WearableCacheItemsDirty = true;
260 253
261 } 254 }
262 } 255 else
263 } 256 p.Appearance.WearableCacheItemsDirty = false;
264 }
265 257
258 for (int iter = 0; iter < maxCacheitemsLoop; iter++)
259 {
260 m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
261 cacheItems[iter].TextureID);
262 }
263 }
264 */
266 public void PostInitialise() 265 public void PostInitialise()
267 { 266 {
268 } 267 }
@@ -280,23 +279,28 @@ namespace OpenSim.Region.ClientStack.Linden
280 279
281 public void RegisterCaps(UUID agentID, Caps caps) 280 public void RegisterCaps(UUID agentID, Caps caps)
282 { 281 {
283 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( 282// UUID capID = UUID.Random();
284 caps, m_scene.AssetService, m_persistBakedTextures);
285
286
287
288 caps.RegisterHandler(
289 "UploadBakedTexture",
290 new RestStreamHandler(
291 "POST",
292 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
293 avatarhandler.UploadBakedTexture,
294 "UploadBakedTexture",
295 agentID.ToString()));
296 283
297 284 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
298 285 if (m_URL == "localhost")
286 {
287 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
288 caps, m_scene.AssetService, m_persistBakedTextures);
299 289
290 caps.RegisterHandler(
291 "UploadBakedTexture",
292 new RestStreamHandler(
293 "POST",
294 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
295 avatarhandler.UploadBakedTexture,
296 "UploadBakedTexture",
297 agentID.ToString()));
298
299 }
300 else
301 {
302 caps.RegisterHandler("UploadBakedTexture", m_URL);
303 }
300 } 304 }
301 } 305 }
302} \ No newline at end of file 306}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 707cc93..6fc35cd 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
@@ -278,53 +298,72 @@ namespace OpenSim.Region.ClientStack.Linden
278 requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); 298 requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
279 299
280 lock (responses) 300 lock (responses)
281 responses[requestID] = response; 301 responses[requestID] = response;
282 } 302 }
283 } 303 }
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 RegisterFetchDescendentsCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
288
289 // Register this as a poll service
290 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, agentID);
291
292 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
307 m_capsDict[agentID] = capUrl;
308 } 308 }
309 309
310 private void DeregisterCaps(UUID agentID, Caps caps) 310 private void RegisterFetchDescendentsCap(UUID agentID, Caps caps, string capName, string url)
311 { 311 {
312 string capUrl; 312 string capUrl;
313 313
314 if (m_capsDict.TryGetValue(agentID, out capUrl)) 314 // disable the cap clause
315 if (url == "")
316 {
317 return;
318 }
319 // handled by the simulator
320 else if (url == "localhost")
321 {
322 capUrl = "/CAPS/" + UUID.Random() + "/";
323
324 // Register this as a poll service
325 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(m_scene, capUrl, agentID);
326 args.Type = PollServiceEventArgs.EventType.Inventory;
327
328 caps.RegisterPollHandler(capName, args);
329 }
330 // external handler
331 else
315 { 332 {
316 MainServer.Instance.RemoveHTTPHandler("", capUrl); 333 capUrl = url;
317 m_capsDict.Remove(agentID); 334 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
335 if (handler != null)
336 handler.RegisterExternalUserCapsHandler(agentID,caps,capName,capUrl);
337 else
338 caps.RegisterHandler(capName, capUrl);
318 } 339 }
340
341 // m_log.DebugFormat(
342 // "[FETCH INVENTORY DESCENDENTS2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
343 // capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
319 } 344 }
320 345
346// private void DeregisterCaps(UUID agentID, Caps caps)
347// {
348// string capUrl;
349//
350// if (m_capsDict.TryGetValue(agentID, out capUrl))
351// {
352// MainServer.Instance.RemoveHTTPHandler("", capUrl);
353// m_capsDict.Remove(agentID);
354// }
355// }
356
321 private void DoInventoryRequests() 357 private void DoInventoryRequests()
322 { 358 {
323 while (true) 359 while (true)
324 { 360 {
361 Watchdog.UpdateThread();
362
325 aPollRequest poolreq = m_queue.Dequeue(); 363 aPollRequest poolreq = m_queue.Dequeue();
326 364
327 poolreq.thepoll.Process(poolreq); 365 if (poolreq != null && poolreq.thepoll != null)
366 poolreq.thepoll.Process(poolreq);
328 } 367 }
329 } 368 }
330 } 369 }