aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities/Caps.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities/Caps.cs')
-rw-r--r--OpenSim/Capabilities/Caps.cs1261
1 files changed, 26 insertions, 1235 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs
index c98498d..95bb465 100644
--- a/OpenSim/Capabilities/Caps.cs
+++ b/OpenSim/Capabilities/Caps.cs
@@ -41,28 +41,6 @@ using OpenSim.Services.Interfaces;
41 41
42namespace OpenSim.Framework.Capabilities 42namespace OpenSim.Framework.Capabilities
43{ 43{
44 public delegate void UpLoadedAsset(
45 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
46 byte[] data, string inventoryType, string assetType);
47
48 public delegate void UploadedBakedTexture(UUID assetID, byte[] data);
49
50 public delegate UUID UpdateItem(UUID itemID, byte[] data);
51
52 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
53
54 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
55
56 public delegate void NewAsset(AssetBase asset);
57
58 public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
59
60 public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
61 bool isScriptRunning, byte[] data);
62
63 public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
64 bool fetchFolders, bool fetchItems, int sortOrder, out int version);
65
66 /// <summary> 44 /// <summary>
67 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that 45 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
68 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want 46 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
@@ -87,34 +65,34 @@ namespace OpenSim.Framework.Capabilities
87 private CapsHandlers m_capsHandlers; 65 private CapsHandlers m_capsHandlers;
88 private Dictionary<string, string> m_externalCapsHandlers; 66 private Dictionary<string, string> m_externalCapsHandlers;
89 67
90 private static readonly string m_requestPath = "0000/";
91 // private static readonly string m_mapLayerPath = "0001/";
92 private static readonly string m_newInventory = "0002/";
93 //private static readonly string m_requestTexture = "0003/";
94 private static readonly string m_notecardUpdatePath = "0004/";
95 private static readonly string m_notecardTaskUpdatePath = "0005/";
96// private static readonly string m_fetchInventoryPath = "0006/";
97
98 // The following entries are in a module, however, they are also here so that we don't re-assign
99 // the path to another cap by mistake.
100 // private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; // This is in a module.
101 // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module.
102
103 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
104 private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
105
106 //private string eventQueue = "0100/";
107 private IScene m_Scene;
108 private IHttpServer m_httpListener; 68 private IHttpServer m_httpListener;
109 private UUID m_agentID; 69 private UUID m_agentID;
110 private IAssetService m_assetCache;
111 private int m_eventQueueCount = 1;
112 private Queue<string> m_capsEventQueue = new Queue<string>();
113 private bool m_dumpAssetsToFile;
114 private string m_regionName; 70 private string m_regionName;
115 private object m_fetchLock = new Object();
116 71
117 private bool m_persistBakedTextures = false; 72 public UUID AgentID
73 {
74 get { return m_agentID; }
75 }
76
77 public string RegionName
78 {
79 get { return m_regionName; }
80 }
81
82 public string HostName
83 {
84 get { return m_httpListenerHostName; }
85 }
86
87 public uint Port
88 {
89 get { return m_httpListenPort; }
90 }
91
92 public IHttpServer HttpListener
93 {
94 get { return m_httpListener; }
95 }
118 96
119 public bool SSLCaps 97 public bool SSLCaps
120 { 98 {
@@ -129,35 +107,15 @@ namespace OpenSim.Framework.Capabilities
129 get { return m_capsHandlers; } 107 get { return m_capsHandlers; }
130 } 108 }
131 109
132 // These are callbacks which will be setup by the scene so that we can update scene data when we 110 public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
133 // receive capability calls 111 UUID agent, string regionName)
134 public NewInventoryItem AddNewInventoryItem = null;
135 public NewAsset AddNewAsset = null;
136 public ItemUpdatedCallback ItemUpdatedCall = null;
137 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
138 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
139 public GetClientDelegate GetClient = null;
140
141 public Caps(IScene scene, IAssetService assetCache, IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
142 UUID agent, bool dumpAssetsToFile, string regionName)
143 { 112 {
144 m_Scene = scene;
145 m_assetCache = assetCache;
146 m_capsObjectPath = capsPath; 113 m_capsObjectPath = capsPath;
147 m_httpListener = httpServer; 114 m_httpListener = httpServer;
148 m_httpListenerHostName = httpListen; 115 m_httpListenerHostName = httpListen;
149 116
150 m_httpListenPort = httpPort; 117 m_httpListenPort = httpPort;
151 118
152 m_persistBakedTextures = false;
153 IConfigSource config = m_Scene.Config;
154 if (config != null)
155 {
156 IConfig sconfig = config.Configs["Startup"];
157 if (sconfig != null)
158 m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures);
159 }
160
161 if (httpServer != null && httpServer.UseSSL) 119 if (httpServer != null && httpServer.UseSSL)
162 { 120 {
163 m_httpListenPort = httpServer.SSLPort; 121 m_httpListenPort = httpServer.SSLPort;
@@ -166,98 +124,12 @@ namespace OpenSim.Framework.Capabilities
166 } 124 }
167 125
168 m_agentID = agent; 126 m_agentID = agent;
169 m_dumpAssetsToFile = dumpAssetsToFile;
170 m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); 127 m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
171 m_externalCapsHandlers = new Dictionary<string, string>(); 128 m_externalCapsHandlers = new Dictionary<string, string>();
172 m_regionName = regionName; 129 m_regionName = regionName;
173 } 130 }
174 131
175 /// <summary> 132 /// <summary>
176 /// Register all CAPS http service handlers
177 /// </summary>
178 public void RegisterHandlers()
179 {
180 DeregisterHandlers();
181
182 string capsBase = "/CAPS/" + m_capsObjectPath;
183
184 RegisterRegionServiceHandlers(capsBase);
185 RegisterInventoryServiceHandlers(capsBase);
186 }
187
188 public void RegisterRegionServiceHandlers(string capsBase)
189 {
190 try
191 {
192 // the root of all evil
193 m_capsHandlers["SEED"] = new RestStreamHandler("POST", capsBase + m_requestPath, CapsRequest);
194 m_log.DebugFormat(
195 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_agentID);
196
197 //m_capsHandlers["MapLayer"] =
198 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
199 // capsBase + m_mapLayerPath,
200 // GetMapLayer);
201 m_capsHandlers["UpdateScriptTaskInventory"] =
202 new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
203 m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"];
204 m_capsHandlers["UploadBakedTexture"] =
205 new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture);
206
207 }
208 catch (Exception e)
209 {
210 m_log.Error("[CAPS]: " + e.ToString());
211 }
212 }
213
214 public void RegisterInventoryServiceHandlers(string capsBase)
215 {
216 try
217 {
218 // I don't think this one works...
219 m_capsHandlers["NewFileAgentInventory"] =
220 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
221 capsBase + m_newInventory,
222 NewAgentInventoryRequest);
223 m_capsHandlers["UpdateNotecardAgentInventory"] =
224 new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
225 m_capsHandlers["UpdateScriptAgentInventory"] = m_capsHandlers["UpdateNotecardAgentInventory"];
226 m_capsHandlers["UpdateScriptAgent"] = m_capsHandlers["UpdateScriptAgentInventory"];
227
228 // As of RC 1.22.9 of the Linden client this is
229 // supported
230
231 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
232
233 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
234 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
235 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
236 // but when I went on the Linden grid, the
237 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
238 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
239 //
240 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
241 // we will be
242 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
243 // m_capsHandlers["FetchInventoryDescendents"] =
244 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
245
246 // m_capsHandlers["FetchInventoryDescendents"] =
247 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
248 // capsBase + m_fetchInventory,
249 // FetchInventory));
250 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
251 // capsBase + m_requestTexture,
252 // RequestTexture);
253 }
254 catch (Exception e)
255 {
256 m_log.Error("[CAPS]: " + e.ToString());
257 }
258 }
259
260 /// <summary>
261 /// Register a handler. This allows modules to register handlers. 133 /// Register a handler. This allows modules to register handlers.
262 /// </summary> 134 /// </summary>
263 /// <param name="capName"></param> 135 /// <param name="capName"></param>
@@ -296,1086 +168,5 @@ namespace OpenSim.Framework.Capabilities
296 } 168 }
297 } 169 }
298 } 170 }
299
300 /// <summary>
301 /// Construct a client response detailing all the capabilities this server can provide.
302 /// </summary>
303 /// <param name="request"></param>
304 /// <param name="path"></param>
305 /// <param name="param"></param>
306 /// <param name="httpRequest">HTTP request header object</param>
307 /// <param name="httpResponse">HTTP response header object</param>
308 /// <returns></returns>
309 public string CapsRequest(string request, string path, string param,
310 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
311 {
312 m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
313
314 if (!m_Scene.CheckClient(m_agentID, httpRequest.RemoteIPEndPoint))
315 {
316 m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
317 return string.Empty;
318 }
319
320 string result = LLSDHelpers.SerialiseLLSDReply(m_capsHandlers.CapsDetails);
321
322 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
323
324 return result;
325 }
326
327 // FIXME: these all should probably go into the respective region
328 // modules
329
330 /// <summary>
331 /// Processes a fetch inventory request and sends the reply
332
333 /// </summary>
334 /// <param name="request"></param>
335 /// <param name="path"></param>
336 /// <param name="param"></param>
337 /// <returns></returns>
338 // Request is like:
339 //<llsd>
340 // <map><key>folders</key>
341 // <array>
342 // <map>
343 // <key>fetch-folders</key><boolean>1</boolean><key>fetch-items</key><boolean>1</boolean><key>folder-id</key><uuid>8e1e3a30-b9bf-11dc-95ff-0800200c9a66</uuid><key>owner-id</key><uuid>11111111-1111-0000-0000-000100bba000</uuid><key>sort-order</key><integer>1</integer>
344 // </map>
345 // </array>
346 // </map>
347 //</llsd>
348 //
349 // multiple fetch-folder maps are allowed within the larger folders map.
350 public string FetchInventoryRequest(string request, string path, string param)
351 {
352 // string unmodifiedRequest = request.ToString();
353
354 //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest);
355 m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName);
356
357 Hashtable hash = new Hashtable();
358 try
359 {
360 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
361 }
362 catch (LLSD.LLSDParseException pe)
363 {
364 m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
365 m_log.Error("Request: " + request.ToString());
366 }
367
368 ArrayList foldersrequested = (ArrayList)hash["folders"];
369
370 string response = "";
371
372 for (int i = 0; i < foldersrequested.Count; i++)
373 {
374 string inventoryitemstr = "";
375 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
376
377 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
378 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
379 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
380
381 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
382 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
383 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
384
385 response += inventoryitemstr;
386 }
387
388 if (response.Length == 0)
389 {
390 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
391 // Therefore, I'm concluding that the client only has so many threads available to do requests
392 // and when a thread stalls.. is stays stalled.
393 // Therefore we need to return something valid
394 response = "<llsd><map><key>folders</key><array /></map></llsd>";
395 }
396 else
397 {
398 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
399 }
400
401 //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml");
402 //m_log.Debug(Util.GetFormattedXml(response));
403
404 return response;
405 }
406
407 public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse)
408 {
409 // nasty temporary hack here, the linden client falsely
410 // identifies the uuid 00000000-0000-0000-0000-000000000000
411 // as a string which breaks us
412 //
413 // correctly mark it as a uuid
414 //
415 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
416
417 // another hack <integer>1</integer> results in a
418 // System.ArgumentException: Object type System.Int32 cannot
419 // be converted to target type: System.Boolean
420 //
421 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
422 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
423
424 Hashtable hash = new Hashtable();
425 try
426 {
427 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
428 }
429 catch (LLSD.LLSDParseException pe)
430 {
431 m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
432 m_log.Error("Request: " + request.ToString());
433 }
434
435 ArrayList foldersrequested = (ArrayList)hash["folders"];
436
437 string response = "";
438 lock (m_fetchLock)
439 {
440 for (int i = 0; i < foldersrequested.Count; i++)
441 {
442 string inventoryitemstr = "";
443 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
444
445 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
446
447 try{
448 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
449 }
450 catch(Exception e)
451 {
452 m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e);
453 }
454 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
455
456 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
457 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
458 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
459
460 response += inventoryitemstr;
461 }
462
463
464 if (response.Length == 0)
465 {
466 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
467 // Therefore, I'm concluding that the client only has so many threads available to do requests
468 // and when a thread stalls.. is stays stalled.
469 // Therefore we need to return something valid
470 response = "<llsd><map><key>folders</key><array /></map></llsd>";
471 }
472 else
473 {
474 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
475 }
476
477 //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
478 //m_log.Debug("[CAPS] "+response);
479
480 }
481 return response;
482 }
483
484
485
486 /// <summary>
487 /// Construct an LLSD reply packet to a CAPS inventory request
488 /// </summary>
489 /// <param name="invFetch"></param>
490 /// <returns></returns>
491 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
492 {
493 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
494 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
495 contents.agent_id = m_agentID;
496 contents.owner_id = invFetch.owner_id;
497 contents.folder_id = invFetch.folder_id;
498
499 reply.folders.Array.Add(contents);
500 InventoryCollection inv = new InventoryCollection();
501 inv.Folders = new List<InventoryFolderBase>();
502 inv.Items = new List<InventoryItemBase>();
503 int version = 0;
504 if (CAPSFetchInventoryDescendents != null)
505 {
506 inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
507 }
508
509 if (inv.Folders != null)
510 {
511 foreach (InventoryFolderBase invFolder in inv.Folders)
512 {
513 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
514 }
515 }
516
517 if (inv.Items != null)
518 {
519 foreach (InventoryItemBase invItem in inv.Items)
520 {
521 contents.items.Array.Add(ConvertInventoryItem(invItem));
522 }
523 }
524
525 contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
526 contents.version = version;
527
528 return reply;
529 }
530
531 /// <summary>
532 /// Convert an internal inventory folder object into an LLSD object.
533 /// </summary>
534 /// <param name="invFolder"></param>
535 /// <returns></returns>
536 private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
537 {
538 LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
539 llsdFolder.folder_id = invFolder.ID;
540 llsdFolder.parent_id = invFolder.ParentID;
541 llsdFolder.name = invFolder.Name;
542 if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length)
543 llsdFolder.type = "-1";
544 else
545 llsdFolder.type = TaskInventoryItem.Types[invFolder.Type];
546 llsdFolder.preferred_type = "-1";
547
548 return llsdFolder;
549 }
550
551 /// <summary>
552 /// Convert an internal inventory item object into an LLSD object.
553 /// </summary>
554 /// <param name="invItem"></param>
555 /// <returns></returns>
556 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
557 {
558 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
559 llsdItem.asset_id = invItem.AssetID;
560 llsdItem.created_at = invItem.CreationDate;
561 llsdItem.desc = invItem.Description;
562 llsdItem.flags = (int)invItem.Flags;
563 llsdItem.item_id = invItem.ID;
564 llsdItem.name = invItem.Name;
565 llsdItem.parent_id = invItem.Folder;
566 try
567 {
568 // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions.
569 llsdItem.type = TaskInventoryItem.Types[invItem.AssetType];
570 llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType];
571 }
572 catch (Exception e)
573 {
574 m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e);
575 }
576 llsdItem.permissions = new LLSDPermissions();
577 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
578 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
579 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
580 llsdItem.permissions.group_id = invItem.GroupID;
581 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
582 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
583 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
584 llsdItem.permissions.owner_id = m_agentID;
585 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
586 llsdItem.sale_info = new LLSDSaleInfo();
587 llsdItem.sale_info.sale_price = invItem.SalePrice;
588 switch (invItem.SaleType)
589 {
590 default:
591 llsdItem.sale_info.sale_type = "not";
592 break;
593 case 1:
594 llsdItem.sale_info.sale_type = "original";
595 break;
596 case 2:
597 llsdItem.sale_info.sale_type = "copy";
598 break;
599 case 3:
600 llsdItem.sale_info.sale_type = "contents";
601 break;
602 }
603
604 return llsdItem;
605 }
606
607 /// <summary>
608 ///
609 /// </summary>
610 /// <param name="mapReq"></param>
611 /// <returns></returns>
612 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
613 {
614 m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName);
615 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
616 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
617 return mapResponse;
618 }
619
620 /// <summary>
621 ///
622 /// </summary>
623 /// <returns></returns>
624 protected static OSDMapLayer GetOSDMapLayerResponse()
625 {
626 OSDMapLayer mapLayer = new OSDMapLayer();
627 mapLayer.Right = 5000;
628 mapLayer.Top = 5000;
629 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
630
631 return mapLayer;
632 }
633
634 /// <summary>
635 ///
636 /// </summary>
637 /// <param name="request"></param>
638 /// <param name="path"></param>
639 /// <param name="param"></param>
640 /// <returns></returns>
641 public string RequestTexture(string request, string path, string param)
642 {
643 m_log.Debug("texture request " + request);
644 // Needs implementing (added to remove compiler warning)
645 return String.Empty;
646 }
647
648 #region EventQueue (Currently not enabled)
649
650 /// <summary>
651 ///
652 /// </summary>
653 /// <param name="request"></param>
654 /// <param name="path"></param>
655 /// <param name="param"></param>
656 /// <returns></returns>
657 public string ProcessEventQueue(string request, string path, string param)
658 {
659 string res = String.Empty;
660
661 if (m_capsEventQueue.Count > 0)
662 {
663 lock (m_capsEventQueue)
664 {
665 string item = m_capsEventQueue.Dequeue();
666 res = item;
667 }
668 }
669 else
670 {
671 res = CreateEmptyEventResponse();
672 }
673 return res;
674 }
675
676 /// <summary>
677 ///
678 /// </summary>
679 /// <param name="caps"></param>
680 /// <param name="ipAddressPort"></param>
681 /// <returns></returns>
682 public string CreateEstablishAgentComms(string caps, string ipAddressPort)
683 {
684 LLSDCapEvent eventItem = new LLSDCapEvent();
685 eventItem.id = m_eventQueueCount;
686 //should be creating a EstablishAgentComms item, but there isn't a class for it yet
687 eventItem.events.Array.Add(new LLSDEmpty());
688 string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
689 m_eventQueueCount++;
690
691 m_capsEventQueue.Enqueue(res);
692 return res;
693 }
694
695 /// <summary>
696 ///
697 /// </summary>
698 /// <returns></returns>
699 public string CreateEmptyEventResponse()
700 {
701 LLSDCapEvent eventItem = new LLSDCapEvent();
702 eventItem.id = m_eventQueueCount;
703 eventItem.events.Array.Add(new LLSDEmpty());
704 string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
705 m_eventQueueCount++;
706 return res;
707 }
708
709 #endregion
710
711 /// <summary>
712 /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
713 /// </summary>
714 /// <param name="request"></param>
715 /// <param name="path"></param>
716 /// <param name="param"></param>
717 /// <param name="httpRequest">HTTP request header object</param>
718 /// <param name="httpResponse">HTTP response header object</param>
719 /// <returns></returns>
720 public string ScriptTaskInventory(string request, string path, string param,
721 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
722 {
723 try
724 {
725 m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
726 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
727
728 Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request));
729 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
730 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
731
732 string capsBase = "/CAPS/" + m_capsObjectPath;
733 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
734
735 TaskInventoryScriptUpdater uploader =
736 new TaskInventoryScriptUpdater(
737 llsdUpdateRequest.item_id,
738 llsdUpdateRequest.task_id,
739 llsdUpdateRequest.is_script_running,
740 capsBase + uploaderPath,
741 m_httpListener,
742 m_dumpAssetsToFile);
743 uploader.OnUpLoad += TaskScriptUpdated;
744
745 m_httpListener.AddStreamHandler(
746 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
747
748 string protocol = "http://";
749
750 if (m_httpListener.UseSSL)
751 protocol = "https://";
752
753 string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
754 uploaderPath;
755
756 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
757 uploadResponse.uploader = uploaderURL;
758 uploadResponse.state = "upload";
759
760// m_log.InfoFormat("[CAPS]: " +
761// "ScriptTaskInventory response: {0}",
762// LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
763
764 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
765 }
766 catch (Exception e)
767 {
768 m_log.Error("[CAPS]: " + e.ToString());
769 }
770
771 return null;
772 }
773
774 public string UploadBakedTexture(string request, string path,
775 string param, OSHttpRequest httpRequest,
776 OSHttpResponse httpResponse)
777 {
778 try
779 {
780// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " +
781// m_regionName);
782
783 string capsBase = "/CAPS/" + m_capsObjectPath;
784 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
785
786 BakedTextureUploader uploader =
787 new BakedTextureUploader(capsBase + uploaderPath,
788 m_httpListener);
789 uploader.OnUpLoad += BakedTextureUploaded;
790
791 m_httpListener.AddStreamHandler(
792 new BinaryStreamHandler("POST", capsBase + uploaderPath,
793 uploader.uploaderCaps));
794
795 string protocol = "http://";
796
797 if (m_httpListener.UseSSL)
798 protocol = "https://";
799
800 string uploaderURL = protocol + m_httpListenerHostName + ":" +
801 m_httpListenPort.ToString() + capsBase + uploaderPath;
802
803 LLSDAssetUploadResponse uploadResponse =
804 new LLSDAssetUploadResponse();
805 uploadResponse.uploader = uploaderURL;
806 uploadResponse.state = "upload";
807
808 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
809 }
810 catch (Exception e)
811 {
812 m_log.Error("[CAPS]: " + e.ToString());
813 }
814
815 return null;
816 }
817
818 /// <summary>
819 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
820 /// </summary>
821 /// <param name="request"></param>
822 /// <param name="path"></param>
823 /// <param name="param"></param>
824 /// <returns></returns>
825 public string NoteCardAgentInventory(string request, string path, string param,
826 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
827 {
828 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request);
829 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request);
830
831 //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request));
832 Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Utils.StringToBytes(request));
833 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
834 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
835
836 string capsBase = "/CAPS/" + m_capsObjectPath;
837 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
838
839 ItemUpdater uploader =
840 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
841 uploader.OnUpLoad += ItemUpdated;
842
843 m_httpListener.AddStreamHandler(
844 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
845
846 string protocol = "http://";
847
848 if (m_httpListener.UseSSL)
849 protocol = "https://";
850
851 string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
852 uploaderPath;
853
854 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
855 uploadResponse.uploader = uploaderURL;
856 uploadResponse.state = "upload";
857
858// m_log.InfoFormat("[CAPS]: " +
859// "NoteCardAgentInventory response: {0}",
860// LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
861
862 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
863 }
864
865 /// <summary>
866 ///
867 /// </summary>
868 /// <param name="llsdRequest"></param>
869 /// <returns></returns>
870 public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
871 {
872 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
873 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
874
875 if (llsdRequest.asset_type == "texture" ||
876 llsdRequest.asset_type == "animation" ||
877 llsdRequest.asset_type == "sound")
878 {
879 IClientAPI client = null;
880 IScene scene = null;
881 if (GetClient != null)
882 {
883 client = GetClient(m_agentID);
884 scene = client.Scene;
885
886 IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
887
888 if (mm != null)
889 {
890 if (!mm.UploadCovered(client, mm.UploadCharge))
891 {
892 if (client != null)
893 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
894
895 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
896 errorResponse.uploader = "";
897 errorResponse.state = "error";
898 return errorResponse;
899 }
900 }
901 }
902 }
903
904
905 string assetName = llsdRequest.name;
906 string assetDes = llsdRequest.description;
907 string capsBase = "/CAPS/" + m_capsObjectPath;
908 UUID newAsset = UUID.Random();
909 UUID newInvItem = UUID.Random();
910 UUID parentFolder = llsdRequest.folder_id;
911 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
912
913 AssetUploader uploader =
914 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
915 llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
916 m_httpListener.AddStreamHandler(
917 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
918
919 string protocol = "http://";
920
921 if (m_httpListener.UseSSL)
922 protocol = "https://";
923
924 string uploaderURL = protocol + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
925 uploaderPath;
926
927 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
928 uploadResponse.uploader = uploaderURL;
929 uploadResponse.state = "upload";
930 uploader.OnUpLoad += UploadCompleteHandler;
931 return uploadResponse;
932 }
933
934 /// <summary>
935 ///
936 /// </summary>
937 /// <param name="assetID"></param>
938 /// <param name="inventoryItem"></param>
939 /// <param name="data"></param>
940 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
941 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
942 string assetType)
943 {
944 sbyte assType = 0;
945 sbyte inType = 0;
946
947 if (inventoryType == "sound")
948 {
949 inType = 1;
950 assType = 1;
951 }
952 else if (inventoryType == "animation")
953 {
954 inType = 19;
955 assType = 20;
956 }
957 else if (inventoryType == "wearable")
958 {
959 inType = 18;
960 switch (assetType)
961 {
962 case "bodypart":
963 assType = 13;
964 break;
965 case "clothing":
966 assType = 5;
967 break;
968 }
969 }
970
971 AssetBase asset;
972 asset = new AssetBase(assetID, assetName, assType, m_agentID.ToString());
973 asset.Data = data;
974 if (AddNewAsset != null)
975 AddNewAsset(asset);
976 else if (m_assetCache != null)
977 m_assetCache.Store(asset);
978
979 InventoryItemBase item = new InventoryItemBase();
980 item.Owner = m_agentID;
981 item.CreatorId = m_agentID.ToString();
982 item.CreatorData = String.Empty;
983 item.ID = inventoryItem;
984 item.AssetID = asset.FullID;
985 item.Description = assetDescription;
986 item.Name = assetName;
987 item.AssetType = assType;
988 item.InvType = inType;
989 item.Folder = parentFolder;
990 item.CurrentPermissions = (uint)PermissionMask.All;
991 item.BasePermissions = (uint)PermissionMask.All;
992 item.EveryOnePermissions = 0;
993 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
994 item.CreationDate = Util.UnixTimeSinceEpoch();
995
996 if (AddNewInventoryItem != null)
997 {
998 AddNewInventoryItem(m_agentID, item);
999 }
1000 }
1001
1002 public void BakedTextureUploaded(UUID assetID, byte[] data)
1003 {
1004// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
1005
1006 AssetBase asset;
1007 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
1008 asset.Data = data;
1009 asset.Temporary = true;
1010 asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are
1011 m_assetCache.Store(asset);
1012 }
1013
1014 /// <summary>
1015 /// Called when new asset data for an agent inventory item update has been uploaded.
1016 /// </summary>
1017 /// <param name="itemID">Item to update</param>
1018 /// <param name="data">New asset data</param>
1019 /// <returns></returns>
1020 public UUID ItemUpdated(UUID itemID, byte[] data)
1021 {
1022 if (ItemUpdatedCall != null)
1023 {
1024 return ItemUpdatedCall(m_agentID, itemID, data);
1025 }
1026
1027 return UUID.Zero;
1028 }
1029
1030 /// <summary>
1031 /// Called when new asset data for an agent inventory item update has been uploaded.
1032 /// </summary>
1033 /// <param name="itemID">Item to update</param>
1034 /// <param name="primID">Prim containing item to update</param>
1035 /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
1036 /// <param name="data">New asset data</param>
1037 public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
1038 {
1039 if (TaskScriptUpdatedCall != null)
1040 {
1041 ArrayList e = TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
1042 foreach (Object item in e)
1043 errors.Add(item);
1044 }
1045 }
1046
1047 public class AssetUploader
1048 {
1049 public event UpLoadedAsset OnUpLoad;
1050 private UpLoadedAsset handlerUpLoad = null;
1051
1052 private string uploaderPath = String.Empty;
1053 private UUID newAssetID;
1054 private UUID inventoryItemID;
1055 private UUID parentFolder;
1056 private IHttpServer httpListener;
1057 private bool m_dumpAssetsToFile;
1058 private string m_assetName = String.Empty;
1059 private string m_assetDes = String.Empty;
1060
1061 private string m_invType = String.Empty;
1062 private string m_assetType = String.Empty;
1063
1064 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1065 UUID parentFolderID, string invType, string assetType, string path,
1066 IHttpServer httpServer, bool dumpAssetsToFile)
1067 {
1068 m_assetName = assetName;
1069 m_assetDes = description;
1070 newAssetID = assetID;
1071 inventoryItemID = inventoryItem;
1072 uploaderPath = path;
1073 httpListener = httpServer;
1074 parentFolder = parentFolderID;
1075 m_assetType = assetType;
1076 m_invType = invType;
1077 m_dumpAssetsToFile = dumpAssetsToFile;
1078 }
1079
1080 /// <summary>
1081 ///
1082 /// </summary>
1083 /// <param name="data"></param>
1084 /// <param name="path"></param>
1085 /// <param name="param"></param>
1086 /// <returns></returns>
1087 public string uploaderCaps(byte[] data, string path, string param)
1088 {
1089 UUID inv = inventoryItemID;
1090 string res = String.Empty;
1091 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1092 uploadComplete.new_asset = newAssetID.ToString();
1093 uploadComplete.new_inventory_item = inv;
1094 uploadComplete.state = "complete";
1095
1096 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1097
1098 httpListener.RemoveStreamHandler("POST", uploaderPath);
1099
1100 // TODO: probably make this a better set of extensions here
1101 string extension = ".jp2";
1102 if (m_invType != "image")
1103 {
1104 extension = ".dat";
1105 }
1106
1107 if (m_dumpAssetsToFile)
1108 {
1109 SaveAssetToFile(m_assetName + extension, data);
1110 }
1111 handlerUpLoad = OnUpLoad;
1112 if (handlerUpLoad != null)
1113 {
1114 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
1115 }
1116
1117 return res;
1118 }
1119 ///Left this in and commented in case there are unforseen issues
1120 //private void SaveAssetToFile(string filename, byte[] data)
1121 //{
1122 // FileStream fs = File.Create(filename);
1123 // BinaryWriter bw = new BinaryWriter(fs);
1124 // bw.Write(data);
1125 // bw.Close();
1126 // fs.Close();
1127 //}
1128 private static void SaveAssetToFile(string filename, byte[] data)
1129 {
1130 string assetPath = "UserAssets";
1131 if (!Directory.Exists(assetPath))
1132 {
1133 Directory.CreateDirectory(assetPath);
1134 }
1135 FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
1136 BinaryWriter bw = new BinaryWriter(fs);
1137 bw.Write(data);
1138 bw.Close();
1139 fs.Close();
1140 }
1141 }
1142
1143 /// <summary>
1144 /// This class is a callback invoked when a client sends asset data to
1145 /// an agent inventory notecard update url
1146 /// </summary>
1147 public class ItemUpdater
1148 {
1149 public event UpdateItem OnUpLoad;
1150
1151 private UpdateItem handlerUpdateItem = null;
1152
1153 private string uploaderPath = String.Empty;
1154 private UUID inventoryItemID;
1155 private IHttpServer httpListener;
1156 private bool m_dumpAssetToFile;
1157
1158 public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile)
1159 {
1160 m_dumpAssetToFile = dumpAssetToFile;
1161
1162 inventoryItemID = inventoryItem;
1163 uploaderPath = path;
1164 httpListener = httpServer;
1165 }
1166
1167 /// <summary>
1168 ///
1169 /// </summary>
1170 /// <param name="data"></param>
1171 /// <param name="path"></param>
1172 /// <param name="param"></param>
1173 /// <returns></returns>
1174 public string uploaderCaps(byte[] data, string path, string param)
1175 {
1176 UUID inv = inventoryItemID;
1177 string res = String.Empty;
1178 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1179 UUID assetID = UUID.Zero;
1180 handlerUpdateItem = OnUpLoad;
1181 if (handlerUpdateItem != null)
1182 {
1183 assetID = handlerUpdateItem(inv, data);
1184 }
1185
1186 uploadComplete.new_asset = assetID.ToString();
1187 uploadComplete.new_inventory_item = inv;
1188 uploadComplete.state = "complete";
1189
1190 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1191
1192 httpListener.RemoveStreamHandler("POST", uploaderPath);
1193
1194 if (m_dumpAssetToFile)
1195 {
1196 SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1197 }
1198
1199 return res;
1200 }
1201 ///Left this in and commented in case there are unforseen issues
1202 //private void SaveAssetToFile(string filename, byte[] data)
1203 //{
1204 // FileStream fs = File.Create(filename);
1205 // BinaryWriter bw = new BinaryWriter(fs);
1206 // bw.Write(data);
1207 // bw.Close();
1208 // fs.Close();
1209 //}
1210 private static void SaveAssetToFile(string filename, byte[] data)
1211 {
1212 string assetPath = "UserAssets";
1213 if (!Directory.Exists(assetPath))
1214 {
1215 Directory.CreateDirectory(assetPath);
1216 }
1217 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1218 BinaryWriter bw = new BinaryWriter(fs);
1219 bw.Write(data);
1220 bw.Close();
1221 fs.Close();
1222 }
1223 }
1224
1225 /// <summary>
1226 /// This class is a callback invoked when a client sends asset data to
1227 /// a task inventory script update url
1228 /// </summary>
1229 public class TaskInventoryScriptUpdater
1230 {
1231 public event UpdateTaskScript OnUpLoad;
1232
1233 private UpdateTaskScript handlerUpdateTaskScript = null;
1234
1235 private string uploaderPath = String.Empty;
1236 private UUID inventoryItemID;
1237 private UUID primID;
1238 private bool isScriptRunning;
1239 private IHttpServer httpListener;
1240 private bool m_dumpAssetToFile;
1241
1242 public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning,
1243 string path, IHttpServer httpServer, bool dumpAssetToFile)
1244 {
1245 m_dumpAssetToFile = dumpAssetToFile;
1246
1247 this.inventoryItemID = inventoryItemID;
1248 this.primID = primID;
1249
1250 // This comes in over the packet as an integer, but actually appears to be treated as a bool
1251 this.isScriptRunning = (0 == isScriptRunning ? false : true);
1252
1253 uploaderPath = path;
1254 httpListener = httpServer;
1255 }
1256
1257 /// <summary>
1258 ///
1259 /// </summary>
1260 /// <param name="data"></param>
1261 /// <param name="path"></param>
1262 /// <param name="param"></param>
1263 /// <returns></returns>
1264 public string uploaderCaps(byte[] data, string path, string param)
1265 {
1266 try
1267 {
1268// m_log.InfoFormat("[CAPS]: " +
1269// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
1270// data, path, param));
1271
1272 string res = String.Empty;
1273 LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
1274
1275 ArrayList errors = new ArrayList();
1276 handlerUpdateTaskScript = OnUpLoad;
1277 if (handlerUpdateTaskScript != null)
1278 {
1279 handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
1280 }
1281
1282 uploadComplete.new_asset = inventoryItemID;
1283 uploadComplete.compiled = errors.Count > 0 ? false : true;
1284 uploadComplete.state = "complete";
1285 uploadComplete.errors = new OSDArray();
1286 uploadComplete.errors.Array = errors;
1287
1288 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1289
1290 httpListener.RemoveStreamHandler("POST", uploaderPath);
1291
1292 if (m_dumpAssetToFile)
1293 {
1294 SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1295 }
1296
1297// m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
1298
1299 return res;
1300 }
1301 catch (Exception e)
1302 {
1303 m_log.Error("[CAPS]: " + e.ToString());
1304 }
1305
1306 // XXX Maybe this should be some meaningful error packet
1307 return null;
1308 }
1309 ///Left this in and commented in case there are unforseen issues
1310 //private void SaveAssetToFile(string filename, byte[] data)
1311 //{
1312 // FileStream fs = File.Create(filename);
1313 // BinaryWriter bw = new BinaryWriter(fs);
1314 // bw.Write(data);
1315 // bw.Close();
1316 // fs.Close();
1317 //}
1318 private static void SaveAssetToFile(string filename, byte[] data)
1319 {
1320 string assetPath = "UserAssets";
1321 if (!Directory.Exists(assetPath))
1322 {
1323 Directory.CreateDirectory(assetPath);
1324 }
1325 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1326 BinaryWriter bw = new BinaryWriter(fs);
1327 bw.Write(data);
1328 bw.Close();
1329 fs.Close();
1330 }
1331 }
1332
1333 public class BakedTextureUploader
1334 {
1335 public event UploadedBakedTexture OnUpLoad;
1336 private UploadedBakedTexture handlerUpLoad = null;
1337
1338 private string uploaderPath = String.Empty;
1339 private UUID newAssetID;
1340 private IHttpServer httpListener;
1341
1342 public BakedTextureUploader(string path, IHttpServer httpServer)
1343 {
1344 newAssetID = UUID.Random();
1345 uploaderPath = path;
1346 httpListener = httpServer;
1347// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
1348 }
1349
1350 /// <summary>
1351 ///
1352 /// </summary>
1353 /// <param name="data"></param>
1354 /// <param name="path"></param>
1355 /// <param name="param"></param>
1356 /// <returns></returns>
1357 public string uploaderCaps(byte[] data, string path, string param)
1358 {
1359 handlerUpLoad = OnUpLoad;
1360 if (handlerUpLoad != null)
1361 {
1362 Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
1363 }
1364
1365 string res = String.Empty;
1366 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1367 uploadComplete.new_asset = newAssetID.ToString();
1368 uploadComplete.new_inventory_item = UUID.Zero;
1369 uploadComplete.state = "complete";
1370
1371 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1372
1373 httpListener.RemoveStreamHandler("POST", uploaderPath);
1374
1375// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
1376
1377 return res;
1378 }
1379 }
1380 } 171 }
1381} 172}