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/BunchOfCaps/BunchOfCaps.cs938
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs91
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs731
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs399
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs136
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs139
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs275
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs370
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs374
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs131
10 files changed, 3584 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
new file mode 100644
index 0000000..95713e9
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -0,0 +1,938 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Reflection;
6
7using OpenMetaverse;
8using Nini.Config;
9using log4net;
10
11using OpenSim.Framework;
12using OpenSim.Framework.Capabilities;
13using OpenSim.Region.Framework;
14using OpenSim.Region.Framework.Scenes;
15using OpenSim.Framework.Servers;
16using OpenSim.Framework.Servers.HttpServer;
17using OpenSim.Services.Interfaces;
18
19using Caps = OpenSim.Framework.Capabilities.Caps;
20
21namespace OpenSim.Region.ClientStack.Linden
22{
23 public delegate void UpLoadedAsset(
24 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
25 byte[] data, string inventoryType, string assetType);
26
27 public delegate void UploadedBakedTexture(UUID assetID, byte[] data);
28
29 public delegate UUID UpdateItem(UUID itemID, byte[] data);
30
31 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
32
33 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
34
35 public delegate void NewAsset(AssetBase asset);
36
37 public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
38
39 public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
40 bool isScriptRunning, byte[] data);
41
42 public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
43 bool fetchFolders, bool fetchItems, int sortOrder, out int version);
44
45 /// <summary>
46 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
47 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
48 /// to just pass the whole Scene into CAPS.
49 /// </summary>
50 public delegate IClientAPI GetClientDelegate(UUID agentID);
51
52 public class BunchOfCaps
53 {
54 private static readonly ILog m_log =
55 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private Scene m_Scene;
58 private Caps m_HostCapsObj;
59
60 private static readonly string m_requestPath = "0000/";
61 // private static readonly string m_mapLayerPath = "0001/";
62 private static readonly string m_newInventory = "0002/";
63 //private static readonly string m_requestTexture = "0003/";
64 private static readonly string m_notecardUpdatePath = "0004/";
65 private static readonly string m_notecardTaskUpdatePath = "0005/";
66 // private static readonly string m_fetchInventoryPath = "0006/";
67 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
68 private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
69
70
71 // These are callbacks which will be setup by the scene so that we can update scene data when we
72 // receive capability calls
73 public NewInventoryItem AddNewInventoryItem = null;
74 public NewAsset AddNewAsset = null;
75 public ItemUpdatedCallback ItemUpdatedCall = null;
76 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
77 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
78 public GetClientDelegate GetClient = null;
79
80 private bool m_persistBakedTextures = false;
81 private IAssetService m_assetService;
82 private bool m_dumpAssetsToFile;
83 private string m_regionName;
84
85 public BunchOfCaps(Scene scene, Caps caps)
86 {
87 m_Scene = scene;
88 m_HostCapsObj = caps;
89 IConfigSource config = m_Scene.Config;
90 if (config != null)
91 {
92 IConfig sconfig = config.Configs["Startup"];
93 if (sconfig != null)
94 m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
95 }
96
97 m_assetService = m_Scene.AssetService;
98 m_regionName = m_Scene.RegionInfo.RegionName;
99
100 RegisterHandlers();
101
102 AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
103 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
104 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
105 CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
106 GetClient = m_Scene.SceneContents.GetControllingClient;
107
108 }
109
110 /// <summary>
111 /// Register a bunch of CAPS http service handlers
112 /// </summary>
113 public void RegisterHandlers()
114 {
115 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
116
117 RegisterRegionServiceHandlers(capsBase);
118 RegisterInventoryServiceHandlers(capsBase);
119 }
120
121 public void RegisterRegionServiceHandlers(string capsBase)
122 {
123 try
124 {
125 // the root of all evil
126 m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
127 m_log.DebugFormat(
128 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
129
130 //m_capsHandlers["MapLayer"] =
131 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
132 // capsBase + m_mapLayerPath,
133 // GetMapLayer);
134 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
135 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
136 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
137 m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture));
138
139 }
140 catch (Exception e)
141 {
142 m_log.Error("[CAPS]: " + e.ToString());
143 }
144 }
145
146 public void RegisterInventoryServiceHandlers(string capsBase)
147 {
148 try
149 {
150 // I don't think this one works...
151 m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
152 capsBase + m_newInventory,
153 NewAgentInventoryRequest));
154 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
155 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
156 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
157 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
158
159 // As of RC 1.22.9 of the Linden client this is
160 // supported
161
162 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
163
164 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
165 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
166 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
167 // but when I went on the Linden grid, the
168 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
169 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
170 //
171 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
172 // we will be
173 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
174 // m_capsHandlers["FetchInventoryDescendents"] =
175 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
176
177 // m_capsHandlers["FetchInventoryDescendents"] =
178 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
179 // capsBase + m_fetchInventory,
180 // FetchInventory));
181 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
182 // capsBase + m_requestTexture,
183 // RequestTexture);
184 }
185 catch (Exception e)
186 {
187 m_log.Error("[CAPS]: " + e.ToString());
188 }
189 }
190
191 /// <summary>
192 /// Construct a client response detailing all the capabilities this server can provide.
193 /// </summary>
194 /// <param name="request"></param>
195 /// <param name="path"></param>
196 /// <param name="param"></param>
197 /// <param name="httpRequest">HTTP request header object</param>
198 /// <param name="httpResponse">HTTP response header object</param>
199 /// <returns></returns>
200 public string SeedCapRequest(string request, string path, string param,
201 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
202 {
203 m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
204
205 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
206 {
207 m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
208 return string.Empty;
209 }
210
211 Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails;
212 // Add the external too
213 foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
214 caps[kvp.Key] = kvp.Value;
215
216 string result = LLSDHelpers.SerialiseLLSDReply(caps);
217
218 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
219
220 return result;
221 }
222
223 /// <summary>
224 /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
225 /// </summary>
226 /// <param name="request"></param>
227 /// <param name="path"></param>
228 /// <param name="param"></param>
229 /// <param name="httpRequest">HTTP request header object</param>
230 /// <param name="httpResponse">HTTP response header object</param>
231 /// <returns></returns>
232 public string ScriptTaskInventory(string request, string path, string param,
233 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
234 {
235 try
236 {
237 m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
238 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
239
240 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
241 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
242 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
243
244 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
245 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
246
247 TaskInventoryScriptUpdater uploader =
248 new TaskInventoryScriptUpdater(
249 llsdUpdateRequest.item_id,
250 llsdUpdateRequest.task_id,
251 llsdUpdateRequest.is_script_running,
252 capsBase + uploaderPath,
253 m_HostCapsObj.HttpListener,
254 m_dumpAssetsToFile);
255 uploader.OnUpLoad += TaskScriptUpdated;
256
257 m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
258
259 string protocol = "http://";
260
261 if (m_HostCapsObj.SSLCaps)
262 protocol = "https://";
263
264 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
265 uploaderPath;
266
267 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
268 uploadResponse.uploader = uploaderURL;
269 uploadResponse.state = "upload";
270
271 // m_log.InfoFormat("[CAPS]: " +
272 // "ScriptTaskInventory response: {0}",
273 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
274
275 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
276 }
277 catch (Exception e)
278 {
279 m_log.Error("[CAPS]: " + e.ToString());
280 }
281
282 return null;
283 }
284
285 /// <summary>
286 /// Called when new asset data for an agent inventory item update has been uploaded.
287 /// </summary>
288 /// <param name="itemID">Item to update</param>
289 /// <param name="primID">Prim containing item to update</param>
290 /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
291 /// <param name="data">New asset data</param>
292 public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
293 {
294 if (TaskScriptUpdatedCall != null)
295 {
296 ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data);
297 foreach (Object item in e)
298 errors.Add(item);
299 }
300 }
301
302 public string UploadBakedTexture(string request, string path,
303 string param, OSHttpRequest httpRequest,
304 OSHttpResponse httpResponse)
305 {
306 try
307 {
308 // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " +
309 // m_regionName);
310
311 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
312 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
313
314 BakedTextureUploader uploader =
315 new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
316 uploader.OnUpLoad += BakedTextureUploaded;
317
318 m_HostCapsObj.HttpListener.AddStreamHandler(
319 new BinaryStreamHandler("POST", capsBase + uploaderPath,
320 uploader.uploaderCaps));
321
322 string protocol = "http://";
323
324 if (m_HostCapsObj.SSLCaps)
325 protocol = "https://";
326
327 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
328 m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
329
330 LLSDAssetUploadResponse uploadResponse =
331 new LLSDAssetUploadResponse();
332 uploadResponse.uploader = uploaderURL;
333 uploadResponse.state = "upload";
334
335 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
336 }
337 catch (Exception e)
338 {
339 m_log.Error("[CAPS]: " + e.ToString());
340 }
341
342 return null;
343 }
344
345 public void BakedTextureUploaded(UUID assetID, byte[] data)
346 {
347 // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
348
349 AssetBase asset;
350 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
351 asset.Data = data;
352 asset.Temporary = true;
353 asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
354 m_assetService.Store(asset);
355 }
356
357 /// <summary>
358 /// Called when new asset data for an agent inventory item update has been uploaded.
359 /// </summary>
360 /// <param name="itemID">Item to update</param>
361 /// <param name="data">New asset data</param>
362 /// <returns></returns>
363 public UUID ItemUpdated(UUID itemID, byte[] data)
364 {
365 if (ItemUpdatedCall != null)
366 {
367 return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data);
368 }
369
370 return UUID.Zero;
371 }
372
373 /// <summary>
374 ///
375 /// </summary>
376 /// <param name="llsdRequest"></param>
377 /// <returns></returns>
378 public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
379 {
380 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
381 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
382
383 if (llsdRequest.asset_type == "texture" ||
384 llsdRequest.asset_type == "animation" ||
385 llsdRequest.asset_type == "sound")
386 {
387 IClientAPI client = null;
388 IScene scene = null;
389 if (GetClient != null)
390 {
391 client = GetClient(m_HostCapsObj.AgentID);
392 scene = client.Scene;
393
394 IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
395
396 if (mm != null)
397 {
398 if (!mm.UploadCovered(client, mm.UploadCharge))
399 {
400 if (client != null)
401 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
402
403 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
404 errorResponse.uploader = "";
405 errorResponse.state = "error";
406 return errorResponse;
407 }
408 }
409 }
410 }
411
412 string assetName = llsdRequest.name;
413 string assetDes = llsdRequest.description;
414 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
415 UUID newAsset = UUID.Random();
416 UUID newInvItem = UUID.Random();
417 UUID parentFolder = llsdRequest.folder_id;
418 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
419
420 AssetUploader uploader =
421 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
422 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
423 m_HostCapsObj.HttpListener.AddStreamHandler(
424 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
425
426 string protocol = "http://";
427
428 if (m_HostCapsObj.SSLCaps)
429 protocol = "https://";
430
431 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
432 uploaderPath;
433
434 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
435 uploadResponse.uploader = uploaderURL;
436 uploadResponse.state = "upload";
437 uploader.OnUpLoad += UploadCompleteHandler;
438 return uploadResponse;
439 }
440
441 /// <summary>
442 ///
443 /// </summary>
444 /// <param name="assetID"></param>
445 /// <param name="inventoryItem"></param>
446 /// <param name="data"></param>
447 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
448 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
449 string assetType)
450 {
451 sbyte assType = 0;
452 sbyte inType = 0;
453
454 if (inventoryType == "sound")
455 {
456 inType = 1;
457 assType = 1;
458 }
459 else if (inventoryType == "animation")
460 {
461 inType = 19;
462 assType = 20;
463 }
464 else if (inventoryType == "wearable")
465 {
466 inType = 18;
467 switch (assetType)
468 {
469 case "bodypart":
470 assType = 13;
471 break;
472 case "clothing":
473 assType = 5;
474 break;
475 }
476 }
477
478 AssetBase asset;
479 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString());
480 asset.Data = data;
481 if (AddNewAsset != null)
482 AddNewAsset(asset);
483 else if (m_assetService != null)
484 m_assetService.Store(asset);
485
486 InventoryItemBase item = new InventoryItemBase();
487 item.Owner = m_HostCapsObj.AgentID;
488 item.CreatorId = m_HostCapsObj.AgentID.ToString();
489 item.CreatorData = String.Empty;
490 item.ID = inventoryItem;
491 item.AssetID = asset.FullID;
492 item.Description = assetDescription;
493 item.Name = assetName;
494 item.AssetType = assType;
495 item.InvType = inType;
496 item.Folder = parentFolder;
497 item.CurrentPermissions = (uint)PermissionMask.All;
498 item.BasePermissions = (uint)PermissionMask.All;
499 item.EveryOnePermissions = 0;
500 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
501 item.CreationDate = Util.UnixTimeSinceEpoch();
502
503 if (AddNewInventoryItem != null)
504 {
505 AddNewInventoryItem(m_HostCapsObj.AgentID, item);
506 }
507 }
508
509
510
511 /// <summary>
512 ///
513 /// </summary>
514 /// <param name="mapReq"></param>
515 /// <returns></returns>
516 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
517 {
518 m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName);
519 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
520 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
521 return mapResponse;
522 }
523
524 /// <summary>
525 ///
526 /// </summary>
527 /// <returns></returns>
528 protected static OSDMapLayer GetOSDMapLayerResponse()
529 {
530 OSDMapLayer mapLayer = new OSDMapLayer();
531 mapLayer.Right = 5000;
532 mapLayer.Top = 5000;
533 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
534
535 return mapLayer;
536 }
537
538 /// <summary>
539 ///
540 /// </summary>
541 /// <param name="request"></param>
542 /// <param name="path"></param>
543 /// <param name="param"></param>
544 /// <returns></returns>
545 public string RequestTexture(string request, string path, string param)
546 {
547 m_log.Debug("texture request " + request);
548 // Needs implementing (added to remove compiler warning)
549 return String.Empty;
550 }
551
552
553 /// <summary>
554 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
555 /// </summary>
556 /// <param name="request"></param>
557 /// <param name="path"></param>
558 /// <param name="param"></param>
559 /// <returns></returns>
560 public string NoteCardAgentInventory(string request, string path, string param,
561 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
562 {
563 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request);
564 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request);
565
566 //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request));
567 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
568 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
569 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
570
571 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
572 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
573
574 ItemUpdater uploader =
575 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
576 uploader.OnUpLoad += ItemUpdated;
577
578 m_HostCapsObj.HttpListener.AddStreamHandler(
579 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
580
581 string protocol = "http://";
582
583 if (m_HostCapsObj.SSLCaps)
584 protocol = "https://";
585
586 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
587 uploaderPath;
588
589 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
590 uploadResponse.uploader = uploaderURL;
591 uploadResponse.state = "upload";
592
593 // m_log.InfoFormat("[CAPS]: " +
594 // "NoteCardAgentInventory response: {0}",
595 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
596
597 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
598 }
599 }
600
601 public class AssetUploader
602 {
603 public event UpLoadedAsset OnUpLoad;
604 private UpLoadedAsset handlerUpLoad = null;
605
606 private string uploaderPath = String.Empty;
607 private UUID newAssetID;
608 private UUID inventoryItemID;
609 private UUID parentFolder;
610 private IHttpServer httpListener;
611 private bool m_dumpAssetsToFile;
612 private string m_assetName = String.Empty;
613 private string m_assetDes = String.Empty;
614
615 private string m_invType = String.Empty;
616 private string m_assetType = String.Empty;
617
618 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
619 UUID parentFolderID, string invType, string assetType, string path,
620 IHttpServer httpServer, bool dumpAssetsToFile)
621 {
622 m_assetName = assetName;
623 m_assetDes = description;
624 newAssetID = assetID;
625 inventoryItemID = inventoryItem;
626 uploaderPath = path;
627 httpListener = httpServer;
628 parentFolder = parentFolderID;
629 m_assetType = assetType;
630 m_invType = invType;
631 m_dumpAssetsToFile = dumpAssetsToFile;
632 }
633
634 /// <summary>
635 ///
636 /// </summary>
637 /// <param name="data"></param>
638 /// <param name="path"></param>
639 /// <param name="param"></param>
640 /// <returns></returns>
641 public string uploaderCaps(byte[] data, string path, string param)
642 {
643 UUID inv = inventoryItemID;
644 string res = String.Empty;
645 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
646 uploadComplete.new_asset = newAssetID.ToString();
647 uploadComplete.new_inventory_item = inv;
648 uploadComplete.state = "complete";
649
650 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
651
652 httpListener.RemoveStreamHandler("POST", uploaderPath);
653
654 // TODO: probably make this a better set of extensions here
655 string extension = ".jp2";
656 if (m_invType != "image")
657 {
658 extension = ".dat";
659 }
660
661 if (m_dumpAssetsToFile)
662 {
663 SaveAssetToFile(m_assetName + extension, data);
664 }
665 handlerUpLoad = OnUpLoad;
666 if (handlerUpLoad != null)
667 {
668 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
669 }
670
671 return res;
672 }
673 ///Left this in and commented in case there are unforseen issues
674 //private void SaveAssetToFile(string filename, byte[] data)
675 //{
676 // FileStream fs = File.Create(filename);
677 // BinaryWriter bw = new BinaryWriter(fs);
678 // bw.Write(data);
679 // bw.Close();
680 // fs.Close();
681 //}
682 private static void SaveAssetToFile(string filename, byte[] data)
683 {
684 string assetPath = "UserAssets";
685 if (!Directory.Exists(assetPath))
686 {
687 Directory.CreateDirectory(assetPath);
688 }
689 FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
690 BinaryWriter bw = new BinaryWriter(fs);
691 bw.Write(data);
692 bw.Close();
693 fs.Close();
694 }
695 }
696
697 /// <summary>
698 /// This class is a callback invoked when a client sends asset data to
699 /// an agent inventory notecard update url
700 /// </summary>
701 public class ItemUpdater
702 {
703 public event UpdateItem OnUpLoad;
704
705 private UpdateItem handlerUpdateItem = null;
706
707 private string uploaderPath = String.Empty;
708 private UUID inventoryItemID;
709 private IHttpServer httpListener;
710 private bool m_dumpAssetToFile;
711
712 public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile)
713 {
714 m_dumpAssetToFile = dumpAssetToFile;
715
716 inventoryItemID = inventoryItem;
717 uploaderPath = path;
718 httpListener = httpServer;
719 }
720
721 /// <summary>
722 ///
723 /// </summary>
724 /// <param name="data"></param>
725 /// <param name="path"></param>
726 /// <param name="param"></param>
727 /// <returns></returns>
728 public string uploaderCaps(byte[] data, string path, string param)
729 {
730 UUID inv = inventoryItemID;
731 string res = String.Empty;
732 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
733 UUID assetID = UUID.Zero;
734 handlerUpdateItem = OnUpLoad;
735 if (handlerUpdateItem != null)
736 {
737 assetID = handlerUpdateItem(inv, data);
738 }
739
740 uploadComplete.new_asset = assetID.ToString();
741 uploadComplete.new_inventory_item = inv;
742 uploadComplete.state = "complete";
743
744 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
745
746 httpListener.RemoveStreamHandler("POST", uploaderPath);
747
748 if (m_dumpAssetToFile)
749 {
750 SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
751 }
752
753 return res;
754 }
755 ///Left this in and commented in case there are unforseen issues
756 //private void SaveAssetToFile(string filename, byte[] data)
757 //{
758 // FileStream fs = File.Create(filename);
759 // BinaryWriter bw = new BinaryWriter(fs);
760 // bw.Write(data);
761 // bw.Close();
762 // fs.Close();
763 //}
764 private static void SaveAssetToFile(string filename, byte[] data)
765 {
766 string assetPath = "UserAssets";
767 if (!Directory.Exists(assetPath))
768 {
769 Directory.CreateDirectory(assetPath);
770 }
771 FileStream fs = File.Create(Path.Combine(assetPath, filename));
772 BinaryWriter bw = new BinaryWriter(fs);
773 bw.Write(data);
774 bw.Close();
775 fs.Close();
776 }
777 }
778
779 /// <summary>
780 /// This class is a callback invoked when a client sends asset data to
781 /// a task inventory script update url
782 /// </summary>
783 public class TaskInventoryScriptUpdater
784 {
785 private static readonly ILog m_log =
786 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
787
788 public event UpdateTaskScript OnUpLoad;
789
790 private UpdateTaskScript handlerUpdateTaskScript = null;
791
792 private string uploaderPath = String.Empty;
793 private UUID inventoryItemID;
794 private UUID primID;
795 private bool isScriptRunning;
796 private IHttpServer httpListener;
797 private bool m_dumpAssetToFile;
798
799 public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning,
800 string path, IHttpServer httpServer, bool dumpAssetToFile)
801 {
802 m_dumpAssetToFile = dumpAssetToFile;
803
804 this.inventoryItemID = inventoryItemID;
805 this.primID = primID;
806
807 // This comes in over the packet as an integer, but actually appears to be treated as a bool
808 this.isScriptRunning = (0 == isScriptRunning ? false : true);
809
810 uploaderPath = path;
811 httpListener = httpServer;
812 }
813
814 /// <summary>
815 ///
816 /// </summary>
817 /// <param name="data"></param>
818 /// <param name="path"></param>
819 /// <param name="param"></param>
820 /// <returns></returns>
821 public string uploaderCaps(byte[] data, string path, string param)
822 {
823 try
824 {
825 // m_log.InfoFormat("[CAPS]: " +
826 // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
827 // data, path, param));
828
829 string res = String.Empty;
830 LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
831
832 ArrayList errors = new ArrayList();
833 handlerUpdateTaskScript = OnUpLoad;
834 if (handlerUpdateTaskScript != null)
835 {
836 handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
837 }
838
839 uploadComplete.new_asset = inventoryItemID;
840 uploadComplete.compiled = errors.Count > 0 ? false : true;
841 uploadComplete.state = "complete";
842 uploadComplete.errors = new OSDArray();
843 uploadComplete.errors.Array = errors;
844
845 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
846
847 httpListener.RemoveStreamHandler("POST", uploaderPath);
848
849 if (m_dumpAssetToFile)
850 {
851 SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
852 }
853
854 // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
855
856 return res;
857 }
858 catch (Exception e)
859 {
860 m_log.Error("[CAPS]: " + e.ToString());
861 }
862
863 // XXX Maybe this should be some meaningful error packet
864 return null;
865 }
866 ///Left this in and commented in case there are unforseen issues
867 //private void SaveAssetToFile(string filename, byte[] data)
868 //{
869 // FileStream fs = File.Create(filename);
870 // BinaryWriter bw = new BinaryWriter(fs);
871 // bw.Write(data);
872 // bw.Close();
873 // fs.Close();
874 //}
875 private static void SaveAssetToFile(string filename, byte[] data)
876 {
877 string assetPath = "UserAssets";
878 if (!Directory.Exists(assetPath))
879 {
880 Directory.CreateDirectory(assetPath);
881 }
882 FileStream fs = File.Create(Path.Combine(assetPath, filename));
883 BinaryWriter bw = new BinaryWriter(fs);
884 bw.Write(data);
885 bw.Close();
886 fs.Close();
887 }
888 }
889
890 public class BakedTextureUploader
891 {
892 public event UploadedBakedTexture OnUpLoad;
893 private UploadedBakedTexture handlerUpLoad = null;
894
895 private string uploaderPath = String.Empty;
896 private UUID newAssetID;
897 private IHttpServer httpListener;
898
899 public BakedTextureUploader(string path, IHttpServer httpServer)
900 {
901 newAssetID = UUID.Random();
902 uploaderPath = path;
903 httpListener = httpServer;
904 // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
905 }
906
907 /// <summary>
908 ///
909 /// </summary>
910 /// <param name="data"></param>
911 /// <param name="path"></param>
912 /// <param name="param"></param>
913 /// <returns></returns>
914 public string uploaderCaps(byte[] data, string path, string param)
915 {
916 handlerUpLoad = OnUpLoad;
917 if (handlerUpLoad != null)
918 {
919 Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
920 }
921
922 string res = String.Empty;
923 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
924 uploadComplete.new_asset = newAssetID.ToString();
925 uploadComplete.new_inventory_item = UUID.Zero;
926 uploadComplete.state = "complete";
927
928 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
929
930 httpListener.RemoveStreamHandler("POST", uploaderPath);
931
932 // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
933
934 return res;
935 }
936 }
937
938}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
new file mode 100644
index 0000000..14160ae
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -0,0 +1,91 @@
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.Generic;
30using System.Reflection;
31
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using Mono.Addins;
36
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42
43[assembly: Addin("LindenCaps", "0.1")]
44[assembly: AddinDependency("OpenSim", "0.5")]
45namespace OpenSim.Region.ClientStack.Linden
46{
47
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class BunchOfCapsModule : INonSharedRegionModule
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private Scene m_Scene;
55
56 #region INonSharedRegionModule
57
58 public string Name { get { return "BunchOfCapsModule"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64 }
65
66 public void Close() { }
67
68 public void AddRegion(Scene scene)
69 {
70 m_Scene = scene;
71 m_Scene.EventManager.OnRegisterCaps += OnRegisterCaps;
72 }
73
74 public void RemoveRegion(Scene scene)
75 {
76 }
77
78 public void RegionLoaded(Scene scene)
79 {
80 }
81
82 public void PostInitialise() { }
83 #endregion
84
85 private void OnRegisterCaps(UUID agentID, Caps caps)
86 {
87 new BunchOfCaps(m_Scene, caps);
88 }
89
90 }
91}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
new file mode 100644
index 0000000..139d8b8
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -0,0 +1,731 @@
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.Generic;
31using System.Net;
32using System.Reflection;
33using System.Threading;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37using OpenMetaverse;
38using OpenMetaverse.Messages.Linden;
39using OpenMetaverse.Packets;
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 BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>;
47using Caps=OpenSim.Framework.Capabilities.Caps;
48
49namespace OpenSim.Region.ClientStack.Linden
50{
51 public struct QueueItem
52 {
53 public int id;
54 public OSDMap body;
55 }
56
57 //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
58 public class EventQueueGetModule : IEventQueue, IRegionModule
59 {
60 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61 protected Scene m_scene = null;
62 private IConfigSource m_gConfig;
63 bool enabledYN = false;
64
65 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
66
67 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
68 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
69 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
70
71 #region IRegionModule methods
72 public virtual void Initialise(Scene scene, IConfigSource config)
73 {
74 m_gConfig = config;
75
76 IConfig startupConfig = m_gConfig.Configs["Startup"];
77
78 ReadConfigAndPopulate(scene, startupConfig, "Startup");
79
80 if (enabledYN)
81 {
82 m_scene = scene;
83 scene.RegisterModuleInterface<IEventQueue>(this);
84
85 // Register fallback handler
86 // Why does EQG Fail on region crossings!
87
88 //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
89
90 scene.EventManager.OnNewClient += OnNewClient;
91
92 // TODO: Leaving these open, or closing them when we
93 // become a child is incorrect. It messes up TP in a big
94 // way. CAPS/EQ need to be active as long as the UDP
95 // circuit is there.
96
97 scene.EventManager.OnClientClosed += ClientClosed;
98 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
99 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
100 }
101 else
102 {
103 m_gConfig = null;
104 }
105
106 }
107
108 private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p)
109 {
110 enabledYN = startupConfig.GetBoolean("EventQueue", true);
111 }
112
113 public void PostInitialise()
114 {
115 }
116
117 public virtual void Close()
118 {
119 }
120
121 public virtual string Name
122 {
123 get { return "EventQueueGetModule"; }
124 }
125
126 public bool IsSharedModule
127 {
128 get { return false; }
129 }
130 #endregion
131
132 /// <summary>
133 /// Always returns a valid queue
134 /// </summary>
135 /// <param name="agentId"></param>
136 /// <returns></returns>
137 private Queue<OSD> TryGetQueue(UUID agentId)
138 {
139 lock (queues)
140 {
141 if (!queues.ContainsKey(agentId))
142 {
143 /*
144 m_log.DebugFormat(
145 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
146 agentId, m_scene.RegionInfo.RegionName);
147 */
148 queues[agentId] = new Queue<OSD>();
149 }
150
151 return queues[agentId];
152 }
153 }
154
155 /// <summary>
156 /// May return a null queue
157 /// </summary>
158 /// <param name="agentId"></param>
159 /// <returns></returns>
160 private Queue<OSD> GetQueue(UUID agentId)
161 {
162 lock (queues)
163 {
164 if (queues.ContainsKey(agentId))
165 {
166 return queues[agentId];
167 }
168 else
169 return null;
170 }
171 }
172
173 #region IEventQueue Members
174
175 public bool Enqueue(OSD ev, UUID avatarID)
176 {
177 //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
178 try
179 {
180 Queue<OSD> queue = GetQueue(avatarID);
181 if (queue != null)
182 queue.Enqueue(ev);
183 }
184 catch(NullReferenceException e)
185 {
186 m_log.Error("[EVENTQUEUE] Caught exception: " + e);
187 return false;
188 }
189
190 return true;
191 }
192
193 #endregion
194
195 private void OnNewClient(IClientAPI client)
196 {
197 //client.OnLogout += ClientClosed;
198 }
199
200// private void ClientClosed(IClientAPI client)
201// {
202// ClientClosed(client.AgentId);
203// }
204
205 private void ClientClosed(UUID AgentID, Scene scene)
206 {
207 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
208
209 int count = 0;
210 while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
211 {
212 Thread.Sleep(1000);
213 }
214
215 lock (queues)
216 {
217 queues.Remove(AgentID);
218 }
219 List<UUID> removeitems = new List<UUID>();
220 lock (m_AvatarQueueUUIDMapping)
221 {
222 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
223 {
224 if (ky == AgentID)
225 {
226 removeitems.Add(ky);
227 }
228 }
229
230 foreach (UUID ky in removeitems)
231 {
232 m_AvatarQueueUUIDMapping.Remove(ky);
233 MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/");
234 }
235
236 }
237 UUID searchval = UUID.Zero;
238
239 removeitems.Clear();
240
241 lock (m_QueueUUIDAvatarMapping)
242 {
243 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys)
244 {
245 searchval = m_QueueUUIDAvatarMapping[ky];
246
247 if (searchval == AgentID)
248 {
249 removeitems.Add(ky);
250 }
251 }
252
253 foreach (UUID ky in removeitems)
254 m_QueueUUIDAvatarMapping.Remove(ky);
255
256 }
257 }
258
259 private void MakeChildAgent(ScenePresence avatar)
260 {
261 //m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
262 //lock (m_ids)
263 // {
264 //if (m_ids.ContainsKey(avatar.UUID))
265 //{
266 // close the event queue.
267 //m_ids[avatar.UUID] = -1;
268 //}
269 //}
270 }
271
272 public void OnRegisterCaps(UUID agentID, Caps caps)
273 {
274 // Register an event queue for the client
275
276 //m_log.DebugFormat(
277 // "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
278 // agentID, caps, m_scene.RegionInfo.RegionName);
279
280 // Let's instantiate a Queue for this agent right now
281 TryGetQueue(agentID);
282
283 string capsBase = "/CAPS/EQG/";
284 UUID EventQueueGetUUID = UUID.Zero;
285
286 lock (m_AvatarQueueUUIDMapping)
287 {
288 // Reuse open queues. The client does!
289 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
290 {
291 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
292 EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
293 }
294 else
295 {
296 EventQueueGetUUID = UUID.Random();
297 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
298 }
299 }
300
301 lock (m_QueueUUIDAvatarMapping)
302 {
303 if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
304 m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
305 }
306
307 lock (m_AvatarQueueUUIDMapping)
308 {
309 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
310 m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
311 }
312
313 // Register this as a caps handler
314 caps.RegisterHandler("EventQueueGet",
315 new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/",
316 delegate(Hashtable m_dhttpMethod)
317 {
318 return ProcessQueue(m_dhttpMethod, agentID, caps);
319 }));
320
321 // This will persist this beyond the expiry of the caps handlers
322 MainServer.Instance.AddPollServiceHTTPHandler(
323 capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
324
325 Random rnd = new Random(Environment.TickCount);
326 lock (m_ids)
327 {
328 if (!m_ids.ContainsKey(agentID))
329 m_ids.Add(agentID, rnd.Next(30000000));
330 }
331 }
332
333 public bool HasEvents(UUID requestID, UUID agentID)
334 {
335 // Don't use this, because of race conditions at agent closing time
336 //Queue<OSD> queue = TryGetQueue(agentID);
337
338 Queue<OSD> queue = GetQueue(agentID);
339 if (queue != null)
340 lock (queue)
341 {
342 if (queue.Count > 0)
343 return true;
344 else
345 return false;
346 }
347 return false;
348 }
349
350 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
351 {
352 Queue<OSD> queue = TryGetQueue(pAgentId);
353 OSD element;
354 lock (queue)
355 {
356 if (queue.Count == 0)
357 return NoEvents(requestID, pAgentId);
358 element = queue.Dequeue(); // 15s timeout
359 }
360
361
362
363 int thisID = 0;
364 lock (m_ids)
365 thisID = m_ids[pAgentId];
366
367 OSDArray array = new OSDArray();
368 if (element == null) // didn't have an event in 15s
369 {
370 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
371 array.Add(EventQueueHelper.KeepAliveEvent());
372 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
373 }
374 else
375 {
376 array.Add(element);
377 lock (queue)
378 {
379 while (queue.Count > 0)
380 {
381 array.Add(queue.Dequeue());
382 thisID++;
383 }
384 }
385 }
386
387 OSDMap events = new OSDMap();
388 events.Add("events", array);
389
390 events.Add("id", new OSDInteger(thisID));
391 lock (m_ids)
392 {
393 m_ids[pAgentId] = thisID + 1;
394 }
395 Hashtable responsedata = new Hashtable();
396 responsedata["int_response_code"] = 200;
397 responsedata["content_type"] = "application/xml";
398 responsedata["keepalive"] = false;
399 responsedata["reusecontext"] = false;
400 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
401 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
402 return responsedata;
403 }
404
405 public Hashtable NoEvents(UUID requestID, UUID agentID)
406 {
407 Hashtable responsedata = new Hashtable();
408 responsedata["int_response_code"] = 502;
409 responsedata["content_type"] = "text/plain";
410 responsedata["keepalive"] = false;
411 responsedata["reusecontext"] = false;
412 responsedata["str_response_string"] = "Upstream error: ";
413 responsedata["error_status_text"] = "Upstream error:";
414 responsedata["http_protocol_version"] = "HTTP/1.0";
415 return responsedata;
416 }
417
418 public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
419 {
420 // TODO: this has to be redone to not busy-wait (and block the thread),
421 // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
422
423// if (m_log.IsDebugEnabled)
424// {
425// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
426// foreach (object key in request.Keys)
427// {
428// debug += key.ToString() + "=" + request[key].ToString() + " ";
429// }
430// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
431// }
432
433 Queue<OSD> queue = TryGetQueue(agentID);
434 OSD element = queue.Dequeue(); // 15s timeout
435
436 Hashtable responsedata = new Hashtable();
437
438 int thisID = 0;
439 lock (m_ids)
440 thisID = m_ids[agentID];
441
442 if (element == null)
443 {
444 //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
445 if (thisID == -1) // close-request
446 {
447 m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
448 responsedata["int_response_code"] = 404; //501; //410; //404;
449 responsedata["content_type"] = "text/plain";
450 responsedata["keepalive"] = false;
451 responsedata["str_response_string"] = "Closed EQG";
452 return responsedata;
453 }
454 responsedata["int_response_code"] = 502;
455 responsedata["content_type"] = "text/plain";
456 responsedata["keepalive"] = false;
457 responsedata["str_response_string"] = "Upstream error: ";
458 responsedata["error_status_text"] = "Upstream error:";
459 responsedata["http_protocol_version"] = "HTTP/1.0";
460 return responsedata;
461 }
462
463 OSDArray array = new OSDArray();
464 if (element == null) // didn't have an event in 15s
465 {
466 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
467 array.Add(EventQueueHelper.KeepAliveEvent());
468 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
469 }
470 else
471 {
472 array.Add(element);
473 while (queue.Count > 0)
474 {
475 array.Add(queue.Dequeue());
476 thisID++;
477 }
478 }
479
480 OSDMap events = new OSDMap();
481 events.Add("events", array);
482
483 events.Add("id", new OSDInteger(thisID));
484 lock (m_ids)
485 {
486 m_ids[agentID] = thisID + 1;
487 }
488
489 responsedata["int_response_code"] = 200;
490 responsedata["content_type"] = "application/xml";
491 responsedata["keepalive"] = false;
492 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
493 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
494
495 return responsedata;
496 }
497
498 public Hashtable EventQueuePoll(Hashtable request)
499 {
500 return new Hashtable();
501 }
502
503 public Hashtable EventQueuePath2(Hashtable request)
504 {
505 string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
506 // pull off the last "/" in the path.
507 Hashtable responsedata = new Hashtable();
508 capuuid = capuuid.Substring(0, capuuid.Length - 1);
509 capuuid = capuuid.Replace("/CAPS/EQG/", "");
510 UUID AvatarID = UUID.Zero;
511 UUID capUUID = UUID.Zero;
512
513 // parse the path and search for the avatar with it registered
514 if (UUID.TryParse(capuuid, out capUUID))
515 {
516 lock (m_QueueUUIDAvatarMapping)
517 {
518 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
519 {
520 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
521 }
522 }
523 if (AvatarID != UUID.Zero)
524 {
525 return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
526 }
527 else
528 {
529 responsedata["int_response_code"] = 404;
530 responsedata["content_type"] = "text/plain";
531 responsedata["keepalive"] = false;
532 responsedata["str_response_string"] = "Not Found";
533 responsedata["error_status_text"] = "Not Found";
534 responsedata["http_protocol_version"] = "HTTP/1.0";
535 return responsedata;
536 // return 404
537 }
538 }
539 else
540 {
541 responsedata["int_response_code"] = 404;
542 responsedata["content_type"] = "text/plain";
543 responsedata["keepalive"] = false;
544 responsedata["str_response_string"] = "Not Found";
545 responsedata["error_status_text"] = "Not Found";
546 responsedata["http_protocol_version"] = "HTTP/1.0";
547 return responsedata;
548 // return 404
549 }
550
551 }
552
553 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
554 {
555 // This is a fallback element to keep the client from loosing EventQueueGet
556 // Why does CAPS fail sometimes!?
557 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
558 string capuuid = path.Replace("/CAPS/EQG/","");
559 capuuid = capuuid.Substring(0, capuuid.Length - 1);
560
561// UUID AvatarID = UUID.Zero;
562 UUID capUUID = UUID.Zero;
563 if (UUID.TryParse(capuuid, out capUUID))
564 {
565/* Don't remove this yet code cleaners!
566 * Still testing this!
567 *
568 lock (m_QueueUUIDAvatarMapping)
569 {
570 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
571 {
572 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
573 }
574 }
575
576
577 if (AvatarID != UUID.Zero)
578 {
579 // Repair the CAP!
580 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
581 //string capsBase = "/CAPS/EQG/";
582 //caps.RegisterHandler("EventQueueGet",
583 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
584 //delegate(Hashtable m_dhttpMethod)
585 //{
586 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
587 //}));
588 // start new ID sequence.
589 Random rnd = new Random(System.Environment.TickCount);
590 lock (m_ids)
591 {
592 if (!m_ids.ContainsKey(AvatarID))
593 m_ids.Add(AvatarID, rnd.Next(30000000));
594 }
595
596
597 int thisID = 0;
598 lock (m_ids)
599 thisID = m_ids[AvatarID];
600
601 BlockingLLSDQueue queue = GetQueue(AvatarID);
602 OSDArray array = new OSDArray();
603 LLSD element = queue.Dequeue(15000); // 15s timeout
604 if (element == null)
605 {
606
607 array.Add(EventQueueHelper.KeepAliveEvent());
608 }
609 else
610 {
611 array.Add(element);
612 while (queue.Count() > 0)
613 {
614 array.Add(queue.Dequeue(1));
615 thisID++;
616 }
617 }
618 OSDMap events = new OSDMap();
619 events.Add("events", array);
620
621 events.Add("id", new LLSDInteger(thisID));
622
623 lock (m_ids)
624 {
625 m_ids[AvatarID] = thisID + 1;
626 }
627
628 return events;
629 }
630 else
631 {
632 return new LLSD();
633 }
634*
635*/
636 }
637 else
638 {
639 //return new LLSD();
640 }
641
642 return new OSDString("shutdown404!");
643 }
644
645 public void DisableSimulator(ulong handle, UUID avatarID)
646 {
647 OSD item = EventQueueHelper.DisableSimulator(handle);
648 Enqueue(item, avatarID);
649 }
650
651 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID)
652 {
653 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint);
654 Enqueue(item, avatarID);
655 }
656
657 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath)
658 {
659 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath);
660 Enqueue(item, avatarID);
661 }
662
663 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
664 IPEndPoint regionExternalEndPoint,
665 uint locationID, uint flags, string capsURL,
666 UUID avatarID)
667 {
668 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
669 locationID, flags, capsURL, avatarID);
670 Enqueue(item, avatarID);
671 }
672
673 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
674 IPEndPoint newRegionExternalEndPoint,
675 string capsURL, UUID avatarID, UUID sessionID)
676 {
677 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
678 capsURL, avatarID, sessionID);
679 Enqueue(item, avatarID);
680 }
681
682 public void ChatterboxInvitation(UUID sessionID, string sessionName,
683 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
684 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
685 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
686 {
687 OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog,
688 timeStamp, offline, parentEstateID, position, ttl, transactionID,
689 fromGroup, binaryBucket);
690 Enqueue(item, toAgent);
691 //m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item);
692
693 }
694
695 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat,
696 bool isModerator, bool textMute)
697 {
698 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
699 isModerator, textMute);
700 Enqueue(item, toAgent);
701 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
702 }
703
704 public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID)
705 {
706 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage);
707 Enqueue(item, avatarID);
708 }
709
710 public void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID)
711 {
712 OSD item = EventQueueHelper.GroupMembership(groupUpdate);
713 Enqueue(item, avatarID);
714 }
715 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
716 {
717 OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
718 Enqueue(item, avatarID);
719 }
720
721 public OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono)
722 {
723 return EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, running, mono);
724 }
725
726 public OSD BuildEvent(string eventName, OSD eventBody)
727 {
728 return EventQueueHelper.BuildEvent(eventName, eventBody);
729 }
730 }
731}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
new file mode 100644
index 0000000..3f49aba
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -0,0 +1,399 @@
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.Net;
30using OpenMetaverse;
31using OpenMetaverse.Packets;
32using OpenMetaverse.StructuredData;
33using OpenMetaverse.Messages.Linden;
34
35namespace OpenSim.Region.ClientStack.Linden
36{
37 public class EventQueueHelper
38 {
39 private EventQueueHelper() {} // no construction possible, it's an utility class
40
41 private static byte[] ulongToByteArray(ulong uLongValue)
42 {
43 // Reverse endianness of RegionHandle
44 return new byte[]
45 {
46 (byte)((uLongValue >> 56) % 256),
47 (byte)((uLongValue >> 48) % 256),
48 (byte)((uLongValue >> 40) % 256),
49 (byte)((uLongValue >> 32) % 256),
50 (byte)((uLongValue >> 24) % 256),
51 (byte)((uLongValue >> 16) % 256),
52 (byte)((uLongValue >> 8) % 256),
53 (byte)(uLongValue % 256)
54 };
55 }
56
57// private static byte[] uintToByteArray(uint uIntValue)
58// {
59// byte[] result = new byte[4];
60// Utils.UIntToBytesBig(uIntValue, result, 0);
61// return result;
62// }
63
64 public static OSD BuildEvent(string eventName, OSD eventBody)
65 {
66 OSDMap llsdEvent = new OSDMap(2);
67 llsdEvent.Add("message", new OSDString(eventName));
68 llsdEvent.Add("body", eventBody);
69
70 return llsdEvent;
71 }
72
73 public static OSD EnableSimulator(ulong handle, IPEndPoint endPoint)
74 {
75 OSDMap llsdSimInfo = new OSDMap(3);
76
77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
80
81 OSDArray arr = new OSDArray(1);
82 arr.Add(llsdSimInfo);
83
84 OSDMap llsdBody = new OSDMap(1);
85 llsdBody.Add("SimulatorInfo", arr);
86
87 return BuildEvent("EnableSimulator", llsdBody);
88 }
89
90 public static OSD DisableSimulator(ulong handle)
91 {
92 //OSDMap llsdSimInfo = new OSDMap(1);
93
94 //llsdSimInfo.Add("Handle", new OSDBinary(regionHandleToByteArray(handle)));
95
96 //OSDArray arr = new OSDArray(1);
97 //arr.Add(llsdSimInfo);
98
99 OSDMap llsdBody = new OSDMap(0);
100 //llsdBody.Add("SimulatorInfo", arr);
101
102 return BuildEvent("DisableSimulator", llsdBody);
103 }
104
105 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
106 IPEndPoint newRegionExternalEndPoint,
107 string capsURL, UUID agentID, UUID sessionID)
108 {
109 OSDArray lookAtArr = new OSDArray(3);
110 lookAtArr.Add(OSD.FromReal(lookAt.X));
111 lookAtArr.Add(OSD.FromReal(lookAt.Y));
112 lookAtArr.Add(OSD.FromReal(lookAt.Z));
113
114 OSDArray positionArr = new OSDArray(3);
115 positionArr.Add(OSD.FromReal(pos.X));
116 positionArr.Add(OSD.FromReal(pos.Y));
117 positionArr.Add(OSD.FromReal(pos.Z));
118
119 OSDMap infoMap = new OSDMap(2);
120 infoMap.Add("LookAt", lookAtArr);
121 infoMap.Add("Position", positionArr);
122
123 OSDArray infoArr = new OSDArray(1);
124 infoArr.Add(infoMap);
125
126 OSDMap agentDataMap = new OSDMap(2);
127 agentDataMap.Add("AgentID", OSD.FromUUID(agentID));
128 agentDataMap.Add("SessionID", OSD.FromUUID(sessionID));
129
130 OSDArray agentDataArr = new OSDArray(1);
131 agentDataArr.Add(agentDataMap);
132
133 OSDMap regionDataMap = new OSDMap(4);
134 regionDataMap.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(handle)));
135 regionDataMap.Add("SeedCapability", OSD.FromString(capsURL));
136 regionDataMap.Add("SimIP", OSD.FromBinary(newRegionExternalEndPoint.Address.GetAddressBytes()));
137 regionDataMap.Add("SimPort", OSD.FromInteger(newRegionExternalEndPoint.Port));
138
139 OSDArray regionDataArr = new OSDArray(1);
140 regionDataArr.Add(regionDataMap);
141
142 OSDMap llsdBody = new OSDMap(3);
143 llsdBody.Add("Info", infoArr);
144 llsdBody.Add("AgentData", agentDataArr);
145 llsdBody.Add("RegionData", regionDataArr);
146
147 return BuildEvent("CrossedRegion", llsdBody);
148 }
149
150 public static OSD TeleportFinishEvent(
151 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
152 uint locationID, uint flags, string capsURL, UUID agentID)
153 {
154 OSDMap info = new OSDMap();
155 info.Add("AgentID", OSD.FromUUID(agentID));
156 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
157 info.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(regionHandle)));
158 info.Add("SeedCapability", OSD.FromString(capsURL));
159 info.Add("SimAccess", OSD.FromInteger(simAccess));
160 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
161 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
162 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
163
164 OSDArray infoArr = new OSDArray();
165 infoArr.Add(info);
166
167 OSDMap body = new OSDMap();
168 body.Add("Info", infoArr);
169
170 return BuildEvent("TeleportFinish", body);
171 }
172
173 public static OSD ScriptRunningReplyEvent(UUID objectID, UUID itemID, bool running, bool mono)
174 {
175 OSDMap script = new OSDMap();
176 script.Add("ObjectID", OSD.FromUUID(objectID));
177 script.Add("ItemID", OSD.FromUUID(itemID));
178 script.Add("Running", OSD.FromBoolean(running));
179 script.Add("Mono", OSD.FromBoolean(mono));
180
181 OSDArray scriptArr = new OSDArray();
182 scriptArr.Add(script);
183
184 OSDMap body = new OSDMap();
185 body.Add("Script", scriptArr);
186
187 return BuildEvent("ScriptRunningReply", body);
188 }
189
190 public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap)
191 {
192 OSDMap body = new OSDMap(3);
193 body.Add("agent-id", new OSDUUID(agentID));
194 body.Add("sim-ip-and-port", new OSDString(simIpAndPort));
195 body.Add("seed-capability", new OSDString(seedcap));
196
197 return BuildEvent("EstablishAgentCommunication", body);
198 }
199
200 public static OSD KeepAliveEvent()
201 {
202 return BuildEvent("FAKEEVENT", new OSDMap());
203 }
204
205 public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate)
206 {
207 OSDMap body = new OSDMap(4);
208
209 body.Add("agent_id", new OSDUUID(agentID));
210 body.Add("check_estate", new OSDInteger(checkEstate ? 1 : 0));
211 body.Add("god_level", new OSDInteger(godLevel));
212 body.Add("limited_to_estate", new OSDInteger(limitedToEstate ? 1 : 0));
213
214 return body;
215 }
216
217 public static OSD InstantMessageParams(UUID fromAgent, string message, UUID toAgent,
218 string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
219 Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
220 {
221 OSDMap messageParams = new OSDMap(15);
222 messageParams.Add("type", new OSDInteger((int)dialog));
223
224 OSDArray positionArray = new OSDArray(3);
225 positionArray.Add(OSD.FromReal(position.X));
226 positionArray.Add(OSD.FromReal(position.Y));
227 positionArray.Add(OSD.FromReal(position.Z));
228 messageParams.Add("position", positionArray);
229
230 messageParams.Add("region_id", new OSDUUID(UUID.Zero));
231 messageParams.Add("to_id", new OSDUUID(toAgent));
232 messageParams.Add("source", new OSDInteger(0));
233
234 OSDMap data = new OSDMap(1);
235 data.Add("binary_bucket", OSD.FromBinary(binaryBucket));
236 messageParams.Add("data", data);
237 messageParams.Add("message", new OSDString(message));
238 messageParams.Add("id", new OSDUUID(transactionID));
239 messageParams.Add("from_name", new OSDString(fromName));
240 messageParams.Add("timestamp", new OSDInteger((int)timeStamp));
241 messageParams.Add("offline", new OSDInteger(offline ? 1 : 0));
242 messageParams.Add("parent_estate_id", new OSDInteger(parentEstateID));
243 messageParams.Add("ttl", new OSDInteger((int)ttl));
244 messageParams.Add("from_id", new OSDUUID(fromAgent));
245 messageParams.Add("from_group", new OSDInteger(fromGroup ? 1 : 0));
246
247 return messageParams;
248 }
249
250 public static OSD InstantMessage(UUID fromAgent, string message, UUID toAgent,
251 string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
252 Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket,
253 bool checkEstate, int godLevel, bool limitedToEstate)
254 {
255 OSDMap im = new OSDMap(2);
256 im.Add("message_params", InstantMessageParams(fromAgent, message, toAgent,
257 fromName, dialog, timeStamp, offline, parentEstateID,
258 position, ttl, transactionID, fromGroup, binaryBucket));
259
260 im.Add("agent_params", AgentParams(fromAgent, checkEstate, godLevel, limitedToEstate));
261
262 return im;
263 }
264
265
266 public static OSD ChatterboxInvitation(UUID sessionID, string sessionName,
267 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
268 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
269 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
270 {
271 OSDMap body = new OSDMap(5);
272 body.Add("session_id", new OSDUUID(sessionID));
273 body.Add("from_name", new OSDString(fromName));
274 body.Add("session_name", new OSDString(sessionName));
275 body.Add("from_id", new OSDUUID(fromAgent));
276
277 body.Add("instantmessage", InstantMessage(fromAgent, message, toAgent,
278 fromName, dialog, timeStamp, offline, parentEstateID, position,
279 ttl, transactionID, fromGroup, binaryBucket, true, 0, true));
280
281 OSDMap chatterboxInvitation = new OSDMap(2);
282 chatterboxInvitation.Add("message", new OSDString("ChatterBoxInvitation"));
283 chatterboxInvitation.Add("body", body);
284 return chatterboxInvitation;
285 }
286
287 public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID,
288 UUID agentID, bool canVoiceChat, bool isModerator, bool textMute)
289 {
290 OSDMap body = new OSDMap();
291 OSDMap agentUpdates = new OSDMap();
292 OSDMap infoDetail = new OSDMap();
293 OSDMap mutes = new OSDMap();
294
295 mutes.Add("text", OSD.FromBoolean(textMute));
296 infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat));
297 infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator));
298 infoDetail.Add("mutes", mutes);
299 OSDMap info = new OSDMap();
300 info.Add("info", infoDetail);
301 agentUpdates.Add(agentID.ToString(), info);
302 body.Add("agent_updates", agentUpdates);
303 body.Add("session_id", OSD.FromUUID(sessionID));
304 body.Add("updates", new OSD());
305
306 OSDMap chatterBoxSessionAgentListUpdates = new OSDMap();
307 chatterBoxSessionAgentListUpdates.Add("message", OSD.FromString("ChatterBoxSessionAgentListUpdates"));
308 chatterBoxSessionAgentListUpdates.Add("body", body);
309
310 return chatterBoxSessionAgentListUpdates;
311 }
312
313 public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket)
314 {
315 OSDMap groupUpdate = new OSDMap();
316 groupUpdate.Add("message", OSD.FromString("AgentGroupDataUpdate"));
317
318 OSDMap body = new OSDMap();
319 OSDArray agentData = new OSDArray();
320 OSDMap agentDataMap = new OSDMap();
321 agentDataMap.Add("AgentID", OSD.FromUUID(groupUpdatePacket.AgentData.AgentID));
322 agentData.Add(agentDataMap);
323 body.Add("AgentData", agentData);
324
325 OSDArray groupData = new OSDArray();
326
327 foreach (AgentGroupDataUpdatePacket.GroupDataBlock groupDataBlock in groupUpdatePacket.GroupData)
328 {
329 OSDMap groupDataMap = new OSDMap();
330 groupDataMap.Add("ListInProfile", OSD.FromBoolean(false));
331 groupDataMap.Add("GroupID", OSD.FromUUID(groupDataBlock.GroupID));
332 groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(groupDataBlock.GroupInsigniaID));
333 groupDataMap.Add("Contribution", OSD.FromInteger(groupDataBlock.Contribution));
334 groupDataMap.Add("GroupPowers", OSD.FromBinary(ulongToByteArray(groupDataBlock.GroupPowers)));
335 groupDataMap.Add("GroupName", OSD.FromString(Utils.BytesToString(groupDataBlock.GroupName)));
336 groupDataMap.Add("AcceptNotices", OSD.FromBoolean(groupDataBlock.AcceptNotices));
337
338 groupData.Add(groupDataMap);
339
340 }
341 body.Add("GroupData", groupData);
342 groupUpdate.Add("body", body);
343
344 return groupUpdate;
345 }
346
347 public static OSD PlacesQuery(PlacesReplyPacket PlacesReply)
348 {
349 OSDMap placesReply = new OSDMap();
350 placesReply.Add("message", OSD.FromString("PlacesReplyMessage"));
351
352 OSDMap body = new OSDMap();
353 OSDArray agentData = new OSDArray();
354 OSDMap agentDataMap = new OSDMap();
355 agentDataMap.Add("AgentID", OSD.FromUUID(PlacesReply.AgentData.AgentID));
356 agentDataMap.Add("QueryID", OSD.FromUUID(PlacesReply.AgentData.QueryID));
357 agentDataMap.Add("TransactionID", OSD.FromUUID(PlacesReply.TransactionData.TransactionID));
358 agentData.Add(agentDataMap);
359 body.Add("AgentData", agentData);
360
361 OSDArray QueryData = new OSDArray();
362
363 foreach (PlacesReplyPacket.QueryDataBlock groupDataBlock in PlacesReply.QueryData)
364 {
365 OSDMap QueryDataMap = new OSDMap();
366 QueryDataMap.Add("ActualArea", OSD.FromInteger(groupDataBlock.ActualArea));
367 QueryDataMap.Add("BillableArea", OSD.FromInteger(groupDataBlock.BillableArea));
368 QueryDataMap.Add("Description", OSD.FromBinary(groupDataBlock.Desc));
369 QueryDataMap.Add("Dwell", OSD.FromInteger((int)groupDataBlock.Dwell));
370 QueryDataMap.Add("Flags", OSD.FromString(Convert.ToString(groupDataBlock.Flags)));
371 QueryDataMap.Add("GlobalX", OSD.FromInteger((int)groupDataBlock.GlobalX));
372 QueryDataMap.Add("GlobalY", OSD.FromInteger((int)groupDataBlock.GlobalY));
373 QueryDataMap.Add("GlobalZ", OSD.FromInteger((int)groupDataBlock.GlobalZ));
374 QueryDataMap.Add("Name", OSD.FromBinary(groupDataBlock.Name));
375 QueryDataMap.Add("OwnerID", OSD.FromUUID(groupDataBlock.OwnerID));
376 QueryDataMap.Add("SimName", OSD.FromBinary(groupDataBlock.SimName));
377 QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID));
378 QueryDataMap.Add("ProductSku", OSD.FromInteger(0));
379 QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price));
380
381 QueryData.Add(QueryDataMap);
382 }
383 body.Add("QueryData", QueryData);
384 placesReply.Add("QueryData[]", body);
385
386 return placesReply;
387 }
388
389 public static OSD ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage)
390 {
391 OSDMap message = new OSDMap();
392 message.Add("message", OSD.FromString("ParcelProperties"));
393 OSD message_body = parcelPropertiesMessage.Serialize();
394 message.Add("body", message_body);
395 return message;
396 }
397
398 }
399}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
new file mode 100644
index 0000000..f2f765c
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.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.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Capabilities.Handlers;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47
48namespace OpenSim.Region.ClientStack.Linden
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class GetMeshModule : INonSharedRegionModule
52 {
53 private static readonly ILog m_log =
54 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57 private IAssetService m_AssetService;
58 private bool m_Enabled = true;
59 private string m_URL;
60
61 #region IRegionModuleBase Members
62
63 public Type ReplaceableInterface
64 {
65 get { return null; }
66 }
67
68 public void Initialise(IConfigSource source)
69 {
70 IConfig config = source.Configs["ClientStack.LindenCaps"];
71 if (config == null)
72 return;
73
74 m_URL = config.GetString("Cap_GetMesh", string.Empty);
75 // Cap doesn't exist
76 if (m_URL != string.Empty)
77 m_Enabled = true;
78 }
79
80 public void AddRegion(Scene pScene)
81 {
82 if (!m_Enabled)
83 return;
84
85 m_scene = pScene;
86 }
87
88 public void RemoveRegion(Scene scene)
89 {
90 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
91 m_scene = null;
92 }
93
94 public void RegionLoaded(Scene scene)
95 {
96 if (!m_Enabled)
97 return;
98
99 m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
100 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
101 }
102
103
104 public void Close() { }
105
106 public string Name { get { return "GetMeshModule"; } }
107
108 #endregion
109
110
111 public void RegisterCaps(UUID agentID, Caps caps)
112 {
113 UUID capID = UUID.Random();
114
115 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
116 if (m_URL == "localhost")
117 {
118 m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
119 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
120 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
121 delegate(Hashtable m_dhttpMethod)
122 {
123 return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
124 });
125
126 caps.RegisterHandler("GetMesh", reqHandler);
127 }
128 else
129 {
130 m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
131 caps.RegisterHandler("GetMesh", m_URL);
132 }
133 }
134
135 }
136}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
new file mode 100644
index 0000000..564ef31
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.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 OpenMetaverse.Imaging;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers;
50
51namespace OpenSim.Region.ClientStack.Linden
52{
53
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
55 public class GetTextureModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private Scene m_scene;
60 private IAssetService m_assetService;
61
62 private bool m_Enabled = false;
63
64 // TODO: Change this to a config option
65 const string REDIRECT_URL = null;
66
67 private string m_URL;
68
69 #region ISharedRegionModule Members
70
71 public void Initialise(IConfigSource source)
72 {
73 IConfig config = source.Configs["ClientStack.LindenCaps"];
74 if (config == null)
75 return;
76
77 m_URL = config.GetString("Cap_GetTexture", string.Empty);
78 // Cap doesn't exist
79 if (m_URL != string.Empty)
80 m_Enabled = true;
81 }
82
83 public void AddRegion(Scene s)
84 {
85 if (!m_Enabled)
86 return;
87
88 m_scene = s;
89 }
90
91 public void RemoveRegion(Scene s)
92 {
93 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
94 m_scene = null;
95 }
96
97 public void RegionLoaded(Scene s)
98 {
99 if (!m_Enabled)
100 return;
101
102 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
103 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
104 }
105
106 public void PostInitialise()
107 {
108 }
109
110 public void Close() { }
111
112 public string Name { get { return "GetTextureModule"; } }
113
114 public Type ReplaceableInterface
115 {
116 get { return null; }
117 }
118
119 #endregion
120
121 public void RegisterCaps(UUID agentID, Caps caps)
122 {
123 UUID capID = UUID.Random();
124
125 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
126 if (m_URL == "localhost")
127 {
128 m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
129 caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
130 }
131 else
132 {
133 m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
134 caps.RegisterHandler("GetTexture", m_URL);
135 }
136 }
137
138 }
139}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
new file mode 100644
index 0000000..b7e79cc
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -0,0 +1,275 @@
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.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46using OpenSim.Framework.Capabilities;
47
48namespace OpenSim.Region.ClientStack.Linden
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
52 {
53// private static readonly ILog m_log =
54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57// private IAssetService m_assetService;
58 private bool m_dumpAssetsToFile = false;
59 private bool m_enabled = true;
60
61 #region IRegionModuleBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71 IConfig meshConfig = source.Configs["Mesh"];
72 if (meshConfig == null)
73 return;
74
75 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
76 }
77
78 public void AddRegion(Scene pScene)
79 {
80 m_scene = pScene;
81 }
82
83 public void RemoveRegion(Scene scene)
84 {
85
86 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
87 m_scene = null;
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92
93// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
94 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
95 }
96
97 #endregion
98
99
100 #region IRegionModule Members
101
102
103
104 public void Close() { }
105
106 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
107
108
109 public void RegisterCaps(UUID agentID, Caps caps)
110 {
111 if(!m_enabled)
112 return;
113
114 UUID capID = UUID.Random();
115
116// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
117 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
118
119 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
120 "/CAPS/" + capID.ToString(),
121 delegate(LLSDAssetUploadRequest req)
122 {
123 return NewAgentInventoryRequest(req,agentID);
124 }));
125
126 }
127
128 #endregion
129
130 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
131 {
132
133 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
134 // You need to be aware of this and
135
136
137 //if (llsdRequest.asset_type == "texture" ||
138 // llsdRequest.asset_type == "animation" ||
139 // llsdRequest.asset_type == "sound")
140 // {
141 IClientAPI client = null;
142
143
144 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
145
146 if (mm != null)
147 {
148 if (m_scene.TryGetClient(agentID, out client))
149 {
150 if (!mm.UploadCovered(client, mm.UploadCharge))
151 {
152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
154
155 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
156 errorResponse.rsvp = "";
157 errorResponse.state = "error";
158 return errorResponse;
159 }
160 }
161 }
162 // }
163
164
165
166 string assetName = llsdRequest.name;
167 string assetDes = llsdRequest.description;
168 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
169 UUID newAsset = UUID.Random();
170 UUID newInvItem = UUID.Random();
171 UUID parentFolder = llsdRequest.folder_id;
172 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
173
174 AssetUploader uploader =
175 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
176 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
177 MainServer.Instance.AddStreamHandler(
178 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
179
180 string protocol = "http://";
181
182 if (MainServer.Instance.UseSSL)
183 protocol = "https://";
184
185 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
186 uploaderPath;
187
188
189 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
190
191
192 uploadResponse.rsvp = uploaderURL;
193 uploadResponse.state = "upload";
194 uploadResponse.resource_cost = 0;
195 uploadResponse.upload_price = 0;
196
197 uploader.OnUpLoad += //UploadCompleteHandler;
198
199 delegate(
200 string passetName, string passetDescription, UUID passetID,
201 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
202 string passetType)
203 {
204 UploadCompleteHandler(passetName, passetDescription, passetID,
205 pinventoryItem, pparentFolder, pdata, pinventoryType,
206 passetType,agentID);
207 };
208 return uploadResponse;
209 }
210
211
212 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
213 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
214 string assetType,UUID AgentID)
215 {
216
217 sbyte assType = 0;
218 sbyte inType = 0;
219
220 if (inventoryType == "sound")
221 {
222 inType = 1;
223 assType = 1;
224 }
225 else if (inventoryType == "animation")
226 {
227 inType = 19;
228 assType = 20;
229 }
230 else if (inventoryType == "wearable")
231 {
232 inType = 18;
233 switch (assetType)
234 {
235 case "bodypart":
236 assType = 13;
237 break;
238 case "clothing":
239 assType = 5;
240 break;
241 }
242 }
243 else if (inventoryType == "mesh")
244 {
245 inType = (sbyte)InventoryType.Mesh;
246 assType = (sbyte)AssetType.Mesh;
247 }
248
249 AssetBase asset;
250 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
251 asset.Data = data;
252
253 if (m_scene.AssetService != null)
254 m_scene.AssetService.Store(asset);
255
256 InventoryItemBase item = new InventoryItemBase();
257 item.Owner = AgentID;
258 item.CreatorId = AgentID.ToString();
259 item.ID = inventoryItem;
260 item.AssetID = asset.FullID;
261 item.Description = assetDescription;
262 item.Name = assetName;
263 item.AssetType = assType;
264 item.InvType = inType;
265 item.Folder = parentFolder;
266 item.CurrentPermissions = (uint)PermissionMask.All;
267 item.BasePermissions = (uint)PermissionMask.All;
268 item.EveryOnePermissions = 0;
269 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
270 item.CreationDate = Util.UnixTimeSinceEpoch();
271 m_scene.AddInventoryItem(item);
272
273 }
274 }
275}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
new file mode 100644
index 0000000..15139a3
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -0,0 +1,370 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using OpenSim.Framework;
36using OpenSim.Framework.Servers;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using Caps=OpenSim.Framework.Capabilities.Caps;
41
42namespace OpenSim.Region.ClientStack.Linden
43{
44 public class ObjectAdd : IRegionModule
45 {
46// private static readonly ILog m_log =
47// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private Scene m_scene;
50 #region IRegionModule Members
51
52 public void Initialise(Scene pScene, IConfigSource pSource)
53 {
54 m_scene = pScene;
55 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
56 }
57
58 public void PostInitialise()
59 {
60
61 }
62
63 public void RegisterCaps(UUID agentID, Caps caps)
64 {
65 UUID capuuid = UUID.Random();
66
67// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
68
69 caps.RegisterHandler("ObjectAdd",
70 new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
71 delegate(Hashtable m_dhttpMethod)
72 {
73 return ProcessAdd(m_dhttpMethod, agentID, caps);
74 }));
75 }
76
77 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
78 {
79 Hashtable responsedata = new Hashtable();
80 responsedata["int_response_code"] = 400; //501; //410; //404;
81 responsedata["content_type"] = "text/plain";
82 responsedata["keepalive"] = false;
83 responsedata["str_response_string"] = "Request wasn't what was expected";
84 ScenePresence avatar;
85
86 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
87 return responsedata;
88
89
90 OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
91 //UUID session_id = UUID.Zero;
92 bool bypass_raycast = false;
93 uint everyone_mask = 0;
94 uint group_mask = 0;
95 uint next_owner_mask = 0;
96 uint flags = 0;
97 UUID group_id = UUID.Zero;
98 int hollow = 0;
99 int material = 0;
100 int p_code = 0;
101 int path_begin = 0;
102 int path_curve = 0;
103 int path_end = 0;
104 int path_radius_offset = 0;
105 int path_revolutions = 0;
106 int path_scale_x = 0;
107 int path_scale_y = 0;
108 int path_shear_x = 0;
109 int path_shear_y = 0;
110 int path_skew = 0;
111 int path_taper_x = 0;
112 int path_taper_y = 0;
113 int path_twist = 0;
114 int path_twist_begin = 0;
115 int profile_begin = 0;
116 int profile_curve = 0;
117 int profile_end = 0;
118 Vector3 ray_end = Vector3.Zero;
119 bool ray_end_is_intersection = false;
120 Vector3 ray_start = Vector3.Zero;
121 UUID ray_target_id = UUID.Zero;
122 Quaternion rotation = Quaternion.Identity;
123 Vector3 scale = Vector3.Zero;
124 int state = 0;
125
126 if (r.Type != OSDType.Map) // not a proper req
127 return responsedata;
128
129 OSDMap rm = (OSDMap)r;
130
131 if (rm.ContainsKey("ObjectData")) //v2
132 {
133 if (rm["ObjectData"].Type != OSDType.Map)
134 {
135 responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format";
136 return responsedata;
137 }
138
139 OSDMap ObjMap = (OSDMap) rm["ObjectData"];
140
141 bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
142 everyone_mask = readuintval(ObjMap["EveryoneMask"]);
143 flags = readuintval(ObjMap["Flags"]);
144 group_mask = readuintval(ObjMap["GroupMask"]);
145 material = ObjMap["Material"].AsInteger();
146 next_owner_mask = readuintval(ObjMap["NextOwnerMask"]);
147 p_code = ObjMap["PCode"].AsInteger();
148
149 if (ObjMap.ContainsKey("Path"))
150 {
151 if (ObjMap["Path"].Type != OSDType.Map)
152 {
153 responsedata["str_response_string"] = "Has Path key, but data not in expected format";
154 return responsedata;
155 }
156
157 OSDMap PathMap = (OSDMap)ObjMap["Path"];
158 path_begin = PathMap["Begin"].AsInteger();
159 path_curve = PathMap["Curve"].AsInteger();
160 path_end = PathMap["End"].AsInteger();
161 path_radius_offset = PathMap["RadiusOffset"].AsInteger();
162 path_revolutions = PathMap["Revolutions"].AsInteger();
163 path_scale_x = PathMap["ScaleX"].AsInteger();
164 path_scale_y = PathMap["ScaleY"].AsInteger();
165 path_shear_x = PathMap["ShearX"].AsInteger();
166 path_shear_y = PathMap["ShearY"].AsInteger();
167 path_skew = PathMap["Skew"].AsInteger();
168 path_taper_x = PathMap["TaperX"].AsInteger();
169 path_taper_y = PathMap["TaperY"].AsInteger();
170 path_twist = PathMap["Twist"].AsInteger();
171 path_twist_begin = PathMap["TwistBegin"].AsInteger();
172
173 }
174
175 if (ObjMap.ContainsKey("Profile"))
176 {
177 if (ObjMap["Profile"].Type != OSDType.Map)
178 {
179 responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
180 return responsedata;
181 }
182
183 OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
184
185 profile_begin = ProfileMap["Begin"].AsInteger();
186 profile_curve = ProfileMap["Curve"].AsInteger();
187 profile_end = ProfileMap["End"].AsInteger();
188 hollow = ProfileMap["Hollow"].AsInteger();
189 }
190 ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
191
192 ray_target_id = ObjMap["RayTargetId"].AsUUID();
193 state = ObjMap["State"].AsInteger();
194 try
195 {
196 ray_end = ((OSDArray) ObjMap["RayEnd"]).AsVector3();
197 ray_start = ((OSDArray) ObjMap["RayStart"]).AsVector3();
198 scale = ((OSDArray) ObjMap["Scale"]).AsVector3();
199 rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
200 }
201 catch (Exception)
202 {
203 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
204 return responsedata;
205 }
206
207 if (rm.ContainsKey("AgentData"))
208 {
209 if (rm["AgentData"].Type != OSDType.Map)
210 {
211 responsedata["str_response_string"] = "Has AgentData key, but data not in expected format";
212 return responsedata;
213 }
214
215 OSDMap AgentDataMap = (OSDMap) rm["AgentData"];
216
217 //session_id = AgentDataMap["SessionId"].AsUUID();
218 group_id = AgentDataMap["GroupId"].AsUUID();
219 }
220
221 }
222 else
223 { //v1
224 bypass_raycast = rm["bypass_raycast"].AsBoolean();
225
226 everyone_mask = readuintval(rm["everyone_mask"]);
227 flags = readuintval(rm["flags"]);
228 group_id = rm["group_id"].AsUUID();
229 group_mask = readuintval(rm["group_mask"]);
230 hollow = rm["hollow"].AsInteger();
231 material = rm["material"].AsInteger();
232 next_owner_mask = readuintval(rm["next_owner_mask"]);
233 hollow = rm["hollow"].AsInteger();
234 p_code = rm["p_code"].AsInteger();
235 path_begin = rm["path_begin"].AsInteger();
236 path_curve = rm["path_curve"].AsInteger();
237 path_end = rm["path_end"].AsInteger();
238 path_radius_offset = rm["path_radius_offset"].AsInteger();
239 path_revolutions = rm["path_revolutions"].AsInteger();
240 path_scale_x = rm["path_scale_x"].AsInteger();
241 path_scale_y = rm["path_scale_y"].AsInteger();
242 path_shear_x = rm["path_shear_x"].AsInteger();
243 path_shear_y = rm["path_shear_y"].AsInteger();
244 path_skew = rm["path_skew"].AsInteger();
245 path_taper_x = rm["path_taper_x"].AsInteger();
246 path_taper_y = rm["path_taper_y"].AsInteger();
247 path_twist = rm["path_twist"].AsInteger();
248 path_twist_begin = rm["path_twist_begin"].AsInteger();
249 profile_begin = rm["profile_begin"].AsInteger();
250 profile_curve = rm["profile_curve"].AsInteger();
251 profile_end = rm["profile_end"].AsInteger();
252
253 ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
254
255 ray_target_id = rm["ray_target_id"].AsUUID();
256
257
258 //session_id = rm["session_id"].AsUUID();
259 state = rm["state"].AsInteger();
260 try
261 {
262 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
263 ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
264 rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
265 scale = ((OSDArray)rm["scale"]).AsVector3();
266 }
267 catch (Exception)
268 {
269 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
270 return responsedata;
271 }
272 }
273
274
275
276 Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false);
277
278 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
279
280 pbs.PathBegin = (ushort)path_begin;
281 pbs.PathCurve = (byte)path_curve;
282 pbs.PathEnd = (ushort)path_end;
283 pbs.PathRadiusOffset = (sbyte)path_radius_offset;
284 pbs.PathRevolutions = (byte)path_revolutions;
285 pbs.PathScaleX = (byte)path_scale_x;
286 pbs.PathScaleY = (byte)path_scale_y;
287 pbs.PathShearX = (byte) path_shear_x;
288 pbs.PathShearY = (byte)path_shear_y;
289 pbs.PathSkew = (sbyte)path_skew;
290 pbs.PathTaperX = (sbyte)path_taper_x;
291 pbs.PathTaperY = (sbyte)path_taper_y;
292 pbs.PathTwist = (sbyte)path_twist;
293 pbs.PathTwistBegin = (sbyte)path_twist_begin;
294 pbs.HollowShape = (HollowShape) hollow;
295 pbs.PCode = (byte)p_code;
296 pbs.ProfileBegin = (ushort) profile_begin;
297 pbs.ProfileCurve = (byte) profile_curve;
298 pbs.ProfileEnd = (ushort)profile_end;
299 pbs.Scale = scale;
300 pbs.State = (byte)state;
301
302 SceneObjectGroup obj = null; ;
303
304 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
305 {
306 // rez ON the ground, not IN the ground
307 // pos.Z += 0.25F;
308
309 obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
310 }
311
312
313 if (obj == null)
314 return responsedata;
315
316 SceneObjectPart rootpart = obj.RootPart;
317 rootpart.Shape = pbs;
318 rootpart.Flags |= (PrimFlags)flags;
319 rootpart.EveryoneMask = everyone_mask;
320 rootpart.GroupID = group_id;
321 rootpart.GroupMask = group_mask;
322 rootpart.NextOwnerMask = next_owner_mask;
323 rootpart.Material = (byte)material;
324
325
326
327 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
328
329 responsedata["int_response_code"] = 200; //501; //410; //404;
330 responsedata["content_type"] = "text/plain";
331 responsedata["keepalive"] = false;
332 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>",ConvertUintToBytes(obj.LocalId));
333
334 return responsedata;
335 }
336
337 private uint readuintval(OSD obj)
338 {
339 byte[] tmp = obj.AsBinary();
340 if (BitConverter.IsLittleEndian)
341 Array.Reverse(tmp);
342 return Utils.BytesToUInt(tmp);
343
344 }
345 private string ConvertUintToBytes(uint val)
346 {
347 byte[] resultbytes = Utils.UIntToBytes(val);
348 if (BitConverter.IsLittleEndian)
349 Array.Reverse(resultbytes);
350 return String.Format("<binary encoding=\"base64\">{0}</binary>",Convert.ToBase64String(resultbytes));
351 }
352
353 public void Close()
354 {
355
356 }
357
358 public string Name
359 {
360 get { return "ObjectAddModule"; }
361 }
362
363 public bool IsSharedModule
364 {
365 get { return false; }
366 }
367
368 #endregion
369 }
370}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
new file mode 100644
index 0000000..3809f84
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -0,0 +1,374 @@
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.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenMetaverse.Messages.Linden;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OSD = OpenMetaverse.StructuredData.OSD;
48using OSDMap = OpenMetaverse.StructuredData.OSDMap;
49using OpenSim.Framework.Capabilities;
50using ExtraParamType = OpenMetaverse.ExtraParamType;
51
52namespace OpenSim.Region.ClientStack.Linden
53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
55 public class UploadObjectAssetModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private Scene m_scene;
60
61 #region IRegionModuleBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71
72 }
73
74 public void AddRegion(Scene pScene)
75 {
76 m_scene = pScene;
77 }
78
79 public void RemoveRegion(Scene scene)
80 {
81
82 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
83 m_scene = null;
84 }
85
86 public void RegionLoaded(Scene scene)
87 {
88
89 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
90 }
91
92 #endregion
93
94
95 #region IRegionModule Members
96
97
98
99 public void Close() { }
100
101 public string Name { get { return "UploadObjectAssetModuleModule"; } }
102
103
104 public void RegisterCaps(UUID agentID, Caps caps)
105 {
106 UUID capID = UUID.Random();
107
108// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
109 caps.RegisterHandler("UploadObjectAsset",
110 new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
111 delegate(Hashtable m_dhttpMethod)
112 {
113 return ProcessAdd(m_dhttpMethod, agentID, caps);
114 }));
115 /*
116 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
117
118 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
119 "/CAPS/" + capID.ToString(),
120 delegate(LLSDAssetUploadRequest req)
121 {
122 return NewAgentInventoryRequest(req,agentID);
123 }));
124 */
125
126 }
127
128 #endregion
129
130
131 /// <summary>
132 /// Parses ad request
133 /// </summary>
134 /// <param name="request"></param>
135 /// <param name="AgentId"></param>
136 /// <param name="cap"></param>
137 /// <returns></returns>
138 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
139 {
140 Hashtable responsedata = new Hashtable();
141 responsedata["int_response_code"] = 400; //501; //410; //404;
142 responsedata["content_type"] = "text/plain";
143 responsedata["keepalive"] = false;
144 responsedata["str_response_string"] = "Request wasn't what was expected";
145 ScenePresence avatar;
146
147 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
148 return responsedata;
149
150 OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]);
151 UploadObjectAssetMessage message = new UploadObjectAssetMessage();
152 try
153 {
154 message.Deserialize(r);
155
156 }
157 catch (Exception ex)
158 {
159 m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString());
160 message = null;
161 }
162
163 if (message == null)
164 {
165 responsedata["int_response_code"] = 400; //501; //410; //404;
166 responsedata["content_type"] = "text/plain";
167 responsedata["keepalive"] = false;
168 responsedata["str_response_string"] =
169 "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>";
170
171 return responsedata;
172 }
173
174 Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation);
175 Quaternion rot = Quaternion.Identity;
176 Vector3 rootpos = Vector3.Zero;
177// Quaternion rootrot = Quaternion.Identity;
178
179 SceneObjectGroup rootGroup = null;
180 SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length];
181 for (int i = 0; i < message.Objects.Length; i++)
182 {
183 UploadObjectAssetMessage.Object obj = message.Objects[i];
184 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
185
186 if (i == 0)
187 {
188 rootpos = obj.Position;
189// rootrot = obj.Rotation;
190 }
191
192 // Combine the extraparams data into it's ugly blob again....
193 //int bytelength = 0;
194 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
195 //{
196 // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length;
197 //}
198 //byte[] extraparams = new byte[bytelength];
199 //int position = 0;
200
201
202
203 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
204 //{
205 // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position,
206 // obj.ExtraParams[extparams].ExtraParamData.Length);
207 //
208 // position += obj.ExtraParams[extparams].ExtraParamData.Length;
209 // }
210
211 //pbs.ExtraParams = extraparams;
212 for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
213 {
214 UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams];
215 switch ((ushort)extraParam.Type)
216 {
217 case (ushort)ExtraParamType.Sculpt:
218 Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0);
219
220 pbs.SculptEntry = true;
221
222 pbs.SculptTexture = obj.SculptID;
223 pbs.SculptType = (byte)sculpt.Type;
224
225 break;
226 case (ushort)ExtraParamType.Flexible:
227 Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0);
228 pbs.FlexiEntry = true;
229 pbs.FlexiDrag = flex.Drag;
230 pbs.FlexiForceX = flex.Force.X;
231 pbs.FlexiForceY = flex.Force.Y;
232 pbs.FlexiForceZ = flex.Force.Z;
233 pbs.FlexiGravity = flex.Gravity;
234 pbs.FlexiSoftness = flex.Softness;
235 pbs.FlexiTension = flex.Tension;
236 pbs.FlexiWind = flex.Wind;
237 break;
238 case (ushort)ExtraParamType.Light:
239 Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0);
240 pbs.LightColorA = light.Color.A;
241 pbs.LightColorB = light.Color.B;
242 pbs.LightColorG = light.Color.G;
243 pbs.LightColorR = light.Color.R;
244 pbs.LightCutoff = light.Cutoff;
245 pbs.LightEntry = true;
246 pbs.LightFalloff = light.Falloff;
247 pbs.LightIntensity = light.Intensity;
248 pbs.LightRadius = light.Radius;
249 break;
250 case 0x40:
251 pbs.ReadProjectionData(extraParam.ExtraParamData, 0);
252 break;
253
254 }
255
256
257 }
258 pbs.PathBegin = (ushort) obj.PathBegin;
259 pbs.PathCurve = (byte) obj.PathCurve;
260 pbs.PathEnd = (ushort) obj.PathEnd;
261 pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset;
262 pbs.PathRevolutions = (byte) obj.Revolutions;
263 pbs.PathScaleX = (byte) obj.ScaleX;
264 pbs.PathScaleY = (byte) obj.ScaleY;
265 pbs.PathShearX = (byte) obj.ShearX;
266 pbs.PathShearY = (byte) obj.ShearY;
267 pbs.PathSkew = (sbyte) obj.Skew;
268 pbs.PathTaperX = (sbyte) obj.TaperX;
269 pbs.PathTaperY = (sbyte) obj.TaperY;
270 pbs.PathTwist = (sbyte) obj.Twist;
271 pbs.PathTwistBegin = (sbyte) obj.TwistBegin;
272 pbs.HollowShape = (HollowShape) obj.ProfileHollow;
273 pbs.PCode = (byte) PCode.Prim;
274 pbs.ProfileBegin = (ushort) obj.ProfileBegin;
275 pbs.ProfileCurve = (byte) obj.ProfileCurve;
276 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
277 pbs.Scale = obj.Scale;
278 pbs.State = (byte) 0;
279 SceneObjectPart prim = new SceneObjectPart();
280 prim.UUID = UUID.Random();
281 prim.CreatorID = AgentId;
282 prim.OwnerID = AgentId;
283 prim.GroupID = obj.GroupID;
284 prim.LastOwnerID = prim.OwnerID;
285 prim.CreationDate = Util.UnixTimeSinceEpoch();
286 prim.Name = obj.Name;
287 prim.Description = "";
288
289 prim.PayPrice[0] = -2;
290 prim.PayPrice[1] = -2;
291 prim.PayPrice[2] = -2;
292 prim.PayPrice[3] = -2;
293 prim.PayPrice[4] = -2;
294 Primitive.TextureEntry tmp =
295 new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f"));
296
297 for (int j = 0; j < obj.Faces.Length; j++)
298 {
299 UploadObjectAssetMessage.Object.Face face = obj.Faces[j];
300
301 Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j);
302
303 primFace.Bump = face.Bump;
304 primFace.RGBA = face.Color;
305 primFace.Fullbright = face.Fullbright;
306 primFace.Glow = face.Glow;
307 primFace.TextureID = face.ImageID;
308 primFace.Rotation = face.ImageRot;
309 primFace.MediaFlags = ((face.MediaFlags & 1) != 0);
310
311 primFace.OffsetU = face.OffsetS;
312 primFace.OffsetV = face.OffsetT;
313 primFace.RepeatU = face.ScaleS;
314 primFace.RepeatV = face.ScaleT;
315 primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
316 }
317 pbs.TextureEntry = tmp.GetBytes();
318 prim.Shape = pbs;
319 prim.Scale = obj.Scale;
320
321
322 SceneObjectGroup grp = new SceneObjectGroup();
323
324 grp.SetRootPart(prim);
325 prim.ParentID = 0;
326 if (i == 0)
327 {
328 rootGroup = grp;
329
330 }
331 grp.AttachToScene(m_scene);
332 grp.AbsolutePosition = obj.Position;
333 prim.RotationOffset = obj.Rotation;
334
335 grp.RootPart.IsAttachment = false;
336 // Required for linking
337 grp.RootPart.UpdateFlag = 0;
338
339 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
340 {
341 m_scene.AddSceneObject(grp);
342 grp.AbsolutePosition = obj.Position;
343 }
344 allparts[i] = grp;
345
346 }
347
348 for (int j = 1; j < allparts.Length; j++)
349 {
350 rootGroup.RootPart.UpdateFlag = 0;
351 allparts[j].RootPart.UpdateFlag = 0;
352 rootGroup.LinkToGroup(allparts[j]);
353 }
354
355 rootGroup.ScheduleGroupForFullUpdate();
356 pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
357
358 responsedata["int_response_code"] = 200; //501; //410; //404;
359 responsedata["content_type"] = "text/plain";
360 responsedata["keepalive"] = false;
361 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId));
362
363 return responsedata;
364 }
365
366 private string ConvertUintToBytes(uint val)
367 {
368 byte[] resultbytes = Utils.UIntToBytes(val);
369 if (BitConverter.IsLittleEndian)
370 Array.Reverse(resultbytes);
371 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
372 }
373 }
374} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
new file mode 100644
index 0000000..55f220d
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -0,0 +1,131 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using Mono.Addins;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40using Caps = OpenSim.Framework.Capabilities.Caps;
41using OpenSim.Capabilities.Handlers;
42
43namespace OpenSim.Region.ClientStack.Linden
44{
45
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47 public class WebFetchInvDescModule : INonSharedRegionModule
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private Scene m_scene;
52
53 private IInventoryService m_InventoryService;
54 private ILibraryService m_LibraryService;
55 private bool m_Enabled = false;
56 private string m_URL;
57
58 #region ISharedRegionModule Members
59
60 public void Initialise(IConfigSource source)
61 {
62 IConfig config = source.Configs["ClientStack.LindenCaps"];
63 if (config == null)
64 return;
65
66 m_URL = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
67 // Cap doesn't exist
68 if (m_URL != string.Empty)
69 m_Enabled = true;
70 }
71
72 public void AddRegion(Scene s)
73 {
74 if (!m_Enabled)
75 return;
76
77 m_scene = s;
78 }
79
80 public void RemoveRegion(Scene s)
81 {
82 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
83 m_scene = null;
84 }
85
86 public void RegionLoaded(Scene s)
87 {
88 if (!m_Enabled)
89 return;
90
91 m_InventoryService = m_scene.InventoryService; ;
92 m_LibraryService = m_scene.LibraryService;
93 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
94 }
95
96 public void PostInitialise()
97 {
98 }
99
100 public void Close() { }
101
102 public string Name { get { return "WebFetchInvDescModule"; } }
103
104 public Type ReplaceableInterface
105 {
106 get { return null; }
107 }
108
109 #endregion
110
111 public void RegisterCaps(UUID agentID, Caps caps)
112 {
113 UUID capID = UUID.Random();
114
115 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
116 if (m_URL == "localhost")
117 {
118 m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
119 WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
120 IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/" + UUID.Random(), webFetchHandler.FetchInventoryDescendentsRequest);
121 caps.RegisterHandler("WebFetchInventoryDescendents", reqHandler);
122 }
123 else
124 {
125 m_log.InfoFormat("[WEBFETCHINVENTORYDESCENDANTS]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
126 caps.RegisterHandler("WebFetchInventoryDescendents", m_URL);
127 }
128 }
129
130 }
131}