aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs269
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs29
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs223
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs296
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs204
7 files changed, 636 insertions, 402 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 185f9ce..580c005 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Timers;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.IO; 32using System.IO;
@@ -60,7 +61,7 @@ namespace OpenSim.Region.ClientStack.Linden
60 61
61 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); 62 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
62 63
63 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); 64 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
64 65
65 public delegate void NewAsset(AssetBase asset); 66 public delegate void NewAsset(AssetBase asset);
66 67
@@ -96,7 +97,10 @@ namespace OpenSim.Region.ClientStack.Linden
96 // private static readonly string m_fetchInventoryPath = "0006/"; 97 // private static readonly string m_fetchInventoryPath = "0006/";
97 private static readonly string m_copyFromNotecardPath = "0007/"; 98 private static readonly string m_copyFromNotecardPath = "0007/";
98 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 99 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
99 100 private static readonly string m_getObjectPhysicsDataPath = "0101/";
101 private static readonly string m_getObjectCostPath = "0102/";
102 private static readonly string m_ResourceCostSelectedPath = "0103/";
103
100 104
101 // These are callbacks which will be setup by the scene so that we can update scene data when we 105 // These are callbacks which will be setup by the scene so that we can update scene data when we
102 // receive capability calls 106 // receive capability calls
@@ -204,6 +208,14 @@ namespace OpenSim.Region.ClientStack.Linden
204 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 208 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
205 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 209 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
206 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 210 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
211 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
212 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
213 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
214 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
215 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
216 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
217
218
207 219
208 m_HostCapsObj.RegisterHandler( 220 m_HostCapsObj.RegisterHandler(
209 "CopyInventoryFromNotecard", 221 "CopyInventoryFromNotecard",
@@ -375,6 +387,37 @@ namespace OpenSim.Region.ClientStack.Linden
375 return UUID.Zero; 387 return UUID.Zero;
376 } 388 }
377 389
390 private delegate void UploadWithCostCompleteDelegate(string assetName,
391 string assetDescription, UUID assetID, UUID inventoryItem,
392 UUID parentFolder, byte[] data, string inventoryType,
393 string assetType, uint cost);
394
395 private class AssetUploaderWithCost : AssetUploader
396 {
397 private uint m_cost;
398
399 public event UploadWithCostCompleteDelegate OnUpLoad;
400
401 public AssetUploaderWithCost(string assetName, string description, UUID assetID,
402 UUID inventoryItem, UUID parentFolderID, string invType, string assetType,
403 string path, IHttpServer httpServer, bool dumpAssetsToFile, uint cost) :
404 base(assetName, description, assetID, inventoryItem, parentFolderID,
405 invType, assetType, path, httpServer, dumpAssetsToFile)
406 {
407 m_cost = cost;
408
409 base.OnUpLoad += UploadCompleteHandler;
410 }
411
412 private void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
413 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
414 string assetType)
415 {
416 OnUpLoad(assetName, assetDescription, assetID, inventoryItem, parentFolder,
417 data, inventoryType, assetType, m_cost);
418 }
419 }
420
378 /// <summary> 421 /// <summary>
379 /// 422 ///
380 /// </summary> 423 /// </summary>
@@ -385,8 +428,11 @@ namespace OpenSim.Region.ClientStack.Linden
385 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); 428 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
386 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); 429 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
387 430
431 uint cost = 0;
432
388 if (llsdRequest.asset_type == "texture" || 433 if (llsdRequest.asset_type == "texture" ||
389 llsdRequest.asset_type == "animation" || 434 llsdRequest.asset_type == "animation" ||
435 llsdRequest.asset_type == "mesh" ||
390 llsdRequest.asset_type == "sound") 436 llsdRequest.asset_type == "sound")
391 { 437 {
392 ScenePresence avatar = null; 438 ScenePresence avatar = null;
@@ -417,7 +463,33 @@ namespace OpenSim.Region.ClientStack.Linden
417 463
418 if (mm != null) 464 if (mm != null)
419 { 465 {
420 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) 466 // XPTO: The cost should be calculated about here
467
468 if (llsdRequest.asset_type == "mesh")
469 {
470 cost += 20; // Constant for now to test showing a price
471
472 if (llsdRequest.asset_resources == null)
473 {
474 client.SendAgentAlertMessage("Unable to upload asset. missing information.", false);
475
476 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
477 errorResponse.uploader = "";
478 errorResponse.state = "error";
479 return errorResponse;
480 }
481
482 uint textures_cost = (uint)llsdRequest.asset_resources.texture_list.Array.Count;
483 textures_cost *= (uint)mm.UploadCharge;
484
485 cost += textures_cost;
486 }
487 else
488 {
489 cost = (uint)mm.UploadCharge;
490 }
491
492 if (!mm.UploadCovered(client.AgentId, (int)cost))
421 { 493 {
422 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 494 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
423 495
@@ -438,9 +510,9 @@ namespace OpenSim.Region.ClientStack.Linden
438 UUID parentFolder = llsdRequest.folder_id; 510 UUID parentFolder = llsdRequest.folder_id;
439 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 511 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
440 512
441 AssetUploader uploader = 513 AssetUploaderWithCost uploader =
442 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 514 new AssetUploaderWithCost(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
443 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 515 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost);
444 516
445 m_HostCapsObj.HttpListener.AddStreamHandler( 517 m_HostCapsObj.HttpListener.AddStreamHandler(
446 new BinaryStreamHandler( 518 new BinaryStreamHandler(
@@ -458,11 +530,31 @@ namespace OpenSim.Region.ClientStack.Linden
458 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 530 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
459 uploaderPath; 531 uploaderPath;
460 532
533
461 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 534 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
462 uploadResponse.uploader = uploaderURL; 535 uploadResponse.uploader = uploaderURL;
463 uploadResponse.state = "upload"; 536 uploadResponse.state = "upload";
537 uploadResponse.upload_price = (int)cost;
538
539 // use fake values for now
540 if (llsdRequest.asset_type == "mesh")
541 {
542 uploadResponse.data = new LLSDAssetUploadResponseData();
543 uploadResponse.data.model_streaming_cost = 1.0;
544 uploadResponse.data.simulation_cost = 1.5;
545
546 uploadResponse.data.physics_cost = 2.0;
547 uploadResponse.data.resource_cost = 3.0;
548 uploadResponse.data.upload_price_breakdown.mesh_instance = 1;
549 uploadResponse.data.upload_price_breakdown.mesh_physics = 2;
550 uploadResponse.data.upload_price_breakdown.mesh_streaming = 3;
551 uploadResponse.data.upload_price_breakdown.texture = 5;
552 uploadResponse.data.upload_price_breakdown.model = 4;
553 }
554
464 uploader.OnUpLoad += UploadCompleteHandler; 555 uploader.OnUpLoad += UploadCompleteHandler;
465 return uploadResponse; 556 return uploadResponse;
557
466 } 558 }
467 559
468 /// <summary> 560 /// <summary>
@@ -473,7 +565,7 @@ namespace OpenSim.Region.ClientStack.Linden
473 /// <param name="data"></param> 565 /// <param name="data"></param>
474 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 566 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
475 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 567 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
476 string assetType) 568 string assetType, uint cost)
477 { 569 {
478 m_log.DebugFormat( 570 m_log.DebugFormat(
479 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}", 571 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
@@ -692,7 +784,7 @@ namespace OpenSim.Region.ClientStack.Linden
692 784
693 if (AddNewInventoryItem != null) 785 if (AddNewInventoryItem != null)
694 { 786 {
695 AddNewInventoryItem(m_HostCapsObj.AgentID, item); 787 AddNewInventoryItem(m_HostCapsObj.AgentID, item, cost);
696 } 788 }
697 } 789 }
698 790
@@ -854,10 +946,158 @@ namespace OpenSim.Region.ClientStack.Linden
854 response["int_response_code"] = 200; 946 response["int_response_code"] = 200;
855 return LLSDHelpers.SerialiseLLSDReply(response); 947 return LLSDHelpers.SerialiseLLSDReply(response);
856 } 948 }
949
950 public string GetObjectPhysicsData(string request, string path,
951 string param, IOSHttpRequest httpRequest,
952 IOSHttpResponse httpResponse)
953 {
954 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
955 OSDMap resp = new OSDMap();
956 OSDArray object_ids = (OSDArray)req["object_ids"];
957
958 for (int i = 0 ; i < object_ids.Count ; i++)
959 {
960 UUID uuid = object_ids[i].AsUUID();
961
962 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
963 if (obj != null)
964 {
965 OSDMap object_data = new OSDMap();
966
967 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
968 object_data["Density"] = obj.Density;
969 object_data["Friction"] = obj.Friction;
970 object_data["Restitution"] = obj.Bounciness;
971 object_data["GravityMultiplier"] = obj.GravityModifier;
972
973 resp[uuid.ToString()] = object_data;
974 }
975 }
976
977 string response = OSDParser.SerializeLLSDXmlString(resp);
978 return response;
979 }
980
981 public string GetObjectCost(string request, string path,
982 string param, IOSHttpRequest httpRequest,
983 IOSHttpResponse httpResponse)
984 {
985 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
986 OSDMap resp = new OSDMap();
987
988 OSDArray object_ids = (OSDArray)req["object_ids"];
989
990 for (int i = 0; i < object_ids.Count; i++)
991 {
992 UUID uuid = object_ids[i].AsUUID();
993
994 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
995
996 if (part != null)
997 {
998 SceneObjectGroup grp = part.ParentGroup;
999 if (grp != null)
1000 {
1001 float linksetCost;
1002 float linksetPhysCost;
1003 float partCost;
1004 float partPhysCost;
1005
1006 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
1007
1008 OSDMap object_data = new OSDMap();
1009 object_data["linked_set_resource_cost"] = linksetCost;
1010 object_data["resource_cost"] = partCost;
1011 object_data["physics_cost"] = partPhysCost;
1012 object_data["linked_set_physics_cost"] = linksetPhysCost;
1013
1014 resp[uuid.ToString()] = object_data;
1015 }
1016 }
1017 }
1018
1019 string response = OSDParser.SerializeLLSDXmlString(resp);
1020 return response;
1021 }
1022
1023 public string ResourceCostSelected(string request, string path,
1024 string param, IOSHttpRequest httpRequest,
1025 IOSHttpResponse httpResponse)
1026 {
1027 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1028 OSDMap resp = new OSDMap();
1029
1030
1031 float phys=0;
1032 float stream=0;
1033 float simul=0;
1034
1035 if (req.ContainsKey("selected_roots"))
1036 {
1037 OSDArray object_ids = (OSDArray)req["selected_roots"];
1038
1039 // should go by SOG suming costs for all parts
1040 // ll v3 works ok with several objects select we get the list and adds ok
1041 // FS calls per object so results are wrong guess fs bug
1042 for (int i = 0; i < object_ids.Count; i++)
1043 {
1044 UUID uuid = object_ids[i].AsUUID();
1045 float Physc;
1046 float simulc;
1047 float streamc;
1048
1049 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
1050 if (grp != null)
1051 {
1052 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
1053 phys += Physc;
1054 stream += streamc;
1055 simul += simulc;
1056 }
1057 }
1058 }
1059 else if (req.ContainsKey("selected_prims"))
1060 {
1061 OSDArray object_ids = (OSDArray)req["selected_prims"];
1062
1063 // don't see in use in any of the 2 viewers
1064 // guess it should be for edit linked but... nothing
1065 // should go to SOP per part
1066 for (int i = 0; i < object_ids.Count; i++)
1067 {
1068 UUID uuid = object_ids[i].AsUUID();
1069
1070 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1071 if (part != null)
1072 {
1073 phys += part.PhysicsCost;
1074 stream += part.StreamingCost;
1075 simul += part.SimulationCost;
1076 }
1077 }
1078 }
1079
1080 if (simul != 0)
1081 {
1082 OSDMap object_data = new OSDMap();
1083
1084 object_data["physics"] = phys;
1085 object_data["streaming"] = stream;
1086 object_data["simulation"] = simul;
1087
1088 resp["selected"] = object_data;
1089 }
1090
1091 string response = OSDParser.SerializeLLSDXmlString(resp);
1092 return response;
1093 }
857 } 1094 }
858 1095
859 public class AssetUploader 1096 public class AssetUploader
860 { 1097 {
1098 private static readonly ILog m_log =
1099 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1100
861 public event UpLoadedAsset OnUpLoad; 1101 public event UpLoadedAsset OnUpLoad;
862 private UpLoadedAsset handlerUpLoad = null; 1102 private UpLoadedAsset handlerUpLoad = null;
863 1103
@@ -872,6 +1112,7 @@ namespace OpenSim.Region.ClientStack.Linden
872 1112
873 private string m_invType = String.Empty; 1113 private string m_invType = String.Empty;
874 private string m_assetType = String.Empty; 1114 private string m_assetType = String.Empty;
1115 private Timer m_timeoutTimer = new Timer();
875 1116
876 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1117 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
877 UUID parentFolderID, string invType, string assetType, string path, 1118 UUID parentFolderID, string invType, string assetType, string path,
@@ -887,6 +1128,11 @@ namespace OpenSim.Region.ClientStack.Linden
887 m_assetType = assetType; 1128 m_assetType = assetType;
888 m_invType = invType; 1129 m_invType = invType;
889 m_dumpAssetsToFile = dumpAssetsToFile; 1130 m_dumpAssetsToFile = dumpAssetsToFile;
1131
1132 m_timeoutTimer.Elapsed += TimedOut;
1133 m_timeoutTimer.Interval = 120000;
1134 m_timeoutTimer.AutoReset = false;
1135 m_timeoutTimer.Start();
890 } 1136 }
891 1137
892 /// <summary> 1138 /// <summary>
@@ -908,6 +1154,7 @@ namespace OpenSim.Region.ClientStack.Linden
908 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1154 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
909 1155
910 httpListener.RemoveStreamHandler("POST", uploaderPath); 1156 httpListener.RemoveStreamHandler("POST", uploaderPath);
1157 m_timeoutTimer.Stop();
911 1158
912 // TODO: probably make this a better set of extensions here 1159 // TODO: probably make this a better set of extensions here
913 string extension = ".jp2"; 1160 string extension = ".jp2";
@@ -929,6 +1176,12 @@ namespace OpenSim.Region.ClientStack.Linden
929 return res; 1176 return res;
930 } 1177 }
931 1178
1179 private void TimedOut(object sender, ElapsedEventArgs args)
1180 {
1181 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
1182 httpListener.RemoveStreamHandler("POST", uploaderPath);
1183 }
1184
932 ///Left this in and commented in case there are unforseen issues 1185 ///Left this in and commented in case there are unforseen issues
933 //private void SaveAssetToFile(string filename, byte[] data) 1186 //private void SaveAssetToFile(string filename, byte[] data)
934 //{ 1187 //{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 594b229..ebfe687 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -377,7 +377,7 @@ namespace OpenSim.Region.ClientStack.Linden
377 // TODO: Add EventQueueGet name/description for diagnostics 377 // TODO: Add EventQueueGet name/description for diagnostics
378 MainServer.Instance.AddPollServiceHTTPHandler( 378 MainServer.Instance.AddPollServiceHTTPHandler(
379 eventQueueGetPath, 379 eventQueueGetPath,
380 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); 380 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 1000));
381 381
382// m_log.DebugFormat( 382// m_log.DebugFormat(
383// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", 383// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
@@ -831,5 +831,13 @@ namespace OpenSim.Region.ClientStack.Linden
831 { 831 {
832 return EventQueueHelper.BuildEvent(eventName, eventBody); 832 return EventQueueHelper.BuildEvent(eventName, eventBody);
833 } 833 }
834
835 public void partPhysicsProperties(uint localID, byte physhapetype,
836 float density, float friction, float bounce, float gravmod,UUID avatarID)
837 {
838 OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype,
839 density, friction, bounce, gravmod);
840 Enqueue(item, avatarID);
841 }
834 } 842 }
835} 843}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 3f49aba..7dcf137 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -151,6 +151,12 @@ namespace OpenSim.Region.ClientStack.Linden
151 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, 151 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
152 uint locationID, uint flags, string capsURL, UUID agentID) 152 uint locationID, uint flags, string capsURL, UUID agentID)
153 { 153 {
154 // not sure why flags get overwritten here
155 if ((flags & (uint)TeleportFlags.IsFlying) != 0)
156 flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying;
157 else
158 flags = (uint)TeleportFlags.ViaLocation;
159
154 OSDMap info = new OSDMap(); 160 OSDMap info = new OSDMap();
155 info.Add("AgentID", OSD.FromUUID(agentID)); 161 info.Add("AgentID", OSD.FromUUID(agentID));
156 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this? 162 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
@@ -159,7 +165,8 @@ namespace OpenSim.Region.ClientStack.Linden
159 info.Add("SimAccess", OSD.FromInteger(simAccess)); 165 info.Add("SimAccess", OSD.FromInteger(simAccess));
160 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes())); 166 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
161 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); 167 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
162 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation 168// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
169 info.Add("TeleportFlags", OSD.FromUInteger(flags));
163 170
164 OSDArray infoArr = new OSDArray(); 171 OSDArray infoArr = new OSDArray();
165 infoArr.Add(info); 172 infoArr.Add(info);
@@ -395,5 +402,25 @@ namespace OpenSim.Region.ClientStack.Linden
395 return message; 402 return message;
396 } 403 }
397 404
405 public static OSD partPhysicsProperties(uint localID, byte physhapetype,
406 float density, float friction, float bounce, float gravmod)
407 {
408
409 OSDMap physinfo = new OSDMap(6);
410 physinfo["LocalID"] = localID;
411 physinfo["Density"] = density;
412 physinfo["Friction"] = friction;
413 physinfo["GravityMultiplier"] = gravmod;
414 physinfo["Restitution"] = bounce;
415 physinfo["PhysicsShapeType"] = (int)physhapetype;
416
417 OSDArray array = new OSDArray(1);
418 array.Add(physinfo);
419
420 OSDMap llsdBody = new OSDMap(1);
421 llsdBody.Add("ObjectData", array);
422
423 return BuildEvent("ObjectPhysicsProperties", llsdBody);
424 }
398 } 425 }
399} 426}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 5ae9cc3..5b125ea 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -27,18 +27,13 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Specialized; 30using System.Collections.Generic;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection; 31using System.Reflection;
34using System.IO; 32using System.Threading;
35using System.Web;
36using log4net; 33using log4net;
37using Nini.Config; 34using Nini.Config;
38using Mono.Addins; 35using Mono.Addins;
39using OpenMetaverse; 36using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework; 37using OpenSim.Framework;
43using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
@@ -47,64 +42,73 @@ using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
50 46
51namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
52{ 48{
53 49
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 50 /// <summary>
51 /// This module implements both WebFetchTextureDescendents and FetchTextureDescendents2 capabilities.
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 54 public class GetTextureModule : INonSharedRegionModule
56 { 55 {
57// private static readonly ILog m_log = 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57
59
60 private Scene m_scene; 58 private Scene m_scene;
61 private IAssetService m_assetService;
62 59
63 private bool m_Enabled = false; 60 private static GetTextureHandler m_getTextureHandler;
61
62 private IAssetService m_assetService = null;
64 63
65 // TODO: Change this to a config option 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
66 const string REDIRECT_URL = null; 65 private static Thread[] m_workerThreads = null;
67 66
68 private string m_URL; 67 private static OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs>();
69 69
70 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
71 71
72 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
73 { 73 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"];
75 if (config == null)
76 return;
77
78 m_URL = config.GetString("Cap_GetTexture", string.Empty);
79 // Cap doesn't exist
80 if (m_URL != string.Empty)
81 m_Enabled = true;
82 } 74 }
83 75
84 public void AddRegion(Scene s) 76 public void AddRegion(Scene s)
85 { 77 {
86 if (!m_Enabled)
87 return;
88
89 m_scene = s; 78 m_scene = s;
79 m_assetService = s.AssetService;
90 } 80 }
91 81
92 public void RemoveRegion(Scene s) 82 public void RemoveRegion(Scene s)
93 { 83 {
94 if (!m_Enabled)
95 return;
96
97 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 84 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
85 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
98 m_scene = null; 86 m_scene = null;
99 } 87 }
100 88
101 public void RegionLoaded(Scene s) 89 public void RegionLoaded(Scene s)
102 { 90 {
103 if (!m_Enabled) 91 // We'll reuse the same handler for all requests.
104 return; 92 m_getTextureHandler = new GetTextureHandler(m_assetService);
105 93
106 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
107 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 94 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
95 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
96
97 if (m_workerThreads == null)
98 {
99 m_workerThreads = new Thread[4];
100
101 for (uint i = 0; i < 4; i++)
102 {
103 m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
104 String.Format("TextureWorkerThread{0}", i),
105 ThreadPriority.Normal,
106 false,
107 true,
108 null,
109 int.MaxValue);
110 }
111 }
108 } 112 }
109 113
110 public void PostInitialise() 114 public void PostInitialise()
@@ -122,24 +126,155 @@ namespace OpenSim.Region.ClientStack.Linden
122 126
123 #endregion 127 #endregion
124 128
125 public void RegisterCaps(UUID agentID, Caps caps) 129 ~GetTextureModule()
130 {
131 foreach (Thread t in m_workerThreads)
132 t.Abort();
133 }
134
135 private class PollServiceTextureEventArgs : PollServiceEventArgs
126 { 136 {
127 UUID capID = UUID.Random(); 137 private List<Hashtable> requests =
138 new List<Hashtable>();
139 private Dictionary<UUID, Hashtable> responses =
140 new Dictionary<UUID, Hashtable>();
141
142 private Scene m_scene;
128 143
129 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 144 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
130 if (m_URL == "localhost") 145 base(null, null, null, null, pId, 30000)
131 { 146 {
132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 147 m_scene = scene;
133 caps.RegisterHandler( 148
134 "GetTexture", 149 HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
135 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString())); 150 GetEvents = (x, y, s) =>
151 {
152 try
153 {
154 return this.responses[x];
155 }
156 finally
157 {
158 responses.Remove(x);
159 }
160 };
161
162 Request = (x, y) =>
163 {
164 y["RequestID"] = x.ToString();
165 lock (this.requests)
166 this.requests.Add(y);
167
168 m_queue.Enqueue(this);
169 };
170
171 NoEvents = (x, y) =>
172 {
173 lock (this.requests)
174 {
175 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
176 requests.Remove(request);
177 }
178
179 Hashtable response = new Hashtable();
180
181 response["int_response_code"] = 500;
182 response["str_response_string"] = "Script timeout";
183 response["content_type"] = "text/plain";
184 response["keepalive"] = false;
185 response["reusecontext"] = false;
186
187 return response;
188 };
136 } 189 }
137 else 190
191 public void Process()
138 { 192 {
139// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 193 Hashtable response;
140 caps.RegisterHandler("GetTexture", m_URL); 194 Hashtable request = null;
195
196 try
197 {
198 lock (this.requests)
199 {
200 request = requests[0];
201 requests.RemoveAt(0);
202 }
203 }
204 catch
205 {
206 return;
207 }
208
209 UUID requestID = new UUID(request["RequestID"].ToString());
210
211 // If the avatar is gone, don't bother to get the texture
212 if (m_scene.GetScenePresence(Id) == null)
213 {
214 response = new Hashtable();
215
216 response["int_response_code"] = 500;
217 response["str_response_string"] = "Script timeout";
218 response["content_type"] = "text/plain";
219 response["keepalive"] = false;
220 response["reusecontext"] = false;
221
222 responses[requestID] = response;
223 return;
224 }
225
226 response = m_getTextureHandler.Handle(request);
227
228 responses[requestID] = response;
229 }
230 }
231
232 private void RegisterCaps(UUID agentID, Caps caps)
233 {
234 string capUrl = "/CAPS/" + UUID.Random() + "/";
235
236 // Register this as a poll service
237 // absurd large timeout to tune later to make a bit less than viewer
238 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
239
240 args.Type = PollServiceEventArgs.EventType.Texture;
241 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
242
243 string hostName = m_scene.RegionInfo.ExternalHostName;
244 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
245 string protocol = "http";
246
247 if (MainServer.Instance.UseSSL)
248 {
249 hostName = MainServer.Instance.SSLCommonName;
250 port = MainServer.Instance.SSLPort;
251 protocol = "https";
141 } 252 }
253 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
254
255 m_capsDict[agentID] = capUrl;
142 } 256 }
143 257
258 private void DeregisterCaps(UUID agentID, Caps caps)
259 {
260 string capUrl;
261
262 if (m_capsDict.TryGetValue(agentID, out capUrl))
263 {
264 MainServer.Instance.RemoveHTTPHandler("", capUrl);
265 m_capsDict.Remove(agentID);
266 }
267 }
268
269 private void DoTextureRequests()
270 {
271 while (true)
272 {
273 PollServiceTextureEventArgs args = m_queue.Dequeue();
274
275 args.Process();
276 }
277 }
144 } 278 }
279
145} 280}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
deleted file mode 100644
index 52c4f44..0000000
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ /dev/null
@@ -1,296 +0,0 @@
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 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private Scene m_scene;
56// private IAssetService m_assetService;
57 private bool m_dumpAssetsToFile = false;
58 private bool m_enabled = true;
59 private int m_levelUpload = 0;
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 m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
77 }
78
79 public void AddRegion(Scene pScene)
80 {
81 m_scene = pScene;
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86
87 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
88 m_scene = null;
89 }
90
91 public void RegionLoaded(Scene scene)
92 {
93
94// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
95 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
96 }
97
98 #endregion
99
100
101 #region IRegionModule Members
102
103
104
105 public void Close() { }
106
107 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
108
109
110 public void RegisterCaps(UUID agentID, Caps caps)
111 {
112 if(!m_enabled)
113 return;
114
115 UUID capID = UUID.Random();
116
117// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
118 caps.RegisterHandler(
119 "NewFileAgentInventoryVariablePrice",
120 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
121 "POST",
122 "/CAPS/" + capID.ToString(),
123 req => NewAgentInventoryRequest(req, agentID),
124 "NewFileAgentInventoryVariablePrice",
125 agentID.ToString()));
126 }
127
128 #endregion
129
130 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
131 {
132 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
133 // you need to be aware of this
134
135 //if (llsdRequest.asset_type == "texture" ||
136 // llsdRequest.asset_type == "animation" ||
137 // llsdRequest.asset_type == "sound")
138 // {
139 // check user level
140
141 ScenePresence avatar = null;
142 IClientAPI client = null;
143 m_scene.TryGetScenePresence(agentID, out avatar);
144
145 if (avatar != null)
146 {
147 client = avatar.ControllingClient;
148
149 if (avatar.UserLevel < m_levelUpload)
150 {
151 if (client != null)
152 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
153
154 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
155 errorResponse.rsvp = "";
156 errorResponse.state = "error";
157 return errorResponse;
158 }
159 }
160
161 // check funds
162 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
163
164 if (mm != null)
165 {
166 if (!mm.UploadCovered(agentID, mm.UploadCharge))
167 {
168 if (client != null)
169 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
170
171 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
172 errorResponse.rsvp = "";
173 errorResponse.state = "error";
174 return errorResponse;
175 }
176 }
177
178 // }
179
180 string assetName = llsdRequest.name;
181 string assetDes = llsdRequest.description;
182 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
183 UUID newAsset = UUID.Random();
184 UUID newInvItem = UUID.Random();
185 UUID parentFolder = llsdRequest.folder_id;
186 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
187
188 AssetUploader uploader =
189 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
190 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
191
192 MainServer.Instance.AddStreamHandler(
193 new BinaryStreamHandler(
194 "POST",
195 capsBase + uploaderPath,
196 uploader.uploaderCaps,
197 "NewFileAgentInventoryVariablePrice",
198 agentID.ToString()));
199
200 string protocol = "http://";
201
202 if (MainServer.Instance.UseSSL)
203 protocol = "https://";
204
205 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
206 uploaderPath;
207
208
209 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
210
211 uploadResponse.rsvp = uploaderURL;
212 uploadResponse.state = "upload";
213 uploadResponse.resource_cost = 0;
214 uploadResponse.upload_price = 0;
215
216 uploader.OnUpLoad += //UploadCompleteHandler;
217
218 delegate(
219 string passetName, string passetDescription, UUID passetID,
220 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
221 string passetType)
222 {
223 UploadCompleteHandler(passetName, passetDescription, passetID,
224 pinventoryItem, pparentFolder, pdata, pinventoryType,
225 passetType,agentID);
226 };
227
228 return uploadResponse;
229 }
230
231 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
232 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
233 string assetType,UUID AgentID)
234 {
235// m_log.DebugFormat(
236// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
237
238 sbyte assType = 0;
239 sbyte inType = 0;
240
241 if (inventoryType == "sound")
242 {
243 inType = 1;
244 assType = 1;
245 }
246 else if (inventoryType == "animation")
247 {
248 inType = 19;
249 assType = 20;
250 }
251 else if (inventoryType == "wearable")
252 {
253 inType = 18;
254 switch (assetType)
255 {
256 case "bodypart":
257 assType = 13;
258 break;
259 case "clothing":
260 assType = 5;
261 break;
262 }
263 }
264 else if (inventoryType == "mesh")
265 {
266 inType = (sbyte)InventoryType.Mesh;
267 assType = (sbyte)AssetType.Mesh;
268 }
269
270 AssetBase asset;
271 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
272 asset.Data = data;
273
274 if (m_scene.AssetService != null)
275 m_scene.AssetService.Store(asset);
276
277 InventoryItemBase item = new InventoryItemBase();
278 item.Owner = AgentID;
279 item.CreatorId = AgentID.ToString();
280 item.ID = inventoryItem;
281 item.AssetID = asset.FullID;
282 item.Description = assetDescription;
283 item.Name = assetName;
284 item.AssetType = assType;
285 item.InvType = inType;
286 item.Folder = parentFolder;
287 item.CurrentPermissions
288 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
289 item.BasePermissions = (uint)PermissionMask.All;
290 item.EveryOnePermissions = 0;
291 item.NextPermissions = (uint)PermissionMask.All;
292 item.CreationDate = Util.UnixTimeSinceEpoch();
293 m_scene.AddInventoryItem(item);
294 }
295 }
296}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 36af55f..413536d 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -64,6 +64,8 @@ namespace OpenSim.Region.ClientStack.Linden
64 private Commands m_commands = new Commands(); 64 private Commands m_commands = new Commands();
65 public ICommands Commands { get { return m_commands; } } 65 public ICommands Commands { get { return m_commands; } }
66 66
67 public event ConsoleMessage OnConsoleMessage;
68
67 public void Initialise(IConfigSource source) 69 public void Initialise(IConfigSource source)
68 { 70 {
69 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help); 71 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
@@ -118,6 +120,11 @@ namespace OpenSim.Region.ClientStack.Linden
118 OSD osd = OSD.FromString(message); 120 OSD osd = OSD.FromString(message);
119 121
120 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID); 122 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
123
124 ConsoleMessage handlerConsoleMessage = OnConsoleMessage;
125
126 if (handlerConsoleMessage != null)
127 handlerConsoleMessage( agentID, message);
121 } 128 }
122 129
123 public bool RunCommand(string command, UUID invokerID) 130 public bool RunCommand(string command, UUID invokerID)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 2359bd6..4908c2c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -27,18 +27,22 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
32using System.Threading;
31using log4net; 33using log4net;
32using Nini.Config; 34using Nini.Config;
33using Mono.Addins; 35using Mono.Addins;
34using OpenMetaverse; 36using OpenMetaverse;
35using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
40using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
41using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
42 46
43namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
44{ 48{
@@ -48,67 +52,65 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class WebFetchInvDescModule : INonSharedRegionModule 53 public class WebFetchInvDescModule : INonSharedRegionModule
50 { 54 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 56
53 private Scene m_scene; 57 private Scene m_scene;
54 58
55 private IInventoryService m_InventoryService; 59 private IInventoryService m_InventoryService;
56 private ILibraryService m_LibraryService; 60 private ILibraryService m_LibraryService;
57 61
58 private bool m_Enabled; 62 private static WebFetchInvDescHandler m_webFetchHandler;
59 63
60 private string m_fetchInventoryDescendents2Url; 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
61 private string m_webFetchInventoryDescendentsUrl; 65 private static Thread[] m_workerThreads = null;
62 66
63 private WebFetchInvDescHandler m_webFetchHandler; 67 private static OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs>();
64 69
65 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
66 71
67 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
68 { 73 {
69 IConfig config = source.Configs["ClientStack.LindenCaps"];
70 if (config == null)
71 return;
72
73 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
74 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
75
76 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
77 {
78 m_Enabled = true;
79 }
80 } 74 }
81 75
82 public void AddRegion(Scene s) 76 public void AddRegion(Scene s)
83 { 77 {
84 if (!m_Enabled)
85 return;
86
87 m_scene = s; 78 m_scene = s;
88 } 79 }
89 80
90 public void RemoveRegion(Scene s) 81 public void RemoveRegion(Scene s)
91 { 82 {
92 if (!m_Enabled)
93 return;
94
95 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 83 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
84 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
96 m_scene = null; 85 m_scene = null;
97 } 86 }
98 87
99 public void RegionLoaded(Scene s) 88 public void RegionLoaded(Scene s)
100 { 89 {
101 if (!m_Enabled)
102 return;
103
104 m_InventoryService = m_scene.InventoryService; 90 m_InventoryService = m_scene.InventoryService;
105 m_LibraryService = m_scene.LibraryService; 91 m_LibraryService = m_scene.LibraryService;
106 92
107 // We'll reuse the same handler for all requests. 93 // We'll reuse the same handler for all requests.
108 if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost") 94 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
109 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
110 95
111 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
97 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
98
99 if (m_workerThreads == null)
100 {
101 m_workerThreads = new Thread[2];
102
103 for (uint i = 0; i < 2; i++)
104 {
105 m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests,
106 String.Format("InventoryWorkerThread{0}", i),
107 ThreadPriority.Normal,
108 false,
109 true,
110 null,
111 int.MaxValue);
112 }
113 }
112 } 114 }
113 115
114 public void PostInitialise() 116 public void PostInitialise()
@@ -126,43 +128,141 @@ namespace OpenSim.Region.ClientStack.Linden
126 128
127 #endregion 129 #endregion
128 130
129 private void RegisterCaps(UUID agentID, Caps caps) 131 ~WebFetchInvDescModule()
130 { 132 {
131 if (m_webFetchInventoryDescendentsUrl != "") 133 foreach (Thread t in m_workerThreads)
132 RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl); 134 t.Abort();
133
134 if (m_fetchInventoryDescendents2Url != "")
135 RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
136 } 135 }
137 136
138 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url) 137 private class PollServiceInventoryEventArgs : PollServiceEventArgs
139 { 138 {
140 string capUrl; 139 private List<Hashtable> requests =
140 new List<Hashtable>();
141 private Dictionary<UUID, Hashtable> responses =
142 new Dictionary<UUID, Hashtable>();
141 143
142 if (url == "localhost") 144 public PollServiceInventoryEventArgs(UUID pId) :
145 base(null, null, null, null, pId, 30000)
143 { 146 {
144 capUrl = "/CAPS/" + UUID.Random(); 147 HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
148 GetEvents = (x, y, s) =>
149 {
150 try
151 {
152 return this.responses[x];
153 }
154 finally
155 {
156 responses.Remove(x);
157 }
158 };
159
160 Request = (x, y) =>
161 {
162 y["RequestID"] = x.ToString();
163 lock (this.requests)
164 this.requests.Add(y);
165
166 m_queue.Enqueue(this);
167 };
168
169 NoEvents = (x, y) =>
170 {
171 lock (this.requests)
172 {
173 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
174 requests.Remove(request);
175 }
176
177 Hashtable response = new Hashtable();
178
179 response["int_response_code"] = 500;
180 response["str_response_string"] = "Script timeout";
181 response["content_type"] = "text/plain";
182 response["keepalive"] = false;
183 response["reusecontext"] = false;
184
185 return response;
186 };
187 }
188
189 public void Process()
190 {
191 Hashtable request = null;
192
193 try
194 {
195 lock (this.requests)
196 {
197 request = requests[0];
198 requests.RemoveAt(0);
199 }
200 }
201 catch
202 {
203 return;
204 }
205
206 UUID requestID = new UUID(request["RequestID"].ToString());
145 207
146 IRequestHandler reqHandler 208 Hashtable response = new Hashtable();
147 = new RestStreamHandler(
148 "POST",
149 capUrl,
150 m_webFetchHandler.FetchInventoryDescendentsRequest,
151 "FetchInventoryDescendents2",
152 agentID.ToString());
153 209
154 caps.RegisterHandler(capName, reqHandler); 210 response["int_response_code"] = 200;
211 response["content_type"] = "text/plain";
212 response["keepalive"] = false;
213 response["reusecontext"] = false;
214
215 response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null);
216
217 responses[requestID] = response;
155 } 218 }
156 else 219 }
220
221 private void RegisterCaps(UUID agentID, Caps caps)
222 {
223 string capUrl = "/CAPS/" + UUID.Random() + "/";
224
225 // Register this as a poll service
226 // absurd large timeout to tune later to make a bit less than viewer
227 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID);
228
229 args.Type = PollServiceEventArgs.EventType.Inventory;
230 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
231
232 string hostName = m_scene.RegionInfo.ExternalHostName;
233 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
234 string protocol = "http";
235
236 if (MainServer.Instance.UseSSL)
157 { 237 {
158 capUrl = url; 238 hostName = MainServer.Instance.SSLCommonName;
239 port = MainServer.Instance.SSLPort;
240 protocol = "https";
241 }
242 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
243
244 m_capsDict[agentID] = capUrl;
245 }
159 246
160 caps.RegisterHandler(capName, capUrl); 247 private void DeregisterCaps(UUID agentID, Caps caps)
248 {
249 string capUrl;
250
251 if (m_capsDict.TryGetValue(agentID, out capUrl))
252 {
253 MainServer.Instance.RemoveHTTPHandler("", capUrl);
254 m_capsDict.Remove(agentID);
161 } 255 }
256 }
162 257
163// m_log.DebugFormat( 258 private void DoInventoryRequests()
164// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}", 259 {
165// capName, capUrl, m_scene.RegionInfo.RegionName, agentID); 260 while (true)
261 {
262 PollServiceInventoryEventArgs args = m_queue.Dequeue();
263
264 args.Process();
265 }
166 } 266 }
167 } 267 }
168} \ No newline at end of file 268}