aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs1213
-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/UDP/IncomingPacket.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs)0
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs (renamed from OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs)0
26 files changed, 3728 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..7945d5e
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -0,0 +1,1213 @@
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 private object m_fetchLock = new Object();
85
86 public BunchOfCaps(Scene scene, Caps caps)
87 {
88 m_Scene = scene;
89 m_HostCapsObj = caps;
90 IConfigSource config = m_Scene.Config;
91 if (config != null)
92 {
93 IConfig sconfig = config.Configs["Startup"];
94 if (sconfig != null)
95 m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
96 }
97
98 m_assetService = m_Scene.AssetService;
99 m_regionName = m_Scene.RegionInfo.RegionName;
100
101 RegisterHandlers();
102
103 AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
104 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
105 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
106 CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
107 GetClient = m_Scene.SceneContents.GetControllingClient;
108
109 }
110
111 /// <summary>
112 /// Register a bunch of CAPS http service handlers
113 /// </summary>
114 public void RegisterHandlers()
115 {
116 m_HostCapsObj.DeregisterHandlers();
117
118 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
119
120 RegisterRegionServiceHandlers(capsBase);
121 RegisterInventoryServiceHandlers(capsBase);
122 }
123
124 public void RegisterRegionServiceHandlers(string capsBase)
125 {
126 try
127 {
128 // the root of all evil
129 m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
130 m_log.DebugFormat(
131 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
132
133 //m_capsHandlers["MapLayer"] =
134 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
135 // capsBase + m_mapLayerPath,
136 // GetMapLayer);
137 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
138 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
139 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
140 m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture));
141
142 }
143 catch (Exception e)
144 {
145 m_log.Error("[CAPS]: " + e.ToString());
146 }
147 }
148
149 public void RegisterInventoryServiceHandlers(string capsBase)
150 {
151 try
152 {
153 // I don't think this one works...
154 m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
155 capsBase + m_newInventory,
156 NewAgentInventoryRequest));
157 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
158 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
159 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
160 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
161
162 // As of RC 1.22.9 of the Linden client this is
163 // supported
164
165 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
166
167 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
168 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
169 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
170 // but when I went on the Linden grid, the
171 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
172 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
173 //
174 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
175 // we will be
176 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
177 // m_capsHandlers["FetchInventoryDescendents"] =
178 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
179
180 // m_capsHandlers["FetchInventoryDescendents"] =
181 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
182 // capsBase + m_fetchInventory,
183 // FetchInventory));
184 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
185 // capsBase + m_requestTexture,
186 // RequestTexture);
187 }
188 catch (Exception e)
189 {
190 m_log.Error("[CAPS]: " + e.ToString());
191 }
192 }
193
194 /// <summary>
195 /// Construct a client response detailing all the capabilities this server can provide.
196 /// </summary>
197 /// <param name="request"></param>
198 /// <param name="path"></param>
199 /// <param name="param"></param>
200 /// <param name="httpRequest">HTTP request header object</param>
201 /// <param name="httpResponse">HTTP response header object</param>
202 /// <returns></returns>
203 public string SeedCapRequest(string request, string path, string param,
204 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
205 {
206 m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
207
208 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
209 {
210 m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
211 return string.Empty;
212 }
213
214 // WARNING: Add the external too
215 string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.CapsHandlers.CapsDetails);
216
217 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
218
219 return result;
220 }
221
222 /// <summary>
223 /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
224 /// </summary>
225 /// <param name="request"></param>
226 /// <param name="path"></param>
227 /// <param name="param"></param>
228 /// <param name="httpRequest">HTTP request header object</param>
229 /// <param name="httpResponse">HTTP response header object</param>
230 /// <returns></returns>
231 public string ScriptTaskInventory(string request, string path, string param,
232 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
233 {
234 try
235 {
236 m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
237 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
238
239 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
240 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
241 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
242
243 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
244 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
245
246 TaskInventoryScriptUpdater uploader =
247 new TaskInventoryScriptUpdater(
248 llsdUpdateRequest.item_id,
249 llsdUpdateRequest.task_id,
250 llsdUpdateRequest.is_script_running,
251 capsBase + uploaderPath,
252 m_HostCapsObj.HttpListener,
253 m_dumpAssetsToFile);
254 uploader.OnUpLoad += TaskScriptUpdated;
255
256 m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
257
258 string protocol = "http://";
259
260 if (m_HostCapsObj.SSLCaps)
261 protocol = "https://";
262
263 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
264 uploaderPath;
265
266 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
267 uploadResponse.uploader = uploaderURL;
268 uploadResponse.state = "upload";
269
270 // m_log.InfoFormat("[CAPS]: " +
271 // "ScriptTaskInventory response: {0}",
272 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
273
274 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
275 }
276 catch (Exception e)
277 {
278 m_log.Error("[CAPS]: " + e.ToString());
279 }
280
281 return null;
282 }
283
284 /// <summary>
285 /// Called when new asset data for an agent inventory item update has been uploaded.
286 /// </summary>
287 /// <param name="itemID">Item to update</param>
288 /// <param name="primID">Prim containing item to update</param>
289 /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
290 /// <param name="data">New asset data</param>
291 public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
292 {
293 if (TaskScriptUpdatedCall != null)
294 {
295 ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data);
296 foreach (Object item in e)
297 errors.Add(item);
298 }
299 }
300
301 public string UploadBakedTexture(string request, string path,
302 string param, OSHttpRequest httpRequest,
303 OSHttpResponse httpResponse)
304 {
305 try
306 {
307 // m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " +
308 // m_regionName);
309
310 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
311 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
312
313 BakedTextureUploader uploader =
314 new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
315 uploader.OnUpLoad += BakedTextureUploaded;
316
317 m_HostCapsObj.HttpListener.AddStreamHandler(
318 new BinaryStreamHandler("POST", capsBase + uploaderPath,
319 uploader.uploaderCaps));
320
321 string protocol = "http://";
322
323 if (m_HostCapsObj.SSLCaps)
324 protocol = "https://";
325
326 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
327 m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
328
329 LLSDAssetUploadResponse uploadResponse =
330 new LLSDAssetUploadResponse();
331 uploadResponse.uploader = uploaderURL;
332 uploadResponse.state = "upload";
333
334 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
335 }
336 catch (Exception e)
337 {
338 m_log.Error("[CAPS]: " + e.ToString());
339 }
340
341 return null;
342 }
343
344 public void BakedTextureUploaded(UUID assetID, byte[] data)
345 {
346 // m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
347
348 AssetBase asset;
349 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
350 asset.Data = data;
351 asset.Temporary = true;
352 asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
353 m_assetService.Store(asset);
354 }
355
356 /// <summary>
357 /// Called when new asset data for an agent inventory item update has been uploaded.
358 /// </summary>
359 /// <param name="itemID">Item to update</param>
360 /// <param name="data">New asset data</param>
361 /// <returns></returns>
362 public UUID ItemUpdated(UUID itemID, byte[] data)
363 {
364 if (ItemUpdatedCall != null)
365 {
366 return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data);
367 }
368
369 return UUID.Zero;
370 }
371
372 /// <summary>
373 ///
374 /// </summary>
375 /// <param name="llsdRequest"></param>
376 /// <returns></returns>
377 public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
378 {
379 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
380 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
381
382 if (llsdRequest.asset_type == "texture" ||
383 llsdRequest.asset_type == "animation" ||
384 llsdRequest.asset_type == "sound")
385 {
386 IClientAPI client = null;
387 IScene scene = null;
388 if (GetClient != null)
389 {
390 client = GetClient(m_HostCapsObj.AgentID);
391 scene = client.Scene;
392
393 IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
394
395 if (mm != null)
396 {
397 if (!mm.UploadCovered(client, mm.UploadCharge))
398 {
399 if (client != null)
400 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
401
402 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
403 errorResponse.uploader = "";
404 errorResponse.state = "error";
405 return errorResponse;
406 }
407 }
408 }
409 }
410
411 string assetName = llsdRequest.name;
412 string assetDes = llsdRequest.description;
413 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
414 UUID newAsset = UUID.Random();
415 UUID newInvItem = UUID.Random();
416 UUID parentFolder = llsdRequest.folder_id;
417 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
418
419 AssetUploader uploader =
420 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
421 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
422 m_HostCapsObj.HttpListener.AddStreamHandler(
423 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
424
425 string protocol = "http://";
426
427 if (m_HostCapsObj.SSLCaps)
428 protocol = "https://";
429
430 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
431 uploaderPath;
432
433 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
434 uploadResponse.uploader = uploaderURL;
435 uploadResponse.state = "upload";
436 uploader.OnUpLoad += UploadCompleteHandler;
437 return uploadResponse;
438 }
439
440 /// <summary>
441 ///
442 /// </summary>
443 /// <param name="assetID"></param>
444 /// <param name="inventoryItem"></param>
445 /// <param name="data"></param>
446 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
447 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
448 string assetType)
449 {
450 sbyte assType = 0;
451 sbyte inType = 0;
452
453 if (inventoryType == "sound")
454 {
455 inType = 1;
456 assType = 1;
457 }
458 else if (inventoryType == "animation")
459 {
460 inType = 19;
461 assType = 20;
462 }
463 else if (inventoryType == "wearable")
464 {
465 inType = 18;
466 switch (assetType)
467 {
468 case "bodypart":
469 assType = 13;
470 break;
471 case "clothing":
472 assType = 5;
473 break;
474 }
475 }
476
477 AssetBase asset;
478 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString());
479 asset.Data = data;
480 if (AddNewAsset != null)
481 AddNewAsset(asset);
482 else if (m_assetService != null)
483 m_assetService.Store(asset);
484
485 InventoryItemBase item = new InventoryItemBase();
486 item.Owner = m_HostCapsObj.AgentID;
487 item.CreatorId = m_HostCapsObj.AgentID.ToString();
488 item.CreatorData = String.Empty;
489 item.ID = inventoryItem;
490 item.AssetID = asset.FullID;
491 item.Description = assetDescription;
492 item.Name = assetName;
493 item.AssetType = assType;
494 item.InvType = inType;
495 item.Folder = parentFolder;
496 item.CurrentPermissions = (uint)PermissionMask.All;
497 item.BasePermissions = (uint)PermissionMask.All;
498 item.EveryOnePermissions = 0;
499 item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
500 item.CreationDate = Util.UnixTimeSinceEpoch();
501
502 if (AddNewInventoryItem != null)
503 {
504 AddNewInventoryItem(m_HostCapsObj.AgentID, item);
505 }
506 }
507
508 /// <summary>
509 /// Processes a fetch inventory request and sends the reply
510
511 /// </summary>
512 /// <param name="request"></param>
513 /// <param name="path"></param>
514 /// <param name="param"></param>
515 /// <returns></returns>
516 // Request is like:
517 //<llsd>
518 // <map><key>folders</key>
519 // <array>
520 // <map>
521 // <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>
522 // </map>
523 // </array>
524 // </map>
525 //</llsd>
526 //
527 // multiple fetch-folder maps are allowed within the larger folders map.
528 public string FetchInventoryRequest(string request, string path, string param)
529 {
530 // string unmodifiedRequest = request.ToString();
531
532 //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest);
533 m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName);
534
535 Hashtable hash = new Hashtable();
536 try
537 {
538 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
539 }
540 catch (LLSD.LLSDParseException pe)
541 {
542 m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
543 m_log.Error("Request: " + request.ToString());
544 }
545
546 ArrayList foldersrequested = (ArrayList)hash["folders"];
547
548 string response = "";
549
550 for (int i = 0; i < foldersrequested.Count; i++)
551 {
552 string inventoryitemstr = "";
553 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
554
555 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
556 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
557 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
558
559 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
560 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
561 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
562
563 response += inventoryitemstr;
564 }
565
566 if (response.Length == 0)
567 {
568 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
569 // Therefore, I'm concluding that the client only has so many threads available to do requests
570 // and when a thread stalls.. is stays stalled.
571 // Therefore we need to return something valid
572 response = "<llsd><map><key>folders</key><array /></map></llsd>";
573 }
574 else
575 {
576 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
577 }
578
579 //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml");
580 //m_log.Debug(Util.GetFormattedXml(response));
581
582 return response;
583 }
584
585 public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
586 {
587 // nasty temporary hack here, the linden client falsely
588 // identifies the uuid 00000000-0000-0000-0000-000000000000
589 // as a string which breaks us
590 //
591 // correctly mark it as a uuid
592 //
593 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
594
595 // another hack <integer>1</integer> results in a
596 // System.ArgumentException: Object type System.Int32 cannot
597 // be converted to target type: System.Boolean
598 //
599 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
600 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
601
602 Hashtable hash = new Hashtable();
603 try
604 {
605 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
606 }
607 catch (LLSD.LLSDParseException pe)
608 {
609 m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
610 m_log.Error("Request: " + request.ToString());
611 }
612
613 ArrayList foldersrequested = (ArrayList)hash["folders"];
614
615 string response = "";
616 lock (m_fetchLock)
617 {
618 for (int i = 0; i < foldersrequested.Count; i++)
619 {
620 string inventoryitemstr = "";
621 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
622
623 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
624
625 try
626 {
627 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
628 }
629 catch (Exception e)
630 {
631 m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e);
632 }
633 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
634
635 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
636 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
637 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
638
639 response += inventoryitemstr;
640 }
641
642
643 if (response.Length == 0)
644 {
645 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
646 // Therefore, I'm concluding that the client only has so many threads available to do requests
647 // and when a thread stalls.. is stays stalled.
648 // Therefore we need to return something valid
649 response = "<llsd><map><key>folders</key><array /></map></llsd>";
650 }
651 else
652 {
653 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
654 }
655
656 //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
657 //m_log.Debug("[CAPS] "+response);
658
659 }
660 return response;
661 }
662
663
664
665 /// <summary>
666 /// Construct an LLSD reply packet to a CAPS inventory request
667 /// </summary>
668 /// <param name="invFetch"></param>
669 /// <returns></returns>
670 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
671 {
672 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
673 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
674 contents.agent_id = m_HostCapsObj.AgentID;
675 contents.owner_id = invFetch.owner_id;
676 contents.folder_id = invFetch.folder_id;
677
678 reply.folders.Array.Add(contents);
679 InventoryCollection inv = new InventoryCollection();
680 inv.Folders = new List<InventoryFolderBase>();
681 inv.Items = new List<InventoryItemBase>();
682 int version = 0;
683 if (CAPSFetchInventoryDescendents != null)
684 {
685 inv = CAPSFetchInventoryDescendents(m_HostCapsObj.AgentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
686 }
687
688 if (inv.Folders != null)
689 {
690 foreach (InventoryFolderBase invFolder in inv.Folders)
691 {
692 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
693 }
694 }
695
696 if (inv.Items != null)
697 {
698 foreach (InventoryItemBase invItem in inv.Items)
699 {
700 contents.items.Array.Add(ConvertInventoryItem(invItem));
701 }
702 }
703
704 contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
705 contents.version = version;
706
707 return reply;
708 }
709
710 /// <summary>
711 /// Convert an internal inventory folder object into an LLSD object.
712 /// </summary>
713 /// <param name="invFolder"></param>
714 /// <returns></returns>
715 private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
716 {
717 LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
718 llsdFolder.folder_id = invFolder.ID;
719 llsdFolder.parent_id = invFolder.ParentID;
720 llsdFolder.name = invFolder.Name;
721 if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length)
722 llsdFolder.type = "-1";
723 else
724 llsdFolder.type = TaskInventoryItem.Types[invFolder.Type];
725 llsdFolder.preferred_type = "-1";
726
727 return llsdFolder;
728 }
729
730 /// <summary>
731 /// Convert an internal inventory item object into an LLSD object.
732 /// </summary>
733 /// <param name="invItem"></param>
734 /// <returns></returns>
735 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
736 {
737 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
738 llsdItem.asset_id = invItem.AssetID;
739 llsdItem.created_at = invItem.CreationDate;
740 llsdItem.desc = invItem.Description;
741 llsdItem.flags = (int)invItem.Flags;
742 llsdItem.item_id = invItem.ID;
743 llsdItem.name = invItem.Name;
744 llsdItem.parent_id = invItem.Folder;
745 try
746 {
747 // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions.
748 llsdItem.type = TaskInventoryItem.Types[invItem.AssetType];
749 llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType];
750 }
751 catch (Exception e)
752 {
753 m_log.Error("[CAPS]: Problem setting asset/inventory type while converting inventory item " + invItem.Name + " to LLSD:", e);
754 }
755 llsdItem.permissions = new LLSDPermissions();
756 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
757 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
758 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
759 llsdItem.permissions.group_id = invItem.GroupID;
760 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
761 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
762 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
763 llsdItem.permissions.owner_id = m_HostCapsObj.AgentID;
764 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
765 llsdItem.sale_info = new LLSDSaleInfo();
766 llsdItem.sale_info.sale_price = invItem.SalePrice;
767 switch (invItem.SaleType)
768 {
769 default:
770 llsdItem.sale_info.sale_type = "not";
771 break;
772 case 1:
773 llsdItem.sale_info.sale_type = "original";
774 break;
775 case 2:
776 llsdItem.sale_info.sale_type = "copy";
777 break;
778 case 3:
779 llsdItem.sale_info.sale_type = "contents";
780 break;
781 }
782
783 return llsdItem;
784 }
785
786 /// <summary>
787 ///
788 /// </summary>
789 /// <param name="mapReq"></param>
790 /// <returns></returns>
791 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
792 {
793 m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName);
794 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
795 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
796 return mapResponse;
797 }
798
799 /// <summary>
800 ///
801 /// </summary>
802 /// <returns></returns>
803 protected static OSDMapLayer GetOSDMapLayerResponse()
804 {
805 OSDMapLayer mapLayer = new OSDMapLayer();
806 mapLayer.Right = 5000;
807 mapLayer.Top = 5000;
808 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
809
810 return mapLayer;
811 }
812
813 /// <summary>
814 ///
815 /// </summary>
816 /// <param name="request"></param>
817 /// <param name="path"></param>
818 /// <param name="param"></param>
819 /// <returns></returns>
820 public string RequestTexture(string request, string path, string param)
821 {
822 m_log.Debug("texture request " + request);
823 // Needs implementing (added to remove compiler warning)
824 return String.Empty;
825 }
826
827
828 /// <summary>
829 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
830 /// </summary>
831 /// <param name="request"></param>
832 /// <param name="path"></param>
833 /// <param name="param"></param>
834 /// <returns></returns>
835 public string NoteCardAgentInventory(string request, string path, string param,
836 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
837 {
838 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request);
839 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request);
840
841 //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request));
842 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
843 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
844 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
845
846 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
847 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
848
849 ItemUpdater uploader =
850 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
851 uploader.OnUpLoad += ItemUpdated;
852
853 m_HostCapsObj.HttpListener.AddStreamHandler(
854 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
855
856 string protocol = "http://";
857
858 if (m_HostCapsObj.SSLCaps)
859 protocol = "https://";
860
861 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
862 uploaderPath;
863
864 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
865 uploadResponse.uploader = uploaderURL;
866 uploadResponse.state = "upload";
867
868 // m_log.InfoFormat("[CAPS]: " +
869 // "NoteCardAgentInventory response: {0}",
870 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
871
872 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
873 }
874 }
875
876 public class AssetUploader
877 {
878 public event UpLoadedAsset OnUpLoad;
879 private UpLoadedAsset handlerUpLoad = null;
880
881 private string uploaderPath = String.Empty;
882 private UUID newAssetID;
883 private UUID inventoryItemID;
884 private UUID parentFolder;
885 private IHttpServer httpListener;
886 private bool m_dumpAssetsToFile;
887 private string m_assetName = String.Empty;
888 private string m_assetDes = String.Empty;
889
890 private string m_invType = String.Empty;
891 private string m_assetType = String.Empty;
892
893 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
894 UUID parentFolderID, string invType, string assetType, string path,
895 IHttpServer httpServer, bool dumpAssetsToFile)
896 {
897 m_assetName = assetName;
898 m_assetDes = description;
899 newAssetID = assetID;
900 inventoryItemID = inventoryItem;
901 uploaderPath = path;
902 httpListener = httpServer;
903 parentFolder = parentFolderID;
904 m_assetType = assetType;
905 m_invType = invType;
906 m_dumpAssetsToFile = dumpAssetsToFile;
907 }
908
909 /// <summary>
910 ///
911 /// </summary>
912 /// <param name="data"></param>
913 /// <param name="path"></param>
914 /// <param name="param"></param>
915 /// <returns></returns>
916 public string uploaderCaps(byte[] data, string path, string param)
917 {
918 UUID inv = inventoryItemID;
919 string res = String.Empty;
920 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
921 uploadComplete.new_asset = newAssetID.ToString();
922 uploadComplete.new_inventory_item = inv;
923 uploadComplete.state = "complete";
924
925 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
926
927 httpListener.RemoveStreamHandler("POST", uploaderPath);
928
929 // TODO: probably make this a better set of extensions here
930 string extension = ".jp2";
931 if (m_invType != "image")
932 {
933 extension = ".dat";
934 }
935
936 if (m_dumpAssetsToFile)
937 {
938 SaveAssetToFile(m_assetName + extension, data);
939 }
940 handlerUpLoad = OnUpLoad;
941 if (handlerUpLoad != null)
942 {
943 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
944 }
945
946 return res;
947 }
948 ///Left this in and commented in case there are unforseen issues
949 //private void SaveAssetToFile(string filename, byte[] data)
950 //{
951 // FileStream fs = File.Create(filename);
952 // BinaryWriter bw = new BinaryWriter(fs);
953 // bw.Write(data);
954 // bw.Close();
955 // fs.Close();
956 //}
957 private static void SaveAssetToFile(string filename, byte[] data)
958 {
959 string assetPath = "UserAssets";
960 if (!Directory.Exists(assetPath))
961 {
962 Directory.CreateDirectory(assetPath);
963 }
964 FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
965 BinaryWriter bw = new BinaryWriter(fs);
966 bw.Write(data);
967 bw.Close();
968 fs.Close();
969 }
970 }
971
972 /// <summary>
973 /// This class is a callback invoked when a client sends asset data to
974 /// an agent inventory notecard update url
975 /// </summary>
976 public class ItemUpdater
977 {
978 public event UpdateItem OnUpLoad;
979
980 private UpdateItem handlerUpdateItem = null;
981
982 private string uploaderPath = String.Empty;
983 private UUID inventoryItemID;
984 private IHttpServer httpListener;
985 private bool m_dumpAssetToFile;
986
987 public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile)
988 {
989 m_dumpAssetToFile = dumpAssetToFile;
990
991 inventoryItemID = inventoryItem;
992 uploaderPath = path;
993 httpListener = httpServer;
994 }
995
996 /// <summary>
997 ///
998 /// </summary>
999 /// <param name="data"></param>
1000 /// <param name="path"></param>
1001 /// <param name="param"></param>
1002 /// <returns></returns>
1003 public string uploaderCaps(byte[] data, string path, string param)
1004 {
1005 UUID inv = inventoryItemID;
1006 string res = String.Empty;
1007 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1008 UUID assetID = UUID.Zero;
1009 handlerUpdateItem = OnUpLoad;
1010 if (handlerUpdateItem != null)
1011 {
1012 assetID = handlerUpdateItem(inv, data);
1013 }
1014
1015 uploadComplete.new_asset = assetID.ToString();
1016 uploadComplete.new_inventory_item = inv;
1017 uploadComplete.state = "complete";
1018
1019 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1020
1021 httpListener.RemoveStreamHandler("POST", uploaderPath);
1022
1023 if (m_dumpAssetToFile)
1024 {
1025 SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1026 }
1027
1028 return res;
1029 }
1030 ///Left this in and commented in case there are unforseen issues
1031 //private void SaveAssetToFile(string filename, byte[] data)
1032 //{
1033 // FileStream fs = File.Create(filename);
1034 // BinaryWriter bw = new BinaryWriter(fs);
1035 // bw.Write(data);
1036 // bw.Close();
1037 // fs.Close();
1038 //}
1039 private static void SaveAssetToFile(string filename, byte[] data)
1040 {
1041 string assetPath = "UserAssets";
1042 if (!Directory.Exists(assetPath))
1043 {
1044 Directory.CreateDirectory(assetPath);
1045 }
1046 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1047 BinaryWriter bw = new BinaryWriter(fs);
1048 bw.Write(data);
1049 bw.Close();
1050 fs.Close();
1051 }
1052 }
1053
1054 /// <summary>
1055 /// This class is a callback invoked when a client sends asset data to
1056 /// a task inventory script update url
1057 /// </summary>
1058 public class TaskInventoryScriptUpdater
1059 {
1060 private static readonly ILog m_log =
1061 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1062
1063 public event UpdateTaskScript OnUpLoad;
1064
1065 private UpdateTaskScript handlerUpdateTaskScript = null;
1066
1067 private string uploaderPath = String.Empty;
1068 private UUID inventoryItemID;
1069 private UUID primID;
1070 private bool isScriptRunning;
1071 private IHttpServer httpListener;
1072 private bool m_dumpAssetToFile;
1073
1074 public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning,
1075 string path, IHttpServer httpServer, bool dumpAssetToFile)
1076 {
1077 m_dumpAssetToFile = dumpAssetToFile;
1078
1079 this.inventoryItemID = inventoryItemID;
1080 this.primID = primID;
1081
1082 // This comes in over the packet as an integer, but actually appears to be treated as a bool
1083 this.isScriptRunning = (0 == isScriptRunning ? false : true);
1084
1085 uploaderPath = path;
1086 httpListener = httpServer;
1087 }
1088
1089 /// <summary>
1090 ///
1091 /// </summary>
1092 /// <param name="data"></param>
1093 /// <param name="path"></param>
1094 /// <param name="param"></param>
1095 /// <returns></returns>
1096 public string uploaderCaps(byte[] data, string path, string param)
1097 {
1098 try
1099 {
1100 // m_log.InfoFormat("[CAPS]: " +
1101 // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
1102 // data, path, param));
1103
1104 string res = String.Empty;
1105 LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
1106
1107 ArrayList errors = new ArrayList();
1108 handlerUpdateTaskScript = OnUpLoad;
1109 if (handlerUpdateTaskScript != null)
1110 {
1111 handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
1112 }
1113
1114 uploadComplete.new_asset = inventoryItemID;
1115 uploadComplete.compiled = errors.Count > 0 ? false : true;
1116 uploadComplete.state = "complete";
1117 uploadComplete.errors = new OSDArray();
1118 uploadComplete.errors.Array = errors;
1119
1120 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1121
1122 httpListener.RemoveStreamHandler("POST", uploaderPath);
1123
1124 if (m_dumpAssetToFile)
1125 {
1126 SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1127 }
1128
1129 // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
1130
1131 return res;
1132 }
1133 catch (Exception e)
1134 {
1135 m_log.Error("[CAPS]: " + e.ToString());
1136 }
1137
1138 // XXX Maybe this should be some meaningful error packet
1139 return null;
1140 }
1141 ///Left this in and commented in case there are unforseen issues
1142 //private void SaveAssetToFile(string filename, byte[] data)
1143 //{
1144 // FileStream fs = File.Create(filename);
1145 // BinaryWriter bw = new BinaryWriter(fs);
1146 // bw.Write(data);
1147 // bw.Close();
1148 // fs.Close();
1149 //}
1150 private static void SaveAssetToFile(string filename, byte[] data)
1151 {
1152 string assetPath = "UserAssets";
1153 if (!Directory.Exists(assetPath))
1154 {
1155 Directory.CreateDirectory(assetPath);
1156 }
1157 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1158 BinaryWriter bw = new BinaryWriter(fs);
1159 bw.Write(data);
1160 bw.Close();
1161 fs.Close();
1162 }
1163 }
1164
1165 public class BakedTextureUploader
1166 {
1167 public event UploadedBakedTexture OnUpLoad;
1168 private UploadedBakedTexture handlerUpLoad = null;
1169
1170 private string uploaderPath = String.Empty;
1171 private UUID newAssetID;
1172 private IHttpServer httpListener;
1173
1174 public BakedTextureUploader(string path, IHttpServer httpServer)
1175 {
1176 newAssetID = UUID.Random();
1177 uploaderPath = path;
1178 httpListener = httpServer;
1179 // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
1180 }
1181
1182 /// <summary>
1183 ///
1184 /// </summary>
1185 /// <param name="data"></param>
1186 /// <param name="path"></param>
1187 /// <param name="param"></param>
1188 /// <returns></returns>
1189 public string uploaderCaps(byte[] data, string path, string param)
1190 {
1191 handlerUpLoad = OnUpLoad;
1192 if (handlerUpLoad != null)
1193 {
1194 Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
1195 }
1196
1197 string res = String.Empty;
1198 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1199 uploadComplete.new_asset = newAssetID.ToString();
1200 uploadComplete.new_inventory_item = UUID.Zero;
1201 uploadComplete.state = "complete";
1202
1203 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1204
1205 httpListener.RemoveStreamHandler("POST", uploaderPath);
1206
1207 // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
1208
1209 return res;
1210 }
1211 }
1212
1213}
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..4a8bb53
--- /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/LindenUDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
index 90b3ede..90b3ede 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs
index 1f73a1d..1f73a1d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/IncomingPacketHistoryCollection.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacketHistoryCollection.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index e9e2dca..e9e2dca 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 43903ce..43903ce 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
index 9e0db12..9e0db12 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ca5501d..ca5501d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index aff90c5..aff90c5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6eebd9d..6eebd9d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs
index 76c6c14..76c6c14 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OutgoingPacket.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index daab84f..daab84f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
index 34c21aa..34c21aa 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/Tests/MockScene.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs
index 7d0757f..7d0757f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/Tests/PacketHandlerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/PacketHandlerTests.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs
index e995d65..e995d65 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLPacketServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLPacketServer.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
index f98586d..f98586d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/Tests/TestLLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
index c9aac0b..c9aac0b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/ThrottleRates.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 29fd1a4..29fd1a4 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
index 793aefe..793aefe 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs