aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/ClientStack/Linden/Caps
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs1610
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs746
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs521
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs110
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs14
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs144
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs329
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs412
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs22
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs297
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs14
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs10
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs18
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs17
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs203
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs101
21 files changed, 3085 insertions, 1515 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs
index aabdb51..8f65a69 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs
@@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenCaps
133 { 133 {
134 data = new AgentPrefs(agent); 134 data = new AgentPrefs(agent);
135 } 135 }
136 136
137 if (req.ContainsKey("access_prefs")) 137 if (req.ContainsKey("access_prefs"))
138 { 138 {
139 OSDMap accessPrefs = (OSDMap)req["access_prefs"]; // We could check with ContainsKey... 139 OSDMap accessPrefs = (OSDMap)req["access_prefs"]; // We could check with ContainsKey...
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
index bbadc55..e3c430c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.ClientStack.Linden
53 public class AvatarPickerSearchModule : INonSharedRegionModule 53 public class AvatarPickerSearchModule : INonSharedRegionModule
54 { 54 {
55// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 56
57 private Scene m_scene; 57 private Scene m_scene;
58 private IPeople m_People; 58 private IPeople m_People;
59 private bool m_Enabled = false; 59 private bool m_Enabled = false;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 774202e..6f5775a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -26,11 +26,14 @@
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;
32using System.Collections.Specialized;
31using System.IO; 33using System.IO;
32using System.Reflection; 34using System.Reflection;
33using System.Text; 35using System.Text;
36using System.Web;
34 37
35using OpenMetaverse; 38using OpenMetaverse;
36using OpenMetaverse.StructuredData; 39using OpenMetaverse.StructuredData;
@@ -40,11 +43,11 @@ using log4net;
40using OpenSim.Framework; 43using OpenSim.Framework;
41using OpenSim.Framework.Capabilities; 44using OpenSim.Framework.Capabilities;
42using OpenSim.Region.Framework; 45using OpenSim.Region.Framework;
46using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization; 48using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Framework.Servers; 49using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer; 50using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Framework.Client;
48using OpenSim.Services.Interfaces; 51using OpenSim.Services.Interfaces;
49 52
50using Caps = OpenSim.Framework.Capabilities.Caps; 53using Caps = OpenSim.Framework.Capabilities.Caps;
@@ -55,14 +58,16 @@ using PermissionMask = OpenSim.Framework.PermissionMask;
55namespace OpenSim.Region.ClientStack.Linden 58namespace OpenSim.Region.ClientStack.Linden
56{ 59{
57 public delegate void UpLoadedAsset( 60 public delegate void UpLoadedAsset(
58 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, 61 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
59 byte[] data, string inventoryType, string assetType); 62 byte[] data, string inventoryType, string assetType,
63 int cost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
64 bool IsAtestUpload, ref string error, ref int nextOwnerMask, ref int groupMask, ref int everyoneMask);
60 65
61 public delegate UUID UpdateItem(UUID itemID, byte[] data); 66 public delegate UUID UpdateItem(UUID itemID, byte[] data);
62 67
63 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); 68 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
64 69
65 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); 70 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
66 71
67 public delegate void NewAsset(AssetBase asset); 72 public delegate void NewAsset(AssetBase asset);
68 73
@@ -87,21 +92,12 @@ namespace OpenSim.Region.ClientStack.Linden
87 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 92 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
88 93
89 private Scene m_Scene; 94 private Scene m_Scene;
95 private UUID m_AgentID;
90 private Caps m_HostCapsObj; 96 private Caps m_HostCapsObj;
97 private ModelCost m_ModelCost;
91 98
92 private static readonly string m_requestPath = "0000/";
93 // private static readonly string m_mapLayerPath = "0001/";
94 private static readonly string m_newInventory = "0002/";
95 //private static readonly string m_requestTexture = "0003/";
96 private static readonly string m_notecardUpdatePath = "0004/";
97 private static readonly string m_notecardTaskUpdatePath = "0005/";
98 // private static readonly string m_fetchInventoryPath = "0006/";
99 private static readonly string m_copyFromNotecardPath = "0007/";
100 // 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.
101 private static readonly string m_getObjectPhysicsDataPath = "0101/"; 100
102 /* 0102 - 0103 RESERVED */
103 private static readonly string m_UpdateAgentInformationPath = "0500/";
104
105 // These are callbacks which will be setup by the scene so that we can update scene data when we 101 // These are callbacks which will be setup by the scene so that we can update scene data when we
106 // receive capability calls 102 // receive capability calls
107 public NewInventoryItem AddNewInventoryItem = null; 103 public NewInventoryItem AddNewInventoryItem = null;
@@ -115,12 +111,45 @@ namespace OpenSim.Region.ClientStack.Linden
115 private IAssetService m_assetService; 111 private IAssetService m_assetService;
116 private bool m_dumpAssetsToFile = false; 112 private bool m_dumpAssetsToFile = false;
117 private string m_regionName; 113 private string m_regionName;
114
118 private int m_levelUpload = 0; 115 private int m_levelUpload = 0;
119 116
120 public BunchOfCaps(Scene scene, Caps caps) 117 private bool m_enableFreeTestUpload = false; // allows "TEST-" prefix hack
118 private bool m_ForceFreeTestUpload = false; // forces all uploads to be test
119
120 private bool m_enableModelUploadTextureToInventory = false; // place uploaded textures also in inventory
121 // may not be visible till relog
122
123 private bool m_RestrictFreeTestUploadPerms = false; // reduces also the permitions. Needs a creator defined!!
124 private UUID m_testAssetsCreatorID = UUID.Zero;
125
126 private float m_PrimScaleMin = 0.001f;
127
128 private bool m_AllowCapHomeLocation = true;
129 private bool m_AllowCapGroupMemberData = true;
130 private IUserManagement m_UserManager;
131
132
133 private enum FileAgentInventoryState : int
134 {
135 idle = 0,
136 processRequest = 1,
137 waitUpload = 2,
138 processUpload = 3
139 }
140 private FileAgentInventoryState m_FileAgentInventoryState = FileAgentInventoryState.idle;
141
142 public BunchOfCaps(Scene scene, UUID agentID, Caps caps)
121 { 143 {
122 m_Scene = scene; 144 m_Scene = scene;
145 m_AgentID = agentID;
123 m_HostCapsObj = caps; 146 m_HostCapsObj = caps;
147
148 // create a model upload cost provider
149 m_ModelCost = new ModelCost(scene);
150
151 m_PrimScaleMin = m_ModelCost.PrimScaleMin;
152
124 IConfigSource config = m_Scene.Config; 153 IConfigSource config = m_Scene.Config;
125 if (config != null) 154 if (config != null)
126 { 155 {
@@ -135,10 +164,45 @@ namespace OpenSim.Region.ClientStack.Linden
135 { 164 {
136 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); 165 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
137 } 166 }
167 // economy for model upload
168 IConfig EconomyConfig = config.Configs["Economy"];
169 if (EconomyConfig != null)
170 {
171 m_ModelCost.Econfig(EconomyConfig);
172
173 m_enableModelUploadTextureToInventory = EconomyConfig.GetBoolean("MeshModelAllowTextureToInventory", m_enableModelUploadTextureToInventory);
174
175 m_RestrictFreeTestUploadPerms = EconomyConfig.GetBoolean("m_RestrictFreeTestUploadPerms", m_RestrictFreeTestUploadPerms);
176 m_enableFreeTestUpload = EconomyConfig.GetBoolean("AllowFreeTestUpload", m_enableFreeTestUpload);
177 m_ForceFreeTestUpload = EconomyConfig.GetBoolean("ForceFreeTestUpload", m_ForceFreeTestUpload);
178 string testcreator = EconomyConfig.GetString("TestAssetsCreatorID", "");
179 if (testcreator != "")
180 {
181 UUID id;
182 UUID.TryParse(testcreator, out id);
183 if (id != null)
184 m_testAssetsCreatorID = id;
185 }
186 }
187
188 IConfig CapsConfig = config.Configs["ClientStack.LindenCaps"];
189 if (CapsConfig != null)
190 {
191 string homeLocationUrl = CapsConfig.GetString("Cap_HomeLocation", "localhost");
192 if(homeLocationUrl == String.Empty)
193 m_AllowCapHomeLocation = false;
194
195 string GroupMemberDataUrl = CapsConfig.GetString("Cap_GroupMemberData", "localhost");
196 if(GroupMemberDataUrl == String.Empty)
197 m_AllowCapGroupMemberData = false;
198 }
138 } 199 }
139 200
140 m_assetService = m_Scene.AssetService; 201 m_assetService = m_Scene.AssetService;
141 m_regionName = m_Scene.RegionInfo.RegionName; 202 m_regionName = m_Scene.RegionInfo.RegionName;
203 m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
204 if (m_UserManager == null)
205 m_log.Error("[CAPS]: GetDisplayNames disabled because user management component not found");
142 206
143 RegisterHandlers(); 207 RegisterHandlers();
144 208
@@ -146,6 +210,13 @@ namespace OpenSim.Region.ClientStack.Linden
146 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset; 210 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
147 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset; 211 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
148 GetClient = m_Scene.SceneGraph.GetControllingClient; 212 GetClient = m_Scene.SceneGraph.GetControllingClient;
213
214 m_FileAgentInventoryState = FileAgentInventoryState.idle;
215 }
216
217 public string GetNewCapPath()
218 {
219 return "/CAPS/" + UUID.Random();
149 } 220 }
150 221
151 /// <summary> 222 /// <summary>
@@ -153,33 +224,67 @@ namespace OpenSim.Region.ClientStack.Linden
153 /// </summary> 224 /// </summary>
154 public void RegisterHandlers() 225 public void RegisterHandlers()
155 { 226 {
156 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 227 // this path is also defined elsewhere so keeping it
228 string seedcapsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath +"0000/";
157 229
158 RegisterRegionServiceHandlers(capsBase); 230 // the root of all evil path needs to be capsBase + m_requestPath
159 RegisterInventoryServiceHandlers(capsBase); 231 m_HostCapsObj.RegisterHandler(
232 "SEED", new RestStreamHandler("POST", seedcapsBase, SeedCapRequest, "SEED", null));
233
234// m_log.DebugFormat(
235// "[CAPS]: Registered seed capability {0} for {1}", seedcapsBase, m_HostCapsObj.AgentID);
236
237 RegisterRegionServiceHandlers();
238 RegisterInventoryServiceHandlers();
239 RegisterOtherHandlers();
160 } 240 }
161 241
162 public void RegisterRegionServiceHandlers(string capsBase) 242 public void RegisterRegionServiceHandlers()
163 { 243 {
164 try 244 try
165 { 245 {
166 // the root of all evil
167 m_HostCapsObj.RegisterHandler(
168 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
169
170// m_log.DebugFormat(
171// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
172
173 //m_capsHandlers["MapLayer"] = 246 //m_capsHandlers["MapLayer"] =
174 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", 247 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
175 // capsBase + m_mapLayerPath, 248 // GetNewCapPath(),
176 // GetMapLayer); 249 // GetMapLayer);
177 IRequestHandler req 250
178 = new RestStreamHandler( 251 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler(
179 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null); 252 "POST", GetNewCapPath(), GetObjectPhysicsData, "GetObjectPhysicsData", null);
253 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
254
255 IRequestHandler getObjectCostHandler = new RestStreamHandler(
256 "POST", GetNewCapPath(), GetObjectCost, "GetObjectCost", null );
257 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
180 258
259 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler(
260 "POST", GetNewCapPath(), ResourceCostSelected, "ResourceCostSelected", null);
261 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
262
263 IRequestHandler req = new RestStreamHandler(
264 "POST", GetNewCapPath(), ScriptTaskInventory, "UpdateScript", null);
181 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); 265 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); 266 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
267
268 if(m_AllowCapHomeLocation)
269 {
270 IRequestHandler HomeLocationHandler = new RestStreamHandler(
271 "POST", GetNewCapPath(), HomeLocation, "HomeLocation", null);
272 m_HostCapsObj.RegisterHandler("HomeLocation", HomeLocationHandler);
273 }
274
275 if(m_AllowCapGroupMemberData)
276 {
277 IRequestHandler GroupMemberDataHandler = new RestStreamHandler(
278 "POST", GetNewCapPath(), GroupMemberData, "GroupMemberData", null);
279 m_HostCapsObj.RegisterHandler("GroupMemberData", GroupMemberDataHandler);
280 }
281
282
283// IRequestHandler animSetRequestHandler
284// = new RestStreamHandler(
285// "POST", capsBase + m_animSetTaskUpdatePath, AnimSetTaskInventory, "UpdateScript", null);
286
287// m_HostCapsObj.RegisterHandler("UpdateAnimSetTaskInventory", animSetRequestHandler);
183 } 288 }
184 catch (Exception e) 289 catch (Exception e)
185 { 290 {
@@ -187,68 +292,29 @@ namespace OpenSim.Region.ClientStack.Linden
187 } 292 }
188 } 293 }
189 294
190 public void RegisterInventoryServiceHandlers(string capsBase) 295 public void RegisterInventoryServiceHandlers()
191 { 296 {
192 try 297 try
193 { 298 {
194 // I don't think this one works... 299 m_HostCapsObj.RegisterHandler("NewFileAgentInventory",
195 m_HostCapsObj.RegisterHandler(
196 "NewFileAgentInventory",
197 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>( 300 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
198 "POST", 301 "POST", GetNewCapPath(), NewAgentInventoryRequest, "NewFileAgentInventory", null));
199 capsBase + m_newInventory,
200 NewAgentInventoryRequest,
201 "NewFileAgentInventory",
202 null));
203
204 IRequestHandler req
205 = new RestStreamHandler(
206 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
207 302
303 IRequestHandler req = new RestStreamHandler(
304 "POST", GetNewCapPath(), NoteCardAgentInventory, "Update*", null);
208 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 305 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
306 m_HostCapsObj.RegisterHandler("UpdateAnimSetAgentInventory", req);
209 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 307 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
210 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 308 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
211 309
212 IRequestHandler getObjectPhysicsDataHandler 310 IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler(
213 = new RestStreamHandler( 311 "POST", GetNewCapPath(), UpdateAgentInformation, "UpdateAgentInformation", null);
214 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
215 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
216
217 IRequestHandler UpdateAgentInformationHandler
218 = new RestStreamHandler(
219 "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null);
220 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); 312 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
221 313
222 m_HostCapsObj.RegisterHandler( 314 IRequestHandler CopyInventoryFromNotecardHandler = new RestStreamHandler(
223 "CopyInventoryFromNotecard", 315 "POST", GetNewCapPath(), CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null);
224 new RestStreamHandler( 316 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", CopyInventoryFromNotecardHandler);
225 "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null)); 317
226
227 // As of RC 1.22.9 of the Linden client this is
228 // supported
229
230 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
231
232 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
233 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
234 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
235 // but when I went on the Linden grid, the
236 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
237 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
238 //
239 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
240 // we will be
241 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
242 // m_capsHandlers["FetchInventoryDescendents"] =
243 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
244
245 // m_capsHandlers["FetchInventoryDescendents"] =
246 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
247 // capsBase + m_fetchInventory,
248 // FetchInventory));
249 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
250 // capsBase + m_requestTexture,
251 // RequestTexture);
252 } 318 }
253 catch (Exception e) 319 catch (Exception e)
254 { 320 {
@@ -256,6 +322,22 @@ namespace OpenSim.Region.ClientStack.Linden
256 } 322 }
257 } 323 }
258 324
325 public void RegisterOtherHandlers()
326 {
327 try
328 {
329 if (m_UserManager != null)
330 {
331 IRequestHandler GetDisplayNamesHandler = new RestStreamHandler(
332 "GET", GetNewCapPath(), GetDisplayNames, "GetDisplayNames", null);
333 m_HostCapsObj.RegisterHandler("GetDisplayNames", GetDisplayNamesHandler);
334 }
335 }
336 catch (Exception e)
337 {
338 m_log.Error("[CAPS]: " + e.ToString());
339 }
340 }
259 /// <summary> 341 /// <summary>
260 /// Construct a client response detailing all the capabilities this server can provide. 342 /// Construct a client response detailing all the capabilities this server can provide.
261 /// </summary> 343 /// </summary>
@@ -268,8 +350,11 @@ namespace OpenSim.Region.ClientStack.Linden
268 public string SeedCapRequest(string request, string path, string param, 350 public string SeedCapRequest(string request, string path, string param,
269 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 351 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
270 { 352 {
271// m_log.DebugFormat( 353 m_log.DebugFormat(
272// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID); 354 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
355
356 if (!m_HostCapsObj.WaitForActivation())
357 return string.Empty;
273 358
274 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 359 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
275 { 360 {
@@ -314,30 +399,28 @@ namespace OpenSim.Region.ClientStack.Linden
314 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate(); 399 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
315 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest); 400 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
316 401
317 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 402 string uploaderPath = GetNewCapPath();
318 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
319 403
320 TaskInventoryScriptUpdater uploader = 404 TaskInventoryScriptUpdater uploader =
321 new TaskInventoryScriptUpdater( 405 new TaskInventoryScriptUpdater(
322 llsdUpdateRequest.item_id, 406 llsdUpdateRequest.item_id,
323 llsdUpdateRequest.task_id, 407 llsdUpdateRequest.task_id,
324 llsdUpdateRequest.is_script_running, 408 llsdUpdateRequest.is_script_running,
325 capsBase + uploaderPath, 409 uploaderPath,
326 m_HostCapsObj.HttpListener, 410 m_HostCapsObj.HttpListener,
327 m_dumpAssetsToFile); 411 m_dumpAssetsToFile);
328 uploader.OnUpLoad += TaskScriptUpdated; 412 uploader.OnUpLoad += TaskScriptUpdated;
329 413
330 m_HostCapsObj.HttpListener.AddStreamHandler( 414 m_HostCapsObj.HttpListener.AddStreamHandler(
331 new BinaryStreamHandler( 415 new BinaryStreamHandler(
332 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null)); 416 "POST", uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
333 417
334 string protocol = "http://"; 418 string protocol = "http://";
335 419
336 if (m_HostCapsObj.SSLCaps) 420 if (m_HostCapsObj.SSLCaps)
337 protocol = "https://"; 421 protocol = "https://";
338 422
339 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 423 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
340 uploaderPath;
341 424
342 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 425 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
343 uploadResponse.uploader = uploaderURL; 426 uploadResponse.uploader = uploaderURL;
@@ -400,83 +483,208 @@ namespace OpenSim.Region.ClientStack.Linden
400 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); 483 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
401 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); 484 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
402 485
486 // start by getting the client
487 IClientAPI client = null;
488 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
489
490 // check current state so we only have one service at a time
491 lock (m_ModelCost)
492 {
493 switch (m_FileAgentInventoryState)
494 {
495 case FileAgentInventoryState.processRequest:
496 case FileAgentInventoryState.processUpload:
497 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
498 resperror.message = "Uploader busy processing previus request";
499 resperror.identifier = UUID.Zero;
500
501 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
502 errorResponse.uploader = "";
503 errorResponse.state = "error";
504 errorResponse.error = resperror;
505 return errorResponse;
506 break;
507 case FileAgentInventoryState.waitUpload:
508 // todo stop current uploader server
509 break;
510 case FileAgentInventoryState.idle:
511 default:
512 break;
513 }
514
515 m_FileAgentInventoryState = FileAgentInventoryState.processRequest;
516 }
517
518 int cost = 0;
519 int nreqtextures = 0;
520 int nreqmeshs= 0;
521 int nreqinstances = 0;
522 bool IsAtestUpload = false;
523
524 string assetName = llsdRequest.name;
525
526 LLSDAssetUploadResponseData meshcostdata = new LLSDAssetUploadResponseData();
527
403 if (llsdRequest.asset_type == "texture" || 528 if (llsdRequest.asset_type == "texture" ||
404 llsdRequest.asset_type == "animation" || 529 llsdRequest.asset_type == "animation" ||
530 llsdRequest.asset_type == "animatn" || // this is the asset name actually used by viewers
531 llsdRequest.asset_type == "mesh" ||
405 llsdRequest.asset_type == "sound") 532 llsdRequest.asset_type == "sound")
406 { 533 {
407 ScenePresence avatar = null; 534 ScenePresence avatar = null;
408 IClientAPI client = null;
409 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar); 535 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
410 536
411 // check user level 537 // check user level
412 if (avatar != null) 538 if (avatar != null)
413 { 539 {
414 client = avatar.ControllingClient; 540 if (avatar.GodController.UserLevel < m_levelUpload)
415
416 if (avatar.UserLevel < m_levelUpload)
417 { 541 {
418 if (client != null) 542 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
419 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); 543 resperror.message = "Insufficient permissions to upload";
544 resperror.identifier = UUID.Zero;
420 545
421 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 546 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
422 errorResponse.uploader = ""; 547 errorResponse.uploader = "";
423 errorResponse.state = "error"; 548 errorResponse.state = "error";
549 errorResponse.error = resperror;
550 lock (m_ModelCost)
551 m_FileAgentInventoryState = FileAgentInventoryState.idle;
424 return errorResponse; 552 return errorResponse;
425 } 553 }
426 } 554 }
427 555
428 // check funds 556 // check test upload and funds
429 if (client != null) 557 if (client != null)
430 { 558 {
431 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>(); 559 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
432 560
561 int baseCost = 0;
433 if (mm != null) 562 if (mm != null)
563 baseCost = mm.UploadCharge;
564
565 string warning = String.Empty;
566
567 if (llsdRequest.asset_type == "mesh")
434 { 568 {
435 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) 569 string error;
570 int modelcost;
571
572
573 if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
574 meshcostdata, out error, ref warning))
436 { 575 {
437 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 576 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
577 resperror.message = error;
578 resperror.identifier = UUID.Zero;
438 579
439 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse(); 580 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
440 errorResponse.uploader = ""; 581 errorResponse.uploader = "";
441 errorResponse.state = "error"; 582 errorResponse.state = "error";
583 errorResponse.error = resperror;
584
585 lock (m_ModelCost)
586 m_FileAgentInventoryState = FileAgentInventoryState.idle;
442 return errorResponse; 587 return errorResponse;
443 } 588 }
589 cost = modelcost;
590 }
591 else
592 {
593 cost = baseCost;
444 } 594 }
595
596 if (cost > 0 && mm != null)
597 {
598 // check for test upload
599
600 if (m_ForceFreeTestUpload) // all are test
601 {
602 if (!(assetName.Length > 5 && assetName.StartsWith("TEST-"))) // has normal name lets change it
603 assetName = "TEST-" + assetName;
604
605 IsAtestUpload = true;
606 }
607
608 else if (m_enableFreeTestUpload) // only if prefixed with "TEST-"
609 {
610
611 IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-"));
612 }
613
614
615 if(IsAtestUpload) // let user know, still showing cost estimation
616 warning += "Upload will have no cost, for testing purposes only. Other uses are prohibited. Items will not work after 48 hours or on other regions";
617
618 // check funds
619 else
620 {
621 if (!mm.UploadCovered(client.AgentId, (int)cost))
622 {
623 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
624 resperror.message = "Insuficient funds";
625 resperror.identifier = UUID.Zero;
626
627 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
628 errorResponse.uploader = "";
629 errorResponse.state = "error";
630 errorResponse.error = resperror;
631 lock (m_ModelCost)
632 m_FileAgentInventoryState = FileAgentInventoryState.idle;
633 return errorResponse;
634 }
635 }
636 }
637
638 if (client != null && warning != String.Empty)
639 client.SendAgentAlertMessage(warning, true);
445 } 640 }
446 } 641 }
447 642
448 string assetName = llsdRequest.name;
449 string assetDes = llsdRequest.description; 643 string assetDes = llsdRequest.description;
450 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
451 UUID newAsset = UUID.Random(); 644 UUID newAsset = UUID.Random();
452 UUID newInvItem = UUID.Random(); 645 UUID newInvItem = UUID.Random();
453 UUID parentFolder = llsdRequest.folder_id; 646 UUID parentFolder = llsdRequest.folder_id;
454 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 647 string uploaderPath = GetNewCapPath();
648 UUID texturesFolder = UUID.Zero;
649
650 if(!IsAtestUpload && m_enableModelUploadTextureToInventory)
651 texturesFolder = llsdRequest.texture_folder_id;
455 652
456 AssetUploader uploader = 653 AssetUploader uploader =
457 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 654 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
458 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 655 llsdRequest.asset_type, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost,
656 texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload,
657 llsdRequest.next_owner_mask, llsdRequest.group_mask, llsdRequest.everyone_mask);
459 658
460 m_HostCapsObj.HttpListener.AddStreamHandler( 659 m_HostCapsObj.HttpListener.AddStreamHandler(
461 new BinaryStreamHandler( 660 new BinaryStreamHandler(
462 "POST", 661 "POST",
463 capsBase + uploaderPath, 662 uploaderPath,
464 uploader.uploaderCaps, 663 uploader.uploaderCaps,
465 "NewAgentInventoryRequest", 664 "NewAgentInventoryRequest",
466 m_HostCapsObj.AgentID.ToString())); 665 m_HostCapsObj.AgentID.ToString()));
467 666
468 string protocol = "http://"; 667 string protocol = "http://";
469
470 if (m_HostCapsObj.SSLCaps) 668 if (m_HostCapsObj.SSLCaps)
471 protocol = "https://"; 669 protocol = "https://";
472 670
473 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 671 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
474 uploaderPath;
475 672
476 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 673 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
477 uploadResponse.uploader = uploaderURL; 674 uploadResponse.uploader = uploaderURL;
478 uploadResponse.state = "upload"; 675 uploadResponse.state = "upload";
676 uploadResponse.upload_price = (int)cost;
677
678 if (llsdRequest.asset_type == "mesh")
679 {
680 uploadResponse.data = meshcostdata;
681 }
682
479 uploader.OnUpLoad += UploadCompleteHandler; 683 uploader.OnUpLoad += UploadCompleteHandler;
684
685 lock (m_ModelCost)
686 m_FileAgentInventoryState = FileAgentInventoryState.waitUpload;
687
480 return uploadResponse; 688 return uploadResponse;
481 } 689 }
482 690
@@ -488,8 +696,14 @@ namespace OpenSim.Region.ClientStack.Linden
488 /// <param name="data"></param> 696 /// <param name="data"></param>
489 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 697 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
490 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 698 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
491 string assetType) 699 string assetType, int cost,
700 UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
701 bool IsAtestUpload, ref string error,
702 ref int nextOwnerMask, ref int groupMask, ref int everyoneMask)
492 { 703 {
704 lock (m_ModelCost)
705 m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
706
493 m_log.DebugFormat( 707 m_log.DebugFormat(
494 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}", 708 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
495 assetID, inventoryItem, inventoryType, assetType); 709 assetID, inventoryItem, inventoryType, assetType);
@@ -497,6 +711,34 @@ namespace OpenSim.Region.ClientStack.Linden
497 sbyte assType = 0; 711 sbyte assType = 0;
498 sbyte inType = 0; 712 sbyte inType = 0;
499 713
714 IClientAPI client = null;
715
716 UUID owner_id = m_HostCapsObj.AgentID;
717 UUID creatorID;
718
719 bool istest = IsAtestUpload && m_enableFreeTestUpload && (cost > 0);
720
721 bool restrictPerms = m_RestrictFreeTestUploadPerms && istest;
722
723 if (istest && m_testAssetsCreatorID != UUID.Zero)
724 creatorID = m_testAssetsCreatorID;
725 else
726 creatorID = owner_id;
727
728 string creatorIDstr = creatorID.ToString();
729
730 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
731 if (mm != null)
732 {
733 // make sure client still has enougth credit
734 if (!mm.UploadCovered(m_HostCapsObj.AgentID, (int)cost))
735 {
736 error = "Insufficient funds.";
737 return;
738 }
739 }
740
741 // strings to types
500 if (inventoryType == "sound") 742 if (inventoryType == "sound")
501 { 743 {
502 inType = (sbyte)InventoryType.Sound; 744 inType = (sbyte)InventoryType.Sound;
@@ -511,6 +753,12 @@ namespace OpenSim.Region.ClientStack.Linden
511 inType = (sbyte)InventoryType.Animation; 753 inType = (sbyte)InventoryType.Animation;
512 assType = (sbyte)AssetType.Animation; 754 assType = (sbyte)AssetType.Animation;
513 } 755 }
756 else if (inventoryType == "animset")
757 {
758 inType = (sbyte)CustomInventoryType.AnimationSet;
759 assType = (sbyte)CustomAssetType.AnimationSet;
760 m_log.Debug("got animset upload request");
761 }
514 else if (inventoryType == "wearable") 762 else if (inventoryType == "wearable")
515 { 763 {
516 inType = (sbyte)InventoryType.Wearable; 764 inType = (sbyte)InventoryType.Wearable;
@@ -526,191 +774,290 @@ namespace OpenSim.Region.ClientStack.Linden
526 } 774 }
527 else if (inventoryType == "object") 775 else if (inventoryType == "object")
528 { 776 {
529 inType = (sbyte)InventoryType.Object; 777 if (assetType == "mesh") // this code for now is for mesh models uploads only
530 assType = (sbyte)AssetType.Object; 778 {
531 779 inType = (sbyte)InventoryType.Object;
532 List<Vector3> positions = new List<Vector3>(); 780 assType = (sbyte)AssetType.Object;
533 List<Quaternion> rotations = new List<Quaternion>();
534 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
535 OSDArray instance_list = (OSDArray)request["instance_list"];
536 OSDArray mesh_list = (OSDArray)request["mesh_list"];
537 OSDArray texture_list = (OSDArray)request["texture_list"];
538 SceneObjectGroup grp = null;
539 781
540 InventoryFolderBase textureUploadFolder = null; 782 List<Vector3> positions = new List<Vector3>();
783 List<Quaternion> rotations = new List<Quaternion>();
784 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
541 785
542 List<InventoryFolderBase> foldersToUpdate = new List<InventoryFolderBase>(); 786 // compare and get updated information
543 List<InventoryItemBase> itemsToUpdate = new List<InventoryItemBase>(); 787/* does nothing still we do need something to avoid special viewer to upload something diferent from the cost estimation
544 IClientInventory clientInv = null; 788 bool mismatchError = true;
545
546 if (texture_list.Count > 0)
547 {
548 ScenePresence avatar = null;
549 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
550 789
551 if (avatar != null) 790 while (mismatchError)
552 { 791 {
553 IClientCore core = (IClientCore)avatar.ControllingClient; 792 mismatchError = false;
793 }
794
795 if (mismatchError)
796 {
797 error = "Upload and fee estimation information don't match";
798 lock (m_ModelCost)
799 m_FileAgentInventoryState = FileAgentInventoryState.idle;
800
801 return;
802 }
803*/
804 OSDArray instance_list = (OSDArray)request["instance_list"];
805 OSDArray mesh_list = (OSDArray)request["mesh_list"];
806 OSDArray texture_list = (OSDArray)request["texture_list"];
807 SceneObjectGroup grp = null;
808
809 // create and store texture assets
810 bool doTextInv = (!istest && m_enableModelUploadTextureToInventory &&
811 texturesFolder != UUID.Zero);
812
813
814 List<UUID> textures = new List<UUID>();
815
816
817// if (doTextInv)
818 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
819
820 if(client == null) // don't put textures in inventory if there is no client
821 doTextInv = false;
554 822
555 if (core.TryGet<IClientInventory>(out clientInv)) 823 for (int i = 0; i < texture_list.Count; i++)
824 {
825 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, creatorIDstr);
826 textureAsset.Data = texture_list[i].AsBinary();
827 if (istest)
828 textureAsset.Local = true;
829 m_assetService.Store(textureAsset);
830 textures.Add(textureAsset.FullID);
831
832 if (doTextInv)
556 { 833 {
557 var systemTextureFolder = m_Scene.InventoryService.GetFolderForType(m_HostCapsObj.AgentID, FolderType.Texture); 834 string name = assetName;
558 textureUploadFolder = new InventoryFolderBase(UUID.Random(), assetName, m_HostCapsObj.AgentID, (short)FolderType.None, systemTextureFolder.ID, 1); 835 if (name.Length > 25)
559 if (m_Scene.InventoryService.AddFolder(textureUploadFolder)) 836 name = name.Substring(0, 24);
560 { 837 name += "_Texture#" + i.ToString();
561 foldersToUpdate.Add(textureUploadFolder); 838 InventoryItemBase texitem = new InventoryItemBase();
839 texitem.Owner = m_HostCapsObj.AgentID;
840 texitem.CreatorId = creatorIDstr;
841 texitem.CreatorData = String.Empty;
842 texitem.ID = UUID.Random();
843 texitem.AssetID = textureAsset.FullID;
844 texitem.Description = "mesh model texture";
845 texitem.Name = name;
846 texitem.AssetType = (int)AssetType.Texture;
847 texitem.InvType = (int)InventoryType.Texture;
848 texitem.Folder = texturesFolder;
849
850 texitem.CurrentPermissions
851 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
852
853 texitem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
854 texitem.EveryOnePermissions = 0;
855 texitem.NextPermissions = (uint)PermissionMask.All;
856 texitem.CreationDate = Util.UnixTimeSinceEpoch();
857
858 m_Scene.AddInventoryItem(client, texitem);
859 texitem = null;
860 }
861 }
562 862
563 m_log.DebugFormat( 863 // create and store meshs assets
564 "[BUNCH OF CAPS]: Created new folder '{0}' ({1}) for textures uploaded with mesh object {2}", 864 List<UUID> meshAssets = new List<UUID>();
565 textureUploadFolder.Name, textureUploadFolder.ID, assetName); 865 List<bool> meshAvatarSkeletons = new List<bool>();
566 } 866 List<bool> meshAvatarColliders = new List<bool>();
567 else 867
868 bool curAvSkeleton;
869 bool curAvCollider;
870 for (int i = 0; i < mesh_list.Count; i++)
871 {
872 curAvSkeleton = false;
873 curAvCollider = false;
874
875 // we do need to parse the mesh now
876 OSD osd = OSDParser.DeserializeLLSDBinary(mesh_list[i]);
877 if (osd is OSDMap)
878 {
879 OSDMap mosd = (OSDMap)osd;
880 if (mosd.ContainsKey("skeleton"))
568 { 881 {
569 textureUploadFolder = null; 882 OSDMap skeleton = (OSDMap)mosd["skeleton"];
883 int sksize = skeleton["size"].AsInteger();
884 if (sksize > 0)
885 curAvSkeleton = true;
570 } 886 }
571 } 887 }
572 }
573 }
574 888
575 List<UUID> textures = new List<UUID>(); 889 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, creatorIDstr);
576 for (int i = 0; i < texture_list.Count; i++) 890 meshAsset.Data = mesh_list[i].AsBinary();
577 { 891 if (istest)
578 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, ""); 892 meshAsset.Local = true;
579 textureAsset.Data = texture_list[i].AsBinary(); 893 m_assetService.Store(meshAsset);
580 m_assetService.Store(textureAsset); 894 meshAssets.Add(meshAsset.FullID);
581 textures.Add(textureAsset.FullID); 895 meshAvatarSkeletons.Add(curAvSkeleton);
896 meshAvatarColliders.Add(curAvCollider);
897
898 // test code
899 if (curAvSkeleton && client != null)
900 {
901 string name = assetName;
902 if (name.Length > 25)
903 name = name.Substring(0, 24);
904 name += "_Mesh#" + i.ToString();
905 InventoryItemBase meshitem = new InventoryItemBase();
906 meshitem.Owner = m_HostCapsObj.AgentID;
907 meshitem.CreatorId = creatorIDstr;
908 meshitem.CreatorData = String.Empty;
909 meshitem.ID = UUID.Random();
910 meshitem.AssetID = meshAsset.FullID;
911 meshitem.Description = "mesh ";
912 meshitem.Name = name;
913 meshitem.AssetType = (int)AssetType.Mesh;
914 meshitem.InvType = (int)InventoryType.Mesh;
915 // meshitem.Folder = UUID.Zero; // send to default
916
917 meshitem.Folder = parentFolder; // dont let it go to folder Meshes that viewers dont show
918
919 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
920 // (owner) permissions. This becomes a problem if next permissions are changed.
921 meshitem.CurrentPermissions
922 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
923
924 meshitem.BasePermissions = (uint)PermissionMask.All;
925 meshitem.EveryOnePermissions = 0;
926 meshitem.NextPermissions = (uint)PermissionMask.All;
927 meshitem.CreationDate = Util.UnixTimeSinceEpoch();
928
929 m_Scene.AddInventoryItem(client, meshitem);
930 meshitem = null;
931 }
932 }
582 933
583 if (textureUploadFolder != null) 934 int skipedMeshs = 0;
935 // build prims from instances
936 for (int i = 0; i < instance_list.Count; i++)
584 { 937 {
585 InventoryItemBase textureItem = new InventoryItemBase(); 938 OSDMap inner_instance_list = (OSDMap)instance_list[i];
586 textureItem.Owner = m_HostCapsObj.AgentID;
587 textureItem.CreatorId = m_HostCapsObj.AgentID.ToString();
588 textureItem.CreatorData = String.Empty;
589 textureItem.ID = UUID.Random();
590 textureItem.AssetID = textureAsset.FullID;
591 textureItem.Description = assetDescription;
592 textureItem.Name = assetName + " - Texture " + (i + 1).ToString();
593 textureItem.AssetType = (int)AssetType.Texture;
594 textureItem.InvType = (int)InventoryType.Texture;
595 textureItem.Folder = textureUploadFolder.ID;
596 textureItem.CurrentPermissions
597 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
598 textureItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
599 textureItem.EveryOnePermissions = 0;
600 textureItem.NextPermissions = (uint)PermissionMask.All;
601 textureItem.CreationDate = Util.UnixTimeSinceEpoch();
602 m_Scene.InventoryService.AddItem(textureItem);
603 itemsToUpdate.Add(textureItem);
604
605 m_log.DebugFormat(
606 "[BUNCH OF CAPS]: Created new inventory item '{0}' ({1}) for texture uploaded with mesh object {2}",
607 textureItem.Name, textureItem.ID, assetName);
608 }
609 }
610 939
611 if (clientInv != null && (foldersToUpdate.Count > 0 || itemsToUpdate.Count > 0)) 940 // skip prims that are 2 small
612 { 941 Vector3 scale = inner_instance_list["scale"].AsVector3();
613 clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray());
614 }
615 942
616 for (int i = 0; i < mesh_list.Count; i++) 943 if (scale.X < m_PrimScaleMin || scale.Y < m_PrimScaleMin || scale.Z < m_PrimScaleMin)
617 { 944 {
618 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); 945 skipedMeshs++;
946 continue;
947 }
619 948
620 Primitive.TextureEntry textureEntry 949 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
621 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
622 OSDMap inner_instance_list = (OSDMap)instance_list[i];
623 950
624 OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; 951 PrimitiveBaseShape pbs = null;
625 for (uint face = 0; face < face_list.Count; face++) 952 if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
626 { 953 {
627 OSDMap faceMap = (OSDMap)face_list[(int)face]; 954 int meshindx = inner_instance_list["mesh"].AsInteger();
628 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); 955 if (meshAssets.Count > meshindx)
629 if(faceMap.ContainsKey("fullbright")) 956 pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]);
630 f.Fullbright = faceMap["fullbright"].AsBoolean(); 957 }
631 if (faceMap.ContainsKey ("diffuse_color")) 958 if(pbs == null) // fallback
632 f.RGBA = faceMap["diffuse_color"].AsColor4(); 959 pbs = PrimitiveBaseShape.CreateBox();
960
961 Primitive.TextureEntry textureEntry
962 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
633 963
634 int textureNum = faceMap["image"].AsInteger(); 964 for (uint face = 0; face < face_list.Count; face++)
635 float imagerot = faceMap["imagerot"].AsInteger(); 965 {
636 float offsets = (float)faceMap["offsets"].AsReal(); 966 OSDMap faceMap = (OSDMap)face_list[(int)face];
637 float offsett = (float)faceMap["offsett"].AsReal();
638 float scales = (float)faceMap["scales"].AsReal();
639 float scalet = (float)faceMap["scalet"].AsReal();
640 967
641 if(imagerot != 0) 968 Primitive.TextureEntryFace f = textureEntry.CreateFace(face); //clone the default
642 f.Rotation = imagerot; 969 if (faceMap.ContainsKey("fullbright"))
970 f.Fullbright = faceMap["fullbright"].AsBoolean();
971 if (faceMap.ContainsKey("diffuse_color"))
972 f.RGBA = faceMap["diffuse_color"].AsColor4();
643 973
644 if(offsets != 0) 974 int textureNum = faceMap["image"].AsInteger();
645 f.OffsetU = offsets; 975 float imagerot = faceMap["imagerot"].AsInteger();
976 float offsets = (float)faceMap["offsets"].AsReal();
977 float offsett = (float)faceMap["offsett"].AsReal();
978 float scales = (float)faceMap["scales"].AsReal();
979 float scalet = (float)faceMap["scalet"].AsReal();
646 980
647 if (offsett != 0) 981 if (imagerot != 0)
648 f.OffsetV = offsett; 982 f.Rotation = imagerot;
649 983
650 if (scales != 0) 984 if (offsets != 0)
651 f.RepeatU = scales; 985 f.OffsetU = offsets;
652 986
653 if (scalet != 0) 987 if (offsett != 0)
654 f.RepeatV = scalet; 988 f.OffsetV = offsett;
655 989
656 if (textures.Count > textureNum) 990 if (scales != 0)
657 f.TextureID = textures[textureNum]; 991 f.RepeatU = scales;
992
993 if (scalet != 0)
994 f.RepeatV = scalet;
995
996 if (textures.Count > textureNum)
997 f.TextureID = textures[textureNum];
998
999 textureEntry.FaceTextures[face] = f;
1000 }
1001 pbs.TextureEntry = textureEntry.GetBytes();
1002
1003 Vector3 position = inner_instance_list["position"].AsVector3();
1004 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
1005
1006 // for now viwers do send fixed defaults
1007 // but this may change
1008// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
1009 byte physicsShapeType = (byte)PhysShapeType.convex; // default is simple convex
1010// int material = inner_instance_list["material"].AsInteger();
1011 byte material = (byte)Material.Wood;
1012
1013 SceneObjectPart prim
1014 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
1015
1016 prim.Scale = scale;
1017 rotations.Add(rotation);
1018 positions.Add(position);
1019 prim.UUID = UUID.Random();
1020 prim.CreatorID = creatorID;
1021 prim.OwnerID = owner_id;
1022 prim.GroupID = UUID.Zero;
1023 prim.LastOwnerID = creatorID;
1024 prim.RezzerID = creatorID;
1025 prim.CreationDate = Util.UnixTimeSinceEpoch();
1026
1027 if (grp == null)
1028 prim.Name = assetName;
658 else 1029 else
659 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; 1030 prim.Name = assetName + "#" + i.ToString();
660 1031
661 textureEntry.FaceTextures[face] = f; 1032 prim.EveryoneMask = 0;
662 } 1033 prim.GroupMask = 0;
663 1034
664 pbs.TextureEntry = textureEntry.GetBytes(); 1035 if (restrictPerms)
665 1036 {
666 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, ""); 1037 prim.BaseMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
667 meshAsset.Data = mesh_list[i].AsBinary(); 1038 prim.OwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify);
668 m_assetService.Store(meshAsset); 1039 prim.NextOwnerMask = 0;
669 1040 }
670 pbs.SculptEntry = true; 1041 else
671 pbs.SculptTexture = meshAsset.FullID; 1042 {
672 pbs.SculptType = (byte)SculptType.Mesh; 1043 prim.BaseMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
673 pbs.SculptData = meshAsset.Data; 1044 prim.OwnerMask = (uint)PermissionMask.All | (uint)PermissionMask.Export;
674 1045 prim.GroupMask = prim.BaseMask & (uint)groupMask;
675 Vector3 position = inner_instance_list["position"].AsVector3(); 1046 prim.EveryoneMask = prim.BaseMask & (uint)everyoneMask;
676 Vector3 scale = inner_instance_list["scale"].AsVector3(); 1047 prim.NextOwnerMask = prim.BaseMask & (uint)nextOwnerMask;
677 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); 1048 // If the viewer gives us bogus permissions, revert to the SL
678 1049 // default of transfer only.
679// no longer used - begin ------------------------ 1050 if ((prim.NextOwnerMask & (uint)PermissionMask.All) == 0)
680// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger(); 1051 prim.NextOwnerMask = (uint)PermissionMask.Transfer;
681// int material = inner_instance_list["material"].AsInteger(); 1052 }
682// int mesh = inner_instance_list["mesh"].AsInteger(); 1053
683 1054 if(istest)
684// OSDMap permissions = (OSDMap)inner_instance_list["permissions"]; 1055 prim.Description = "For testing only. Other uses are prohibited";
685// int base_mask = permissions["base_mask"].AsInteger(); 1056 else
686// int everyone_mask = permissions["everyone_mask"].AsInteger(); 1057 prim.Description = "";
687// UUID creator_id = permissions["creator_id"].AsUUID(); 1058
688// UUID group_id = permissions["group_id"].AsUUID(); 1059 prim.Material = material;
689// int group_mask = permissions["group_mask"].AsInteger(); 1060 prim.PhysicsShapeType = physicsShapeType;
690// bool is_owner_group = permissions["is_owner_group"].AsBoolean();
691// UUID last_owner_id = permissions["last_owner_id"].AsUUID();
692// int next_owner_mask = permissions["next_owner_mask"].AsInteger();
693// UUID owner_id = permissions["owner_id"].AsUUID();
694// int owner_mask = permissions["owner_mask"].AsInteger();
695// no longer used - end ------------------------
696
697 UUID owner_id = m_HostCapsObj.AgentID;
698
699 SceneObjectPart prim
700 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
701
702 prim.Scale = scale;
703 //prim.OffsetPosition = position;
704 rotations.Add(rotation);
705 positions.Add(position);
706 prim.UUID = UUID.Random();
707 prim.CreatorID = owner_id;
708 prim.OwnerID = owner_id;
709 prim.GroupID = UUID.Zero;
710 prim.LastOwnerID = prim.OwnerID;
711 prim.CreationDate = Util.UnixTimeSinceEpoch();
712 prim.Name = assetName;
713 prim.Description = "";
714 1061
715// prim.BaseMask = (uint)base_mask; 1062// prim.BaseMask = (uint)base_mask;
716// prim.EveryoneMask = (uint)everyone_mask; 1063// prim.EveryoneMask = (uint)everyone_mask;
@@ -718,52 +1065,65 @@ namespace OpenSim.Region.ClientStack.Linden
718// prim.NextOwnerMask = (uint)next_owner_mask; 1065// prim.NextOwnerMask = (uint)next_owner_mask;
719// prim.OwnerMask = (uint)owner_mask; 1066// prim.OwnerMask = (uint)owner_mask;
720 1067
721 if (grp == null) 1068 if (grp == null)
722 grp = new SceneObjectGroup(prim); 1069 {
723 else 1070 grp = new SceneObjectGroup(prim);
724 grp.AddPart(prim); 1071 grp.LastOwnerID = creatorID;
725 } 1072 grp.RezzerID = creatorID;
1073 }
1074 else
1075 grp.AddPart(prim);
1076 }
726 1077
727 Vector3 rootPos = positions[0]; 1078 Vector3 rootPos = positions[0];
728 1079
729 if (grp.Parts.Length > 1) 1080 if (grp.Parts.Length > 1)
730 { 1081 {
731 // Fix first link number 1082 // Fix first link number
732 grp.RootPart.LinkNum++; 1083 grp.RootPart.LinkNum++;
733 1084
734 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]); 1085 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
735 Quaternion tmprot; 1086 Quaternion tmprot;
736 Vector3 offset; 1087 Vector3 offset;
737 1088
738 // fix children rotations and positions 1089 // fix children rotations and positions
739 for (int i = 1; i < rotations.Count; i++) 1090 for (int i = 1; i < rotations.Count; i++)
740 { 1091 {
741 tmprot = rotations[i]; 1092 tmprot = rotations[i];
742 tmprot = rootRotConj * tmprot; 1093 tmprot = rootRotConj * tmprot;
743 1094
744 grp.Parts[i].RotationOffset = tmprot; 1095 grp.Parts[i].RotationOffset = tmprot;
745 1096
746 offset = positions[i] - rootPos; 1097 offset = positions[i] - rootPos;
1098
1099 offset *= rootRotConj;
1100 grp.Parts[i].OffsetPosition = offset;
1101 }
747 1102
748 offset *= rootRotConj; 1103 grp.AbsolutePosition = rootPos;
749 grp.Parts[i].OffsetPosition = offset; 1104 grp.UpdateGroupRotationR(rotations[0]);
1105 }
1106 else
1107 {
1108 grp.AbsolutePosition = rootPos;
1109 grp.UpdateGroupRotationR(rotations[0]);
750 } 1110 }
751 1111
752 grp.AbsolutePosition = rootPos; 1112 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
753 grp.UpdateGroupRotationR(rotations[0]);
754 } 1113 }
755 else 1114
1115 else // not a mesh model
756 { 1116 {
757 grp.AbsolutePosition = rootPos; 1117 m_log.ErrorFormat("[CAPS Asset Upload] got unsuported assetType for object upload");
758 grp.UpdateGroupRotationR(rotations[0]); 1118 return;
759 } 1119 }
760
761 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
762 } 1120 }
763 1121
764 AssetBase asset; 1122 AssetBase asset;
765 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString()); 1123 asset = new AssetBase(assetID, assetName, assType, creatorIDstr);
766 asset.Data = data; 1124 asset.Data = data;
1125 if (istest)
1126 asset.Local = true;
767 if (AddNewAsset != null) 1127 if (AddNewAsset != null)
768 AddNewAsset(asset); 1128 AddNewAsset(asset);
769 else if (m_assetService != null) 1129 else if (m_assetService != null)
@@ -771,11 +1131,17 @@ namespace OpenSim.Region.ClientStack.Linden
771 1131
772 InventoryItemBase item = new InventoryItemBase(); 1132 InventoryItemBase item = new InventoryItemBase();
773 item.Owner = m_HostCapsObj.AgentID; 1133 item.Owner = m_HostCapsObj.AgentID;
774 item.CreatorId = m_HostCapsObj.AgentID.ToString(); 1134 item.CreatorId = creatorIDstr;
775 item.CreatorData = String.Empty; 1135 item.CreatorData = String.Empty;
776 item.ID = inventoryItem; 1136 item.ID = inventoryItem;
777 item.AssetID = asset.FullID; 1137 item.AssetID = asset.FullID;
778 item.Description = assetDescription; 1138 if (istest)
1139 {
1140 item.Description = "For testing only. Other uses are prohibited";
1141 item.Flags = (uint) (InventoryItemFlags.SharedSingleReference);
1142 }
1143 else
1144 item.Description = assetDescription;
779 item.Name = assetName; 1145 item.Name = assetName;
780 item.AssetType = assType; 1146 item.AssetType = assType;
781 item.InvType = inType; 1147 item.InvType = inType;
@@ -783,18 +1149,69 @@ namespace OpenSim.Region.ClientStack.Linden
783 1149
784 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current 1150 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
785 // (owner) permissions. This becomes a problem if next permissions are changed. 1151 // (owner) permissions. This becomes a problem if next permissions are changed.
786 item.CurrentPermissions
787 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
788 1152
789 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export; 1153 if (inType == (sbyte)CustomInventoryType.AnimationSet)
790 item.EveryOnePermissions = 0; 1154 {
791 item.NextPermissions = (uint)PermissionMask.All; 1155 AnimationSet.setCreateItemPermitions(item);
1156 }
1157
1158 else if (restrictPerms)
1159 {
1160 item.BasePermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1161 item.CurrentPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify);
1162 item.GroupPermissions = 0;
1163 item.EveryOnePermissions = 0;
1164 item.NextPermissions = 0;
1165 }
1166 else
1167 {
1168 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1169 item.CurrentPermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
1170 item.GroupPermissions = item.BasePermissions & (uint)groupMask;
1171 item.EveryOnePermissions = item.BasePermissions & (uint)everyoneMask;
1172 item.NextPermissions = item.BasePermissions & (uint)nextOwnerMask;
1173 if ((item.NextPermissions & (uint)PermissionMask.All) == 0)
1174 item.NextPermissions = (uint)PermissionMask.Transfer;
1175 }
1176
792 item.CreationDate = Util.UnixTimeSinceEpoch(); 1177 item.CreationDate = Util.UnixTimeSinceEpoch();
793 1178
1179 everyoneMask = (int)item.EveryOnePermissions;
1180 groupMask = (int)item.GroupPermissions;
1181 nextOwnerMask = (int)item.NextPermissions;
1182
1183 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
1184
794 if (AddNewInventoryItem != null) 1185 if (AddNewInventoryItem != null)
795 { 1186 {
796 AddNewInventoryItem(m_HostCapsObj.AgentID, item); 1187 if (istest)
1188 {
1189 m_Scene.AddInventoryItem(client, item);
1190/*
1191 AddNewInventoryItem(m_HostCapsObj.AgentID, item, 0);
1192 if (client != null)
1193 client.SendAgentAlertMessage("Upload will have no cost, for personal test purposes only. Other uses are forbiden. Items may not work on a another region" , true);
1194 */
1195 }
1196 else
1197 {
1198 AddNewInventoryItem(m_HostCapsObj.AgentID, item, (uint)cost);
1199// if (client != null)
1200// {
1201// // let users see anything.. i don't so far
1202// string str;
1203// if (cost > 0)
1204// // dont remember where is money unit name to put here
1205// str = "Upload complete. charged " + cost.ToString() + "$";
1206// else
1207// str = "Upload complete";
1208// client.SendAgentAlertMessage(str, true);
1209// }
1210 }
797 } 1211 }
1212
1213 lock (m_ModelCost)
1214 m_FileAgentInventoryState = FileAgentInventoryState.idle;
798 } 1215 }
799 1216
800 /// <summary> 1217 /// <summary>
@@ -857,24 +1274,22 @@ namespace OpenSim.Region.ClientStack.Linden
857 LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); 1274 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
858 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest); 1275 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
859 1276
860 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath; 1277 string uploaderPath = GetNewCapPath();
861 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
862 1278
863 ItemUpdater uploader = 1279 ItemUpdater uploader =
864 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 1280 new ItemUpdater(llsdRequest.item_id, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
865 uploader.OnUpLoad += ItemUpdated; 1281 uploader.OnUpLoad += ItemUpdated;
866 1282
867 m_HostCapsObj.HttpListener.AddStreamHandler( 1283 m_HostCapsObj.HttpListener.AddStreamHandler(
868 new BinaryStreamHandler( 1284 new BinaryStreamHandler(
869 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null)); 1285 "POST", uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
870 1286
871 string protocol = "http://"; 1287 string protocol = "http://";
872 1288
873 if (m_HostCapsObj.SSLCaps) 1289 if (m_HostCapsObj.SSLCaps)
874 protocol = "https://"; 1290 protocol = "https://";
875 1291
876 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 1292 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + uploaderPath;
877 uploaderPath;
878 1293
879 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 1294 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
880 uploadResponse.uploader = uploaderURL; 1295 uploadResponse.uploader = uploaderURL;
@@ -930,29 +1345,22 @@ namespace OpenSim.Region.ClientStack.Linden
930 IClientAPI client = null; 1345 IClientAPI client = null;
931 1346
932 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client); 1347 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
933 item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID)); 1348 item = m_Scene.InventoryService.GetItem(m_HostCapsObj.AgentID, itemID);
934 if (item != null) 1349 if (item != null)
935 { 1350 {
936 string message; 1351 string message;
937 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID, out message); 1352 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID, out message);
938 if (client != null) 1353 if (copyItem != null && client != null)
939 { 1354 {
940 if (copyItem != null) 1355 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
941 { 1356 client.SendBulkUpdateInventory(copyItem);
942 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
943 client.SendBulkUpdateInventory(copyItem);
944 }
945 else
946 {
947 client.SendAgentAlertMessage(message, false);
948 }
949 } 1357 }
950 } 1358 }
951 else 1359 else
952 { 1360 {
953 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID); 1361 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
954 if (client != null) 1362 if (client != null)
955 client.SendAgentAlertMessage("Failed to retrieve item", false); 1363 client.SendAlertMessage("Failed to retrieve item");
956 } 1364 }
957 } 1365 }
958 catch (Exception e) 1366 catch (Exception e)
@@ -995,26 +1403,483 @@ namespace OpenSim.Region.ClientStack.Linden
995 return response; 1403 return response;
996 } 1404 }
997 1405
998 public string UpdateAgentInformation(string request, string path, 1406 public string GetObjectCost(string request, string path,
999 string param, IOSHttpRequest httpRequest, 1407 string param, IOSHttpRequest httpRequest,
1000 IOSHttpResponse httpResponse) 1408 IOSHttpResponse httpResponse)
1001 { 1409 {
1002 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); 1410 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1003 OSDMap accessPrefs = (OSDMap)req["access_prefs"]; 1411 OSDMap resp = new OSDMap();
1004 string desiredMaturity = accessPrefs["max"]; 1412
1413 OSDArray object_ids = (OSDArray)req["object_ids"];
1414
1415 for (int i = 0; i < object_ids.Count; i++)
1416 {
1417 UUID uuid = object_ids[i].AsUUID();
1418
1419 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1420 SceneObjectGroup grp = null;
1421 if (part != null)
1422 grp = part.ParentGroup;
1423 if (grp != null)
1424 {
1425 float linksetCost;
1426 float linksetPhysCost;
1427 float partCost;
1428 float partPhysCost;
1429
1430 grp.GetResourcesCosts(part,out linksetCost,out linksetPhysCost,out partCost,out partPhysCost);
1431
1432 OSDMap object_data = new OSDMap();
1433 object_data["linked_set_resource_cost"] = linksetCost;
1434 object_data["resource_cost"] = partCost;
1435 object_data["physics_cost"] = partPhysCost;
1436 object_data["linked_set_physics_cost"] = linksetPhysCost;
1437 object_data["resource_limiting_type"] = "legacy";
1438 resp[uuid.ToString()] = object_data;
1439 }
1440 }
1441 if(resp.Count == 0)
1442 {
1443 OSDMap object_data = new OSDMap();
1444 object_data["linked_set_resource_cost"] = 0;
1445 object_data["resource_cost"] = 0;
1446 object_data["physics_cost"] = 0;
1447 object_data["linked_set_physics_cost"] = 0;
1448 resp[UUID.Zero.ToString()] = object_data;
1449 }
1450 string response = OSDParser.SerializeLLSDXmlString(resp);
1451 return response;
1452 }
1453
1454 public string ResourceCostSelected(string request, string path,
1455 string param, IOSHttpRequest httpRequest,
1456 IOSHttpResponse httpResponse)
1457 {
1458 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1459 OSDMap resp = new OSDMap();
1460
1461
1462 float phys=0;
1463 float stream=0;
1464 float simul=0;
1465
1466 if (req.ContainsKey("selected_roots"))
1467 {
1468 OSDArray object_ids = (OSDArray)req["selected_roots"];
1469
1470 // should go by SOG suming costs for all parts
1471 // ll v3 works ok with several objects select we get the list and adds ok
1472 // FS calls per object so results are wrong guess fs bug
1473 for (int i = 0; i < object_ids.Count; i++)
1474 {
1475 UUID uuid = object_ids[i].AsUUID();
1476 float Physc;
1477 float simulc;
1478 float streamc;
1479
1480 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
1481 if (grp != null)
1482 {
1483 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
1484 phys += Physc;
1485 stream += streamc;
1486 simul += simulc;
1487 }
1488 }
1489 }
1490 else if (req.ContainsKey("selected_prims"))
1491 {
1492 OSDArray object_ids = (OSDArray)req["selected_prims"];
1493
1494 // don't see in use in any of the 2 viewers
1495 // guess it should be for edit linked but... nothing
1496 // should go to SOP per part
1497 for (int i = 0; i < object_ids.Count; i++)
1498 {
1499 UUID uuid = object_ids[i].AsUUID();
1500
1501 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
1502 if (part != null)
1503 {
1504 phys += part.PhysicsCost;
1505 stream += part.StreamingCost;
1506 simul += part.SimulationCost;
1507 }
1508 }
1509 }
1510
1511 OSDMap object_data = new OSDMap();
1512
1513 object_data["physics"] = phys;
1514 object_data["streaming"] = stream;
1515 object_data["simulation"] = simul;
1516
1517 resp["selected"] = object_data;
1518// resp["transaction_id"] = "undef";
1519 string response = OSDParser.SerializeLLSDXmlString(resp);
1520 return response;
1521 }
1005 1522
1523 public string UpdateAgentInformation(string request, string path,
1524 string param, IOSHttpRequest httpRequest,
1525 IOSHttpResponse httpResponse)
1526 {
1527// OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1006 OSDMap resp = new OSDMap(); 1528 OSDMap resp = new OSDMap();
1007 OSDMap respAccessPrefs = new OSDMap(); 1529
1008 respAccessPrefs["max"] = desiredMaturity; // echoing the maturity back means success 1530 OSDMap accessPrefs = new OSDMap();
1009 resp["access_prefs"] = respAccessPrefs; 1531 accessPrefs["max"] = "A";
1532
1533 resp["access_prefs"] = accessPrefs;
1010 1534
1011 string response = OSDParser.SerializeLLSDXmlString(resp); 1535 string response = OSDParser.SerializeLLSDXmlString(resp);
1012 return response; 1536 return response;
1537 }
1538
1539 public bool OSDMapTOVector3(OSDMap map, out Vector3 v)
1540 {
1541 v = Vector3.Zero;
1542 if(!map.ContainsKey("X"))
1543 return false;
1544 if(!map.ContainsKey("Y"))
1545 return false;
1546 if(!map.ContainsKey("Z"))
1547 return false;
1548 v.X = (float)map["X"].AsReal();
1549 v.Y = (float)map["Y"].AsReal();
1550 v.Z = (float)map["Z"].AsReal();
1551 return true;
1552 }
1553
1554 public string HomeLocation(string request, string path, string param, IOSHttpRequest httpRequest,
1555 IOSHttpResponse httpResponse)
1556 {
1557 OSDMap resp = new OSDMap();
1558
1559 resp["success"] = "false";
1560
1561
1562 bool fail = true;
1563 string message = "Set Home request failed";
1564 int locationID = 1;
1565 Vector3 pos = Vector3.Zero;
1566 Vector3 lookAt = Vector3.Zero;
1567
1568 IClientAPI client = null;
1569 ScenePresence sp;
1570
1571 while(true)
1572 {
1573 if(m_Scene.GridUserService == null)
1574 break;
1575
1576 if(m_Scene.UserManagementModule == null)
1577 break;
1578
1579 m_Scene.TryGetScenePresence(m_AgentID, out sp);
1580 if(sp == null || sp.IsChildAgent || sp.IsDeleted)
1581 break;
1582
1583 if(sp.IsInTransit && !sp.IsInLocalTransit)
1584 break;
1585
1586 client = sp.ControllingClient;
1587
1588 if(!m_Scene.UserManagementModule.IsLocalGridUser(m_AgentID))
1589 break;
1590
1591 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1592 if(!req.ContainsKey("HomeLocation"))
1593 break;
1594
1595 OSDMap HLocation = (OSDMap)req["HomeLocation"];
1596 if(!HLocation.ContainsKey("LocationPos"))
1597 break;
1598 if(!HLocation.ContainsKey("LocationLookAt"))
1599 break;
1600
1601 locationID = HLocation["LocationId"].AsInteger();
1602
1603 if(!OSDMapTOVector3((OSDMap)HLocation["LocationPos"], out pos))
1604 break;
1605
1606 if(!OSDMapTOVector3((OSDMap)HLocation["LocationLookAt"], out lookAt))
1607 break;
1608
1609 ILandObject land = m_Scene.LandChannel.GetLandObject(pos);
1610 if(land == null)
1611 break;
1612
1613 ulong gpowers = client.GetGroupPowers(land.LandData.GroupID);
1614 SceneObjectGroup telehub = null;
1615 if (m_Scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero)
1616 // Does the telehub exist in the scene?
1617 telehub = m_Scene.GetSceneObjectGroup(m_Scene.RegionInfo.RegionSettings.TelehubObject);
1618
1619 if (!m_Scene.Permissions.IsAdministrator(m_AgentID) && // (a) gods and land managers can set home
1620 !m_Scene.Permissions.IsGod(m_AgentID) &&
1621 m_AgentID != land.LandData.OwnerID && // (b) land owners can set home
1622 // (c) members of the land-associated group in roles that can set home
1623 ((gpowers & (ulong)GroupPowers.AllowSetHome) != (ulong)GroupPowers.AllowSetHome) &&
1624 // (d) parcels with telehubs can be the home of anyone
1625 (telehub == null || !land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y)))
1626 {
1627 message = "You are not allowed to set your home location in this parcel.";
1628 break;
1629 }
1630
1631 string userId;
1632 UUID test;
1633 if (!m_Scene.UserManagementModule.GetUserUUI(m_AgentID, out userId))
1634 {
1635 message = "Set Home request failed. (User Lookup)";
1636 break;
1637 }
1638
1639 if (!UUID.TryParse(userId, out test))
1640 {
1641 message = "Set Home request failed. (HG visitor)";
1642 break;
1643 }
1644
1645 if (m_Scene.GridUserService.SetHome(userId, land.RegionUUID, pos, lookAt))
1646 fail = false;
1647
1648 break;
1649 }
1650
1651 string response;
1652
1653 if(fail)
1654 {
1655 if(client != null)
1656 client.SendAlertMessage(message);
1657 response = OSDParser.SerializeLLSDXmlString(resp);
1658 return response;
1659 }
1660
1661 // so its http but still needs a udp reply to inform user? crap :p
1662 if(client != null)
1663 client.SendAlertMessage("Home position set.","HomePositionSet");
1664
1665 resp["success"] = "true";
1666 OSDMap homeloc = new OSDMap();
1667 OSDMap homelocpos = new OSDMap();
1668 // for some odd reason viewers send pos as reals but read as integer
1669 homelocpos["X"] = new OSDReal(pos.X);
1670 homelocpos["Y"] = new OSDReal(pos.Y);
1671 homelocpos["Z"] = new OSDReal(pos.Z);
1672 homeloc["LocationPos"] = homelocpos;
1673
1674 resp["HomeLocation"] = homeloc;
1675
1676 response = OSDParser.SerializeLLSDXmlString(resp);
1677 return response;
1678 }
1679
1680 private static int CompareRolesByMembersDesc(GroupRolesData x, GroupRolesData y)
1681 {
1682 return -(x.Members.CompareTo(y.Members));
1683 }
1684
1685 public string GroupMemberData(string request, string path, string param, IOSHttpRequest httpRequest,
1686 IOSHttpResponse httpResponse)
1687 {
1688 OSDMap resp = new OSDMap();
1689
1690 string response;
1691
1692 bool fail = true;
1693 IClientAPI client = null;
1694 ScenePresence sp;
1695 IGroupsModule m_GroupsModule;
1696 UUID groupID = UUID.Zero;
1697
1698 while(true)
1699 {
1700 m_GroupsModule = m_Scene.RequestModuleInterface<IGroupsModule>();
1701 if(m_GroupsModule == null)
1702 break;
1703
1704 m_Scene.TryGetScenePresence(m_AgentID, out sp);
1705 if(sp == null || sp.IsChildAgent || sp.IsDeleted)
1706 break;
1707
1708 if(sp.IsInTransit && !sp.IsInLocalTransit)
1709 break;
1710
1711 client = sp.ControllingClient;
1712
1713 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1714 if(!req.ContainsKey("group_id"))
1715 break;
1716
1717 groupID = req["group_id"].AsUUID();
1718 if(groupID == UUID.Zero)
1719 break;
1720
1721 List<GroupRolesData> roles = m_GroupsModule.GroupRoleDataRequest(client, groupID);
1722 if(roles == null || roles.Count == 0)
1723 break;
1724
1725 List<GroupMembersData> members = m_GroupsModule.GroupMembersRequest(client, groupID);
1726 if(members == null || members.Count == 0)
1727 break;
1728
1729 int memberCount = members.Count;
1730
1731 Dictionary<string,int> titles = new Dictionary<string,int>();
1732 int i = 0;
1733
1734 ulong defaultPowers = 0;
1735
1736
1737 // build titles array and index
1738 roles.Sort(CompareRolesByMembersDesc);
1739
1740 OSDArray osdtitles = new OSDArray();
1741 foreach(GroupRolesData grd in roles)
1742 {
1743 if(grd.Title == null)
1744 continue;
1745 string title = grd.Title;
1746 if(i==0)
1747 defaultPowers = grd.Powers;
1748
1749 if(!titles.ContainsKey(title))
1750 {
1751 titles[title] = i++;
1752 osdtitles.Add(new OSDString(title));
1753 }
1754 }
1755
1756 if(titles.Count == 0)
1757 break;
1758
1759 OSDMap osdmembers = new OSDMap();
1760 foreach(GroupMembersData gmd in members)
1761 {
1762 OSDMap m = new OSDMap();
1763 if(gmd.OnlineStatus != null && gmd.OnlineStatus != "")
1764 m["last_login"] = new OSDString(gmd.OnlineStatus);
1765 if(gmd.AgentPowers != defaultPowers)
1766 m["powers"] = new OSDString((gmd.AgentPowers).ToString("X"));
1767 if(gmd.Title != null && titles.ContainsKey(gmd.Title) && titles[gmd.Title] != 0)
1768 m["title"] = new OSDInteger(titles[gmd.Title]);
1769 if(gmd.IsOwner)
1770 m["owner"] = new OSDString("true");
1771 if(gmd.Contribution != 0)
1772 m["donated_square_meters"] = new OSDInteger(gmd.Contribution);
1773
1774 osdmembers[(gmd.AgentID).ToString()] = m;
1775 }
1776
1777 OSDMap osddefaults = new OSDMap();
1778 osddefaults["default_powers"] = new OSDString(defaultPowers.ToString("X"));
1779
1780 resp["group_id"] = new OSDUUID(groupID);
1781 resp["agent_id"] = new OSDUUID(m_AgentID);
1782 resp["member_count"] = new OSDInteger(memberCount);
1783 resp["defaults"] = osddefaults;
1784 resp["titles"] = osdtitles;
1785 resp["members"] = osdmembers;
1786
1787 fail = false;
1788 break;
1789 }
1790
1791 if(fail)
1792 {
1793 resp["group_id"] = new OSDUUID(groupID);
1794 resp["agent_id"] = new OSDUUID(m_AgentID);
1795 resp["member_count"] = new OSDInteger(0);
1796 resp["defaults"] = new OSDMap();
1797 resp["titles"] = new OSDArray();
1798 resp["members"] = new OSDMap();
1799 }
1800
1801 response = OSDParser.SerializeLLSDXmlString(resp);
1802 return response;
1803 }
1804
1805 public string GetDisplayNames(string request, string path,
1806 string param, IOSHttpRequest httpRequest,
1807 IOSHttpResponse httpResponse)
1808 {
1809 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.Gone;
1810 httpResponse.ContentType = "text/plain";
1811
1812 ScenePresence sp = m_Scene.GetScenePresence(m_AgentID);
1813 if(sp == null || sp.IsDeleted)
1814 return "";
1815
1816 if(sp.IsInTransit && !sp.IsInLocalTransit)
1817 {
1818 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable;
1819 httpResponse.AddHeader("Retry-After","30");
1820 return "";
1821 }
1822
1823 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
1824 string[] ids = query.GetValues("ids");
1825
1826 Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids);
1827
1828 OSDMap osdReply = new OSDMap();
1829 OSDArray agents = new OSDArray();
1830
1831 osdReply["agents"] = agents;
1832 foreach (KeyValuePair<UUID,string> kvp in names)
1833 {
1834 if (string.IsNullOrEmpty(kvp.Value))
1835 continue;
1836 if(kvp.Key == UUID.Zero)
1837 continue;
1838
1839 string[] parts = kvp.Value.Split(new char[] {' '});
1840 OSDMap osdname = new OSDMap();
1841
1842 // dont tell about unknown users, we can't send them back on Bad either
1843 if(parts[0] == "Unknown")
1844 continue;
1845/*
1846 if(parts[0] == "Unknown")
1847 {
1848 osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
1849 osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
1850 }
1851 else
1852*/
1853 {
1854 osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
1855 osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));
1856 }
1857 osdname["display_name"] = OSD.FromString(kvp.Value);
1858 osdname["legacy_first_name"] = parts[0];
1859 osdname["legacy_last_name"] = parts[1];
1860 osdname["username"] = OSD.FromString(kvp.Value);
1861 osdname["id"] = OSD.FromUUID(kvp.Key);
1862 osdname["is_display_name_default"] = OSD.FromBoolean(true);
1863
1864 agents.Add(osdname);
1865 }
1866
1867 // Full content request
1868 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
1869 //httpResponse.ContentLength = ??;
1870 httpResponse.ContentType = "application/llsd+xml";
1871
1872 string reply = OSDParser.SerializeLLSDXmlString(osdReply);
1873 return reply;
1013 } 1874 }
1014 } 1875 }
1015 1876
1016 public class AssetUploader 1877 public class AssetUploader
1017 { 1878 {
1879 private static readonly ILog m_log =
1880 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1881
1882
1018 public event UpLoadedAsset OnUpLoad; 1883 public event UpLoadedAsset OnUpLoad;
1019 private UpLoadedAsset handlerUpLoad = null; 1884 private UpLoadedAsset handlerUpLoad = null;
1020 1885
@@ -1029,10 +1894,26 @@ namespace OpenSim.Region.ClientStack.Linden
1029 1894
1030 private string m_invType = String.Empty; 1895 private string m_invType = String.Empty;
1031 private string m_assetType = String.Empty; 1896 private string m_assetType = String.Empty;
1897 private int m_cost;
1898 private string m_error = String.Empty;
1899
1900 private Timer m_timeoutTimer = new Timer();
1901 private UUID m_texturesFolder;
1902 private int m_nreqtextures;
1903 private int m_nreqmeshs;
1904 private int m_nreqinstances;
1905 private bool m_IsAtestUpload;
1906
1907 private int m_nextOwnerMask;
1908 private int m_groupMask;
1909 private int m_everyoneMask;
1910
1032 1911
1033 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1912 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1034 UUID parentFolderID, string invType, string assetType, string path, 1913 UUID parentFolderID, string invType, string assetType, string path,
1035 IHttpServer httpServer, bool dumpAssetsToFile) 1914 IHttpServer httpServer, bool dumpAssetsToFile,
1915 int totalCost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
1916 bool IsAtestUpload, int nextOwnerMask, int groupMask, int everyoneMask)
1036 { 1917 {
1037 m_assetName = assetName; 1918 m_assetName = assetName;
1038 m_assetDes = description; 1919 m_assetDes = description;
@@ -1044,6 +1925,22 @@ namespace OpenSim.Region.ClientStack.Linden
1044 m_assetType = assetType; 1925 m_assetType = assetType;
1045 m_invType = invType; 1926 m_invType = invType;
1046 m_dumpAssetsToFile = dumpAssetsToFile; 1927 m_dumpAssetsToFile = dumpAssetsToFile;
1928 m_cost = totalCost;
1929
1930 m_texturesFolder = texturesFolder;
1931 m_nreqtextures = nreqtextures;
1932 m_nreqmeshs = nreqmeshs;
1933 m_nreqinstances = nreqinstances;
1934 m_IsAtestUpload = IsAtestUpload;
1935
1936 m_timeoutTimer.Elapsed += TimedOut;
1937 m_timeoutTimer.Interval = 120000;
1938 m_timeoutTimer.AutoReset = false;
1939 m_timeoutTimer.Start();
1940
1941 m_nextOwnerMask = nextOwnerMask;
1942 m_groupMask = groupMask;
1943 m_everyoneMask = everyoneMask;
1047 } 1944 }
1048 1945
1049 /// <summary> 1946 /// <summary>
@@ -1058,12 +1955,14 @@ namespace OpenSim.Region.ClientStack.Linden
1058 UUID inv = inventoryItemID; 1955 UUID inv = inventoryItemID;
1059 string res = String.Empty; 1956 string res = String.Empty;
1060 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); 1957 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1958/*
1061 uploadComplete.new_asset = newAssetID.ToString(); 1959 uploadComplete.new_asset = newAssetID.ToString();
1062 uploadComplete.new_inventory_item = inv; 1960 uploadComplete.new_inventory_item = inv;
1063 uploadComplete.state = "complete"; 1961 uploadComplete.state = "complete";
1064 1962
1065 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1963 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1066 1964*/
1965 m_timeoutTimer.Stop();
1067 httpListener.RemoveStreamHandler("POST", uploaderPath); 1966 httpListener.RemoveStreamHandler("POST", uploaderPath);
1068 1967
1069 // TODO: probably make this a better set of extensions here 1968 // TODO: probably make this a better set of extensions here
@@ -1080,12 +1979,55 @@ namespace OpenSim.Region.ClientStack.Linden
1080 handlerUpLoad = OnUpLoad; 1979 handlerUpLoad = OnUpLoad;
1081 if (handlerUpLoad != null) 1980 if (handlerUpLoad != null)
1082 { 1981 {
1083 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); 1982 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType,
1983 m_cost, m_texturesFolder, m_nreqtextures, m_nreqmeshs, m_nreqinstances, m_IsAtestUpload,
1984 ref m_error, ref m_nextOwnerMask, ref m_groupMask, ref m_everyoneMask);
1084 } 1985 }
1085 1986
1987 uploadComplete.new_next_owner_mask = m_nextOwnerMask;
1988 uploadComplete.new_group_mask = m_groupMask;
1989 uploadComplete.new_everyone_mask = m_everyoneMask;
1990
1991 if (m_IsAtestUpload)
1992 {
1993 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
1994 resperror.message = "Upload SUCESSEFULL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions";
1995 resperror.identifier = inv;
1996
1997 uploadComplete.error = resperror;
1998 uploadComplete.state = "Upload4Testing";
1999 }
2000 else
2001 {
2002 if (m_error == String.Empty)
2003 {
2004 uploadComplete.new_asset = newAssetID.ToString();
2005 uploadComplete.new_inventory_item = inv;
2006 // if (m_texturesFolder != UUID.Zero)
2007 // uploadComplete.new_texture_folder_id = m_texturesFolder;
2008 uploadComplete.state = "complete";
2009 }
2010 else
2011 {
2012 LLSDAssetUploadError resperror = new LLSDAssetUploadError();
2013 resperror.message = m_error;
2014 resperror.identifier = inv;
2015
2016 uploadComplete.error = resperror;
2017 uploadComplete.state = "failed";
2018 }
2019 }
2020
2021 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1086 return res; 2022 return res;
1087 } 2023 }
1088 2024
2025 private void TimedOut(object sender, ElapsedEventArgs args)
2026 {
2027 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
2028 httpListener.RemoveStreamHandler("POST", uploaderPath);
2029 }
2030
1089 ///Left this in and commented in case there are unforseen issues 2031 ///Left this in and commented in case there are unforseen issues
1090 //private void SaveAssetToFile(string filename, byte[] data) 2032 //private void SaveAssetToFile(string filename, byte[] data)
1091 //{ 2033 //{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
index c241075..683c3d5 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden
63 { 63 {
64 } 64 }
65 65
66 public void Close() { } 66 public void Close() { }
67 67
68 public void AddRegion(Scene scene) 68 public void AddRegion(Scene scene)
69 { 69 {
@@ -80,11 +80,11 @@ namespace OpenSim.Region.ClientStack.Linden
80 } 80 }
81 81
82 public void PostInitialise() { } 82 public void PostInitialise() { }
83 #endregion 83 #endregion
84 84
85 private void OnRegisterCaps(UUID agentID, Caps caps) 85 private void OnRegisterCaps(UUID agentID, Caps caps)
86 { 86 {
87 new BunchOfCaps(m_Scene, caps); 87 new BunchOfCaps(m_Scene, agentID, caps);
88 } 88 }
89 89
90 } 90 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
new file mode 100644
index 0000000..eb1ab45
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs
@@ -0,0 +1,746 @@
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
28
29using System;
30using System.IO;
31using System.Collections;
32using System.Collections.Generic;
33using System.Text;
34
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37
38using OpenSim.Framework;
39using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Framework.Capabilities;
42
43using ComponentAce.Compression.Libs.zlib;
44
45using OSDArray = OpenMetaverse.StructuredData.OSDArray;
46using OSDMap = OpenMetaverse.StructuredData.OSDMap;
47
48using Nini.Config;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52 public struct ModelPrimLimits
53 {
54
55 }
56
57 public class ModelCost
58 {
59
60 // upload fee defaults
61 // fees are normalized to 1.0
62 // this parameters scale them to basic cost ( so 1.0 translates to 10 )
63
64 public float ModelMeshCostFactor = 0.0f; // scale total cost relative to basic (excluding textures)
65 public float ModelTextureCostFactor = 1.0f; // scale textures fee to basic.
66 public float ModelMinCostFactor = 0.0f; // 0.5f; // minimum total model free excluding textures
67
68 // itens costs in normalized values
69 // ie will be multiplied by basicCost and factors above
70 public float primCreationCost = 0.002f; // extra cost for each prim creation overhead
71 // weigthed size to normalized cost
72 public float bytecost = 1e-5f;
73
74 // mesh upload fees based on compressed data sizes
75 // several data sections are counted more that once
76 // to promote user optimization
77 // following parameters control how many extra times they are added
78 // to global size.
79 // LOD meshs
80 const float medSizeWth = 1f; // 2x
81 const float lowSizeWth = 1.5f; // 2.5x
82 const float lowestSizeWth = 2f; // 3x
83 // favor potencially physical optimized meshs versus automatic decomposition
84 const float physMeshSizeWth = 6f; // counts 7x
85 const float physHullSizeWth = 8f; // counts 9x
86
87 // stream cost area factors
88 // more or less like SL
89 const float highLodFactor = 17.36f;
90 const float midLodFactor = 277.78f;
91 const float lowLodFactor = 1111.11f;
92
93 // physics cost is below, identical to SL, assuming shape type convex
94 // server cost is below identical to SL assuming non scripted non physical object
95
96 // internal
97 const int bytesPerCoord = 6; // 3 coords, 2 bytes per each
98
99 // control prims dimensions
100 public float PrimScaleMin = 0.001f;
101 public float NonPhysicalPrimScaleMax = 256f;
102 public float PhysicalPrimScaleMax = 10f;
103 public int ObjectLinkedPartsMax = 512;
104
105
106 public ModelCost(Scene scene)
107 {
108 PrimScaleMin = scene.m_minNonphys;
109 NonPhysicalPrimScaleMax = scene.m_maxNonphys;
110 PhysicalPrimScaleMax = scene.m_maxPhys;
111 ObjectLinkedPartsMax = scene.m_linksetCapacity;
112 }
113
114 public void Econfig(IConfig EconomyConfig)
115 {
116 ModelMeshCostFactor = EconomyConfig.GetFloat("MeshModelUploadCostFactor", ModelMeshCostFactor);
117 ModelTextureCostFactor = EconomyConfig.GetFloat("MeshModelUploadTextureCostFactor", ModelTextureCostFactor);
118 ModelMinCostFactor = EconomyConfig.GetFloat("MeshModelMinCostFactor", ModelMinCostFactor);
119 // next 2 are normalized so final cost is afected by modelUploadFactor above and normal cost
120 primCreationCost = EconomyConfig.GetFloat("ModelPrimCreationCost", primCreationCost);
121 bytecost = EconomyConfig.GetFloat("ModelMeshByteCost", bytecost);
122 }
123
124 // storage for a single mesh asset cost parameters
125 private class ameshCostParam
126 {
127 // LOD sizes for size dependent streaming cost
128 public int highLODSize;
129 public int medLODSize;
130 public int lowLODSize;
131 public int lowestLODSize;
132 // normalized fee based on compressed data sizes
133 public float costFee;
134 // physics cost
135 public float physicsCost;
136 }
137
138 // calculates a mesh model costs
139 // returns false on error, with a reason on parameter error
140 // resources input LLSD request
141 // basicCost input region assets upload cost
142 // totalcost returns model total upload fee
143 // meshcostdata returns detailed costs for viewer
144 // avatarSkeleton if mesh includes a avatar skeleton
145 // useAvatarCollider if we should use physics mesh for avatar
146 public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost,
147 LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning)
148 {
149 totalcost = 0;
150 error = string.Empty;
151
152 bool avatarSkeleton = false;
153
154 if (resources == null ||
155 resources.instance_list == null ||
156 resources.instance_list.Array.Count == 0)
157 {
158 error = "missing model information.";
159 return false;
160 }
161
162 int numberInstances = resources.instance_list.Array.Count;
163
164 if (ObjectLinkedPartsMax != 0 && numberInstances > ObjectLinkedPartsMax)
165 {
166 error = "Model would have more than " + ObjectLinkedPartsMax.ToString() + " linked prims";
167 return false;
168 }
169
170 meshcostdata.model_streaming_cost = 0.0;
171 meshcostdata.simulation_cost = 0.0;
172 meshcostdata.physics_cost = 0.0;
173 meshcostdata.resource_cost = 0.0;
174
175 meshcostdata.upload_price_breakdown.mesh_instance = 0;
176 meshcostdata.upload_price_breakdown.mesh_physics = 0;
177 meshcostdata.upload_price_breakdown.mesh_streaming = 0;
178 meshcostdata.upload_price_breakdown.model = 0;
179
180 int itmp;
181
182 // textures cost
183 if (resources.texture_list != null && resources.texture_list.Array.Count > 0)
184 {
185 float textures_cost = (float)(resources.texture_list.Array.Count * basicCost);
186 textures_cost *= ModelTextureCostFactor;
187
188 itmp = (int)(textures_cost + 0.5f); // round
189 meshcostdata.upload_price_breakdown.texture = itmp;
190 totalcost += itmp;
191 }
192
193 // meshs assets cost
194 float meshsfee = 0;
195 int numberMeshs = 0;
196 bool haveMeshs = false;
197
198 bool curskeleton;
199 bool curAvatarPhys;
200
201 List<ameshCostParam> meshsCosts = new List<ameshCostParam>();
202
203 if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0)
204 {
205 numberMeshs = resources.mesh_list.Array.Count;
206
207 for (int i = 0; i < numberMeshs; i++)
208 {
209 ameshCostParam curCost = new ameshCostParam();
210 byte[] data = (byte[])resources.mesh_list.Array[i];
211
212 if (!MeshCost(data, curCost,out curskeleton, out curAvatarPhys, out error))
213 {
214 return false;
215 }
216
217 if (curskeleton)
218 {
219 if (avatarSkeleton)
220 {
221 error = "model can only contain a avatar skeleton";
222 return false;
223 }
224 avatarSkeleton = true;
225 }
226 meshsCosts.Add(curCost);
227 meshsfee += curCost.costFee;
228 }
229 haveMeshs = true;
230 }
231
232 // instances (prims) cost
233
234
235 int mesh;
236 int skipedSmall = 0;
237 for (int i = 0; i < numberInstances; i++)
238 {
239 Hashtable inst = (Hashtable)resources.instance_list.Array[i];
240
241 ArrayList ascale = (ArrayList)inst["scale"];
242 Vector3 scale;
243 double tmp;
244 tmp = (double)ascale[0];
245 scale.X = (float)tmp;
246 tmp = (double)ascale[1];
247 scale.Y = (float)tmp;
248 tmp = (double)ascale[2];
249 scale.Z = (float)tmp;
250
251 if (scale.X < PrimScaleMin || scale.Y < PrimScaleMin || scale.Z < PrimScaleMin)
252 {
253 skipedSmall++;
254 continue;
255 }
256
257 if (scale.X > NonPhysicalPrimScaleMax || scale.Y > NonPhysicalPrimScaleMax || scale.Z > NonPhysicalPrimScaleMax)
258 {
259 error = "Model contains parts with sides larger than " + NonPhysicalPrimScaleMax.ToString() + "m. Please ajust scale";
260 return false;
261 }
262
263 if (haveMeshs && inst.ContainsKey("mesh"))
264 {
265 mesh = (int)inst["mesh"];
266
267 if (mesh >= numberMeshs)
268 {
269 error = "Incoerent model information.";
270 return false;
271 }
272
273 // streamming cost
274
275 float sqdiam = scale.LengthSquared();
276
277 ameshCostParam curCost = meshsCosts[mesh];
278 float mesh_streaming = streamingCost(curCost, sqdiam);
279
280 meshcostdata.model_streaming_cost += mesh_streaming;
281 meshcostdata.physics_cost += curCost.physicsCost;
282 }
283 else // instance as no mesh ??
284 {
285 // to do later if needed
286 meshcostdata.model_streaming_cost += 0.5f;
287 meshcostdata.physics_cost += 1.0f;
288 }
289
290 // assume unscripted and static prim server cost
291 meshcostdata.simulation_cost += 0.5f;
292 // charge for prims creation
293 meshsfee += primCreationCost;
294 }
295
296 if (skipedSmall > 0)
297 {
298 if (skipedSmall > numberInstances / 2)
299 {
300 error = "Model contains too many prims smaller than " + PrimScaleMin.ToString() +
301 "m minimum allowed size. Please check scalling";
302 return false;
303 }
304 else
305 warning += skipedSmall.ToString() + " of the requested " +numberInstances.ToString() +
306 " model prims will not upload because they are smaller than " + PrimScaleMin.ToString() +
307 "m minimum allowed size. Please check scalling ";
308 }
309
310 if (meshcostdata.physics_cost <= meshcostdata.model_streaming_cost)
311 meshcostdata.resource_cost = meshcostdata.model_streaming_cost;
312 else
313 meshcostdata.resource_cost = meshcostdata.physics_cost;
314
315 if (meshcostdata.resource_cost < meshcostdata.simulation_cost)
316 meshcostdata.resource_cost = meshcostdata.simulation_cost;
317
318 // scale cost
319 // at this point a cost of 1.0 whould mean basic cost
320 meshsfee *= ModelMeshCostFactor;
321
322 if (meshsfee < ModelMinCostFactor)
323 meshsfee = ModelMinCostFactor;
324
325 // actually scale it to basic cost
326 meshsfee *= (float)basicCost;
327
328 meshsfee += 0.5f; // rounding
329
330 totalcost += (int)meshsfee;
331
332 // breakdown prices
333 // don't seem to be in use so removed code for now
334
335 return true;
336 }
337
338 // single mesh asset cost
339 private bool MeshCost(byte[] data, ameshCostParam cost,out bool skeleton, out bool avatarPhys, out string error)
340 {
341 cost.highLODSize = 0;
342 cost.medLODSize = 0;
343 cost.lowLODSize = 0;
344 cost.lowestLODSize = 0;
345 cost.physicsCost = 0.0f;
346 cost.costFee = 0.0f;
347
348 error = string.Empty;
349
350 skeleton = false;
351 avatarPhys = false;
352
353 if (data == null || data.Length == 0)
354 {
355 error = "Missing model information.";
356 return false;
357 }
358
359 OSD meshOsd = null;
360 int start = 0;
361
362 error = "Invalid model data";
363
364 using (MemoryStream ms = new MemoryStream(data))
365 {
366 try
367 {
368 OSD osd = OSDParser.DeserializeLLSDBinary(ms);
369 if (osd is OSDMap)
370 meshOsd = (OSDMap)osd;
371 else
372 return false;
373 }
374 catch
375 {
376 return false;
377 }
378 start = (int)ms.Position;
379 }
380
381 OSDMap map = (OSDMap)meshOsd;
382 OSDMap tmpmap;
383
384 int highlod_size = 0;
385 int medlod_size = 0;
386 int lowlod_size = 0;
387 int lowestlod_size = 0;
388 int skin_size = 0;
389
390 int hulls_size = 0;
391 int phys_nhulls;
392 int phys_hullsvertices = 0;
393
394 int physmesh_size = 0;
395 int phys_ntriangles = 0;
396
397 int submesh_offset = -1;
398
399 if (map.ContainsKey("skeleton"))
400 {
401 tmpmap = (OSDMap)map["skeleton"];
402 if (tmpmap.ContainsKey("offset") && tmpmap.ContainsKey("size"))
403 {
404 int sksize = tmpmap["size"].AsInteger();
405 if(sksize > 0)
406 skeleton = true;
407 }
408 }
409
410 if (map.ContainsKey("physics_convex"))
411 {
412 tmpmap = (OSDMap)map["physics_convex"];
413 if (tmpmap.ContainsKey("offset"))
414 submesh_offset = tmpmap["offset"].AsInteger() + start;
415 if (tmpmap.ContainsKey("size"))
416 hulls_size = tmpmap["size"].AsInteger();
417 }
418
419 if (submesh_offset < 0 || hulls_size == 0)
420 {
421 error = "Missing physics_convex block";
422 return false;
423 }
424
425 if (!hulls(data, submesh_offset, hulls_size, out phys_hullsvertices, out phys_nhulls))
426 {
427 error = "Bad physics_convex block";
428 return false;
429 }
430
431 submesh_offset = -1;
432
433 // only look for LOD meshs sizes
434
435 if (map.ContainsKey("high_lod"))
436 {
437 tmpmap = (OSDMap)map["high_lod"];
438 // see at least if there is a offset for this one
439 if (tmpmap.ContainsKey("offset"))
440 submesh_offset = tmpmap["offset"].AsInteger() + start;
441 if (tmpmap.ContainsKey("size"))
442 highlod_size = tmpmap["size"].AsInteger();
443 }
444
445 if (submesh_offset < 0 || highlod_size <= 0)
446 {
447 error = "Missing high_lod block";
448 return false;
449 }
450
451 bool haveprev = true;
452
453 if (map.ContainsKey("medium_lod"))
454 {
455 tmpmap = (OSDMap)map["medium_lod"];
456 if (tmpmap.ContainsKey("size"))
457 medlod_size = tmpmap["size"].AsInteger();
458 else
459 haveprev = false;
460 }
461
462 if (haveprev && map.ContainsKey("low_lod"))
463 {
464 tmpmap = (OSDMap)map["low_lod"];
465 if (tmpmap.ContainsKey("size"))
466 lowlod_size = tmpmap["size"].AsInteger();
467 else
468 haveprev = false;
469 }
470
471 if (haveprev && map.ContainsKey("lowest_lod"))
472 {
473 tmpmap = (OSDMap)map["lowest_lod"];
474 if (tmpmap.ContainsKey("size"))
475 lowestlod_size = tmpmap["size"].AsInteger();
476 }
477
478 if (map.ContainsKey("skin"))
479 {
480 tmpmap = (OSDMap)map["skin"];
481 if (tmpmap.ContainsKey("size"))
482 skin_size = tmpmap["size"].AsInteger();
483 }
484
485 cost.highLODSize = highlod_size;
486 cost.medLODSize = medlod_size;
487 cost.lowLODSize = lowlod_size;
488 cost.lowestLODSize = lowestlod_size;
489
490 submesh_offset = -1;
491
492 tmpmap = null;
493 if(map.ContainsKey("physics_mesh"))
494 tmpmap = (OSDMap)map["physics_mesh"];
495 else if (map.ContainsKey("physics_shape")) // old naming
496 tmpmap = (OSDMap)map["physics_shape"];
497
498 if(tmpmap != null)
499 {
500 if (tmpmap.ContainsKey("offset"))
501 submesh_offset = tmpmap["offset"].AsInteger() + start;
502 if (tmpmap.ContainsKey("size"))
503 physmesh_size = tmpmap["size"].AsInteger();
504
505 if (submesh_offset >= 0 || physmesh_size > 0)
506 {
507
508 if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles))
509 {
510 error = "Model data parsing error";
511 return false;
512 }
513 }
514 }
515
516 // upload is done in convex shape type so only one hull
517 phys_hullsvertices++;
518 cost.physicsCost = 0.04f * phys_hullsvertices;
519
520 float sfee;
521
522 sfee = data.Length; // start with total compressed data size
523
524 // penalize lod meshs that should be more builder optimized
525 sfee += medSizeWth * medlod_size;
526 sfee += lowSizeWth * lowlod_size;
527 sfee += lowestSizeWth * lowlod_size;
528
529 // physics
530 // favor potencial optimized meshs versus automatic decomposition
531 if (physmesh_size != 0)
532 sfee += physMeshSizeWth * (physmesh_size + hulls_size / 4); // reduce cost of mandatory convex hull
533 else
534 sfee += physHullSizeWth * hulls_size;
535
536 // bytes to money
537 sfee *= bytecost;
538
539 cost.costFee = sfee;
540 return true;
541 }
542
543 // parses a LOD or physics mesh component
544 private bool submesh(byte[] data, int offset, int size, out int ntriangles)
545 {
546 ntriangles = 0;
547
548 OSD decodedMeshOsd = new OSD();
549 byte[] meshBytes = new byte[size];
550 System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
551 try
552 {
553 using (MemoryStream inMs = new MemoryStream(meshBytes))
554 {
555 using (MemoryStream outMs = new MemoryStream())
556 {
557 using (ZOutputStream zOut = new ZOutputStream(outMs))
558 {
559 byte[] readBuffer = new byte[4096];
560 int readLen = 0;
561 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
562 {
563 zOut.Write(readBuffer, 0, readLen);
564 }
565 zOut.Flush();
566 outMs.Seek(0, SeekOrigin.Begin);
567
568 byte[] decompressedBuf = outMs.GetBuffer();
569 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
570 }
571 }
572 }
573 }
574 catch
575 {
576 return false;
577 }
578
579 OSDArray decodedMeshOsdArray = null;
580
581 byte[] dummy;
582
583 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
584 foreach (OSD subMeshOsd in decodedMeshOsdArray)
585 {
586 if (subMeshOsd is OSDMap)
587 {
588 OSDMap subtmpmap = (OSDMap)subMeshOsd;
589 if (subtmpmap.ContainsKey("NoGeometry") && ((OSDBoolean)subtmpmap["NoGeometry"]))
590 continue;
591
592 if (!subtmpmap.ContainsKey("Position"))
593 return false;
594
595 if (subtmpmap.ContainsKey("TriangleList"))
596 {
597 dummy = subtmpmap["TriangleList"].AsBinary();
598 ntriangles += dummy.Length / bytesPerCoord;
599 }
600 else
601 return false;
602 }
603 }
604
605 return true;
606 }
607
608 // parses convex hulls component
609 private bool hulls(byte[] data, int offset, int size, out int nvertices, out int nhulls)
610 {
611 nvertices = 0;
612 nhulls = 1;
613
614 OSD decodedMeshOsd = new OSD();
615 byte[] meshBytes = new byte[size];
616 System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
617 try
618 {
619 using (MemoryStream inMs = new MemoryStream(meshBytes))
620 {
621 using (MemoryStream outMs = new MemoryStream())
622 {
623 using (ZOutputStream zOut = new ZOutputStream(outMs))
624 {
625 byte[] readBuffer = new byte[4096];
626 int readLen = 0;
627 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
628 {
629 zOut.Write(readBuffer, 0, readLen);
630 }
631 zOut.Flush();
632 outMs.Seek(0, SeekOrigin.Begin);
633
634 byte[] decompressedBuf = outMs.GetBuffer();
635 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
636 }
637 }
638 }
639 }
640 catch
641 {
642 return false;
643 }
644
645 OSDMap cmap = (OSDMap)decodedMeshOsd;
646 if (cmap == null)
647 return false;
648
649 byte[] dummy;
650
651 // must have one of this
652 if (cmap.ContainsKey("BoundingVerts"))
653 {
654 dummy = cmap["BoundingVerts"].AsBinary();
655 nvertices = dummy.Length / bytesPerCoord;
656 }
657 else
658 return false;
659
660/* upload is done with convex shape type
661 if (cmap.ContainsKey("HullList"))
662 {
663 dummy = cmap["HullList"].AsBinary();
664 nhulls += dummy.Length;
665 }
666
667
668 if (cmap.ContainsKey("Positions"))
669 {
670 dummy = cmap["Positions"].AsBinary();
671 nvertices = dummy.Length / bytesPerCoord;
672 }
673 */
674
675 return true;
676 }
677
678 // returns streaming cost from on mesh LODs sizes in curCost and square of prim size length
679 private float streamingCost(ameshCostParam curCost, float sqdiam)
680 {
681 // compute efective areas
682 float ma = 262144f;
683
684 float mh = sqdiam * highLodFactor;
685 if (mh > ma)
686 mh = ma;
687 float mm = sqdiam * midLodFactor;
688 if (mm > ma)
689 mm = ma;
690
691 float ml = sqdiam * lowLodFactor;
692 if (ml > ma)
693 ml = ma;
694
695 float mlst = ma;
696
697 mlst -= ml;
698 ml -= mm;
699 mm -= mh;
700
701 if (mlst < 1.0f)
702 mlst = 1.0f;
703 if (ml < 1.0f)
704 ml = 1.0f;
705 if (mm < 1.0f)
706 mm = 1.0f;
707 if (mh < 1.0f)
708 mh = 1.0f;
709
710 ma = mlst + ml + mm + mh;
711
712 // get LODs compressed sizes
713 // giving 384 bytes bonus
714 int lst = curCost.lowestLODSize - 384;
715 int l = curCost.lowLODSize - 384;
716 int m = curCost.medLODSize - 384;
717 int h = curCost.highLODSize - 384;
718
719 // use previus higher LOD size on missing ones
720 if (m <= 0)
721 m = h;
722 if (l <= 0)
723 l = m;
724 if (lst <= 0)
725 lst = l;
726
727 // force minumum sizes
728 if (lst < 16)
729 lst = 16;
730 if (l < 16)
731 l = 16;
732 if (m < 16)
733 m = 16;
734 if (h < 16)
735 h = 16;
736
737 // compute cost weighted by relative effective areas
738 float cost = (float)lst * mlst + (float)l * ml + (float)m * mm + (float)h * mh;
739 cost /= ma;
740
741 cost *= 0.004f; // overall tunning parameter
742
743 return cost;
744 }
745 }
746}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 9b9f6a7..7c9a1c4 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -74,13 +74,12 @@ namespace OpenSim.Region.ClientStack.Linden
74 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000); 74 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
75 75
76 protected Scene m_scene; 76 protected Scene m_scene;
77 77
78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>(); 78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
79 79
80 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>(); 80 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
81 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
82 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>(); 81 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
83 82
84 #region INonSharedRegionModule methods 83 #region INonSharedRegionModule methods
85 public virtual void Initialise(IConfigSource config) 84 public virtual void Initialise(IConfigSource config)
86 { 85 {
@@ -171,7 +170,7 @@ namespace OpenSim.Region.ClientStack.Linden
171 foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues) 170 foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues)
172 { 171 {
173 MainConsole.Instance.OutputFormat( 172 MainConsole.Instance.OutputFormat(
174 "For agent {0} there are {1} messages queued for send.", 173 "For agent {0} there are {1} messages queued for send.",
175 kvp.Key, kvp.Value.Count); 174 kvp.Key, kvp.Value.Count);
176 } 175 }
177 } 176 }
@@ -190,7 +189,7 @@ namespace OpenSim.Region.ClientStack.Linden
190 { 189 {
191 if (DebugLevel > 0) 190 if (DebugLevel > 0)
192 m_log.DebugFormat( 191 m_log.DebugFormat(
193 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", 192 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
194 agentId, m_scene.RegionInfo.RegionName); 193 agentId, m_scene.RegionInfo.RegionName);
195 194
196 queues[agentId] = new Queue<OSD>(); 195 queues[agentId] = new Queue<OSD>();
@@ -201,6 +200,7 @@ namespace OpenSim.Region.ClientStack.Linden
201 } 200 }
202 201
203 /// <summary> 202 /// <summary>
203
204 /// May return a null queue 204 /// May return a null queue
205 /// </summary> 205 /// </summary>
206 /// <param name="agentId"></param> 206 /// <param name="agentId"></param>
@@ -231,26 +231,20 @@ namespace OpenSim.Region.ClientStack.Linden
231 lock (queue) 231 lock (queue)
232 queue.Enqueue(ev); 232 queue.Enqueue(ev);
233 } 233 }
234 else if (DebugLevel > 0) 234 else
235 { 235 {
236 ScenePresence sp = m_scene.GetScenePresence(avatarID);
237
238 // This assumes that an NPC should never have a queue.
239 if (sp != null && sp.PresenceType != PresenceType.Npc)
240 {
241 OSDMap evMap = (OSDMap)ev; 236 OSDMap evMap = (OSDMap)ev;
242 m_log.WarnFormat( 237 m_log.WarnFormat(
243 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}", 238 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}",
244 sp.Name, sp.UUID, evMap["message"], m_scene.Name); 239 avatarID, evMap["message"], m_scene.Name);
245 }
246 } 240 }
247 } 241 }
248 catch (NullReferenceException e) 242 catch (NullReferenceException e)
249 { 243 {
250 m_log.Error("[EVENTQUEUE] Caught exception: " + e); 244 m_log.Error("[EVENTQUEUE] Caught exception: " + e);
251 return false; 245 return false;
252 } 246 }
253 247
254 return true; 248 return true;
255 } 249 }
256 250
@@ -263,28 +257,13 @@ namespace OpenSim.Region.ClientStack.Linden
263 lock (queues) 257 lock (queues)
264 queues.Remove(agentID); 258 queues.Remove(agentID);
265 259
266 List<UUID> removeitems = new List<UUID>();
267 lock (m_AvatarQueueUUIDMapping) 260 lock (m_AvatarQueueUUIDMapping)
268 m_AvatarQueueUUIDMapping.Remove(agentID); 261 m_AvatarQueueUUIDMapping.Remove(agentID);
269 262
270 UUID searchval = UUID.Zero; 263 lock (m_ids)
271
272 removeitems.Clear();
273
274 lock (m_QueueUUIDAvatarMapping)
275 { 264 {
276 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys) 265 if (!m_ids.ContainsKey(agentID))
277 { 266 m_ids.Remove(agentID);
278 searchval = m_QueueUUIDAvatarMapping[ky];
279
280 if (searchval == agentID)
281 {
282 removeitems.Add(ky);
283 }
284 }
285
286 foreach (UUID ky in removeitems)
287 m_QueueUUIDAvatarMapping.Remove(ky);
288 } 267 }
289 268
290 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 269 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
@@ -309,55 +288,95 @@ namespace OpenSim.Region.ClientStack.Linden
309 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}", 288 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
310 agentID, caps, m_scene.RegionInfo.RegionName); 289 agentID, caps, m_scene.RegionInfo.RegionName);
311 290
312 // Let's instantiate a Queue for this agent right now
313 TryGetQueue(agentID);
314
315 UUID eventQueueGetUUID; 291 UUID eventQueueGetUUID;
292 Queue<OSD> queue;
293 Random rnd = new Random(Environment.TickCount);
294 int nrnd = rnd.Next(30000000);
295 if (nrnd < 0)
296 nrnd = -nrnd;
316 297
317 lock (m_AvatarQueueUUIDMapping) 298 lock (queues)
318 { 299 {
319 // Reuse open queues. The client does! 300 if (queues.ContainsKey(agentID))
320 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 301 queue = queues[agentID];
302 else
303 queue = null;
304
305 if (queue == null)
321 { 306 {
322 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 307 queue = new Queue<OSD>();
323 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 308 queues[agentID] = queue;
309
310 // push markers to handle old responses still waiting
311 // this will cost at most viewer getting two forced noevents
312 // even being a new queue better be safe
313 queue.Enqueue(null);
314 queue.Enqueue(null); // one should be enough
315
316 lock (m_AvatarQueueUUIDMapping)
317 {
318 eventQueueGetUUID = UUID.Random();
319 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
320 {
321 // oops this should not happen ?
322 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue");
323 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
324 }
325 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
326 }
327 lock (m_ids)
328 {
329 if (!m_ids.ContainsKey(agentID))
330 m_ids.Add(agentID, nrnd);
331 else
332 m_ids[agentID] = nrnd;
333 }
324 } 334 }
325 else 335 else
326 { 336 {
327 eventQueueGetUUID = UUID.Random(); 337 // push markers to handle old responses still waiting
328 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 338 // this will cost at most viewer getting two forced noevents
339 // even being a new queue better be safe
340 queue.Enqueue(null);
341 queue.Enqueue(null); // one should be enough
342
343 // reuse or not to reuse TODO FIX
344 lock (m_AvatarQueueUUIDMapping)
345 {
346 // Reuse open queues. The client does!
347 // Its reuse caps path not queues those are been reused already
348 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
349 {
350 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
351 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
352 }
353 else
354 {
355 eventQueueGetUUID = UUID.Random();
356 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
357 m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
358 }
359 }
360 lock (m_ids)
361 {
362 // change to negative numbers so they are changed at end of sending first marker
363 // old data on a queue may be sent on a response for a new caps
364 // but at least will be sent with coerent IDs
365 if (!m_ids.ContainsKey(agentID))
366 m_ids.Add(agentID, -nrnd); // should not happen
367 else
368 m_ids[agentID] = -m_ids[agentID];
369 }
329 } 370 }
330 } 371 }
331 372
332 lock (m_QueueUUIDAvatarMapping)
333 {
334 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
335 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
336 }
337
338 lock (m_AvatarQueueUUIDMapping)
339 {
340 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
341 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
342 }
343
344 caps.RegisterPollHandler( 373 caps.RegisterPollHandler(
345 "EventQueueGet", 374 "EventQueueGet",
346 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); 375 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
347
348 Random rnd = new Random(Environment.TickCount);
349 lock (m_ids)
350 {
351 if (!m_ids.ContainsKey(agentID))
352 m_ids.Add(agentID, rnd.Next(30000000));
353 }
354 } 376 }
355 377
356 public bool HasEvents(UUID requestID, UUID agentID) 378 public bool HasEvents(UUID requestID, UUID agentID)
357 { 379 {
358 // Don't use this, because of race conditions at agent closing time
359 //Queue<OSD> queue = TryGetQueue(agentID);
360
361 Queue<OSD> queue = GetQueue(agentID); 380 Queue<OSD> queue = GetQueue(agentID);
362 if (queue != null) 381 if (queue != null)
363 lock (queue) 382 lock (queue)
@@ -366,7 +385,8 @@ namespace OpenSim.Region.ClientStack.Linden
366 return queue.Count > 0; 385 return queue.Count > 0;
367 } 386 }
368 387
369 return false; 388 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} unknown agent", agentID);
389 return true;
370 } 390 }
371 391
372 /// <summary> 392 /// <summary>
@@ -383,6 +403,10 @@ namespace OpenSim.Region.ClientStack.Linden
383 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name); 403 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
384 } 404 }
385 } 405 }
406 public void Drop(UUID requestID, UUID pAgentId)
407 {
408 // do nothing for now, hope client close will do it
409 }
386 410
387 public Hashtable GetEvents(UUID requestID, UUID pAgentId) 411 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
388 { 412 {
@@ -395,55 +419,65 @@ namespace OpenSim.Region.ClientStack.Linden
395 return NoEvents(requestID, pAgentId); 419 return NoEvents(requestID, pAgentId);
396 } 420 }
397 421
398 OSD element; 422 OSD element = null;;
423 OSDArray array = new OSDArray();
424 int thisID = 0;
425 bool negativeID = false;
426
399 lock (queue) 427 lock (queue)
400 { 428 {
401 if (queue.Count == 0) 429 if (queue.Count == 0)
402 return NoEvents(requestID, pAgentId); 430 return NoEvents(requestID, pAgentId);
403 element = queue.Dequeue(); // 15s timeout
404 }
405
406 int thisID = 0;
407 lock (m_ids)
408 thisID = m_ids[pAgentId];
409 431
410 OSDArray array = new OSDArray(); 432 lock (m_ids)
411 if (element == null) // didn't have an event in 15s 433 thisID = m_ids[pAgentId];
412 {
413 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
414 array.Add(EventQueueHelper.KeepAliveEvent());
415 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
416 }
417 else
418 {
419 if (DebugLevel > 0)
420 LogOutboundDebugMessage(element, pAgentId);
421 434
422 array.Add(element); 435 if (thisID < 0)
436 {
437 negativeID = true;
438 thisID = -thisID;
439 }
423 440
424 lock (queue) 441 while (queue.Count > 0)
425 { 442 {
426 while (queue.Count > 0) 443 element = queue.Dequeue();
427 { 444 // add elements until a marker is found
428 element = queue.Dequeue(); 445 // so they get into a response
446 if (element == null)
447 break;
448 if (DebugLevel > 0)
449 LogOutboundDebugMessage(element, pAgentId);
450 array.Add(element);
451 thisID++;
452 }
453 }
429 454
430 if (DebugLevel > 0) 455 OSDMap events = null;
431 LogOutboundDebugMessage(element, pAgentId);
432 456
433 array.Add(element); 457 if (array.Count > 0)
434 thisID++; 458 {
435 } 459 events = new OSDMap();
436 } 460 events.Add("events", array);
461 events.Add("id", new OSDInteger(thisID));
437 } 462 }
438 463
439 OSDMap events = new OSDMap(); 464 if (negativeID && element == null)
440 events.Add("events", array); 465 {
466 Random rnd = new Random(Environment.TickCount);
467 thisID = rnd.Next(30000000);
468 if (thisID < 0)
469 thisID = -thisID;
470 }
441 471
442 events.Add("id", new OSDInteger(thisID));
443 lock (m_ids) 472 lock (m_ids)
444 { 473 {
445 m_ids[pAgentId] = thisID + 1; 474 m_ids[pAgentId] = thisID + 1;
446 } 475 }
476
477 // if there where no elements before a marker send a NoEvents
478 if (array.Count == 0)
479 return NoEvents(requestID, pAgentId);
480
447 Hashtable responsedata = new Hashtable(); 481 Hashtable responsedata = new Hashtable();
448 responsedata["int_response_code"] = 200; 482 responsedata["int_response_code"] = 200;
449 responsedata["content_type"] = "application/xml"; 483 responsedata["content_type"] = "application/xml";
@@ -461,266 +495,18 @@ namespace OpenSim.Region.ClientStack.Linden
461 responsedata["content_type"] = "text/plain"; 495 responsedata["content_type"] = "text/plain";
462 responsedata["keepalive"] = false; 496 responsedata["keepalive"] = false;
463 responsedata["reusecontext"] = false; 497 responsedata["reusecontext"] = false;
464 responsedata["str_response_string"] = "Upstream error: "; 498 responsedata["str_response_string"] = "<llsd></llsd>";
465 responsedata["error_status_text"] = "Upstream error:"; 499 responsedata["error_status_text"] = "<llsd></llsd>";
466 responsedata["http_protocol_version"] = "HTTP/1.0"; 500 responsedata["http_protocol_version"] = "HTTP/1.0";
467 return responsedata; 501 return responsedata;
468 } 502 }
469 503/* this is not a event message
470// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
471// {
472// // TODO: this has to be redone to not busy-wait (and block the thread),
473// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
474//
475//// if (m_log.IsDebugEnabled)
476//// {
477//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
478//// foreach (object key in request.Keys)
479//// {
480//// debug += key.ToString() + "=" + request[key].ToString() + " ";
481//// }
482//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
483//// }
484//
485// Queue<OSD> queue = TryGetQueue(agentID);
486// OSD element;
487//
488// lock (queue)
489// element = queue.Dequeue(); // 15s timeout
490//
491// Hashtable responsedata = new Hashtable();
492//
493// int thisID = 0;
494// lock (m_ids)
495// thisID = m_ids[agentID];
496//
497// if (element == null)
498// {
499// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
500// if (thisID == -1) // close-request
501// {
502// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
503// responsedata["int_response_code"] = 404; //501; //410; //404;
504// responsedata["content_type"] = "text/plain";
505// responsedata["keepalive"] = false;
506// responsedata["str_response_string"] = "Closed EQG";
507// return responsedata;
508// }
509// responsedata["int_response_code"] = 502;
510// responsedata["content_type"] = "text/plain";
511// responsedata["keepalive"] = false;
512// responsedata["str_response_string"] = "Upstream error: ";
513// responsedata["error_status_text"] = "Upstream error:";
514// responsedata["http_protocol_version"] = "HTTP/1.0";
515// return responsedata;
516// }
517//
518// OSDArray array = new OSDArray();
519// if (element == null) // didn't have an event in 15s
520// {
521// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
522// array.Add(EventQueueHelper.KeepAliveEvent());
523// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
524// }
525// else
526// {
527// array.Add(element);
528//
529// if (element is OSDMap)
530// {
531// OSDMap ev = (OSDMap)element;
532// m_log.DebugFormat(
533// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
534// ev["message"], m_scene.GetScenePresence(agentID).Name);
535// }
536//
537// lock (queue)
538// {
539// while (queue.Count > 0)
540// {
541// element = queue.Dequeue();
542//
543// if (element is OSDMap)
544// {
545// OSDMap ev = (OSDMap)element;
546// m_log.DebugFormat(
547// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
548// ev["message"], m_scene.GetScenePresence(agentID).Name);
549// }
550//
551// array.Add(element);
552// thisID++;
553// }
554// }
555// }
556//
557// OSDMap events = new OSDMap();
558// events.Add("events", array);
559//
560// events.Add("id", new OSDInteger(thisID));
561// lock (m_ids)
562// {
563// m_ids[agentID] = thisID + 1;
564// }
565//
566// responsedata["int_response_code"] = 200;
567// responsedata["content_type"] = "application/xml";
568// responsedata["keepalive"] = false;
569// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
570//
571// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
572//
573// return responsedata;
574// }
575
576// public Hashtable EventQueuePath2(Hashtable request)
577// {
578// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
579// // pull off the last "/" in the path.
580// Hashtable responsedata = new Hashtable();
581// capuuid = capuuid.Substring(0, capuuid.Length - 1);
582// capuuid = capuuid.Replace("/CAPS/EQG/", "");
583// UUID AvatarID = UUID.Zero;
584// UUID capUUID = UUID.Zero;
585//
586// // parse the path and search for the avatar with it registered
587// if (UUID.TryParse(capuuid, out capUUID))
588// {
589// lock (m_QueueUUIDAvatarMapping)
590// {
591// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
592// {
593// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
594// }
595// }
596//
597// if (AvatarID != UUID.Zero)
598// {
599// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
600// }
601// else
602// {
603// responsedata["int_response_code"] = 404;
604// responsedata["content_type"] = "text/plain";
605// responsedata["keepalive"] = false;
606// responsedata["str_response_string"] = "Not Found";
607// responsedata["error_status_text"] = "Not Found";
608// responsedata["http_protocol_version"] = "HTTP/1.0";
609// return responsedata;
610// // return 404
611// }
612// }
613// else
614// {
615// responsedata["int_response_code"] = 404;
616// responsedata["content_type"] = "text/plain";
617// responsedata["keepalive"] = false;
618// responsedata["str_response_string"] = "Not Found";
619// responsedata["error_status_text"] = "Not Found";
620// responsedata["http_protocol_version"] = "HTTP/1.0";
621// return responsedata;
622// // return 404
623// }
624// }
625
626 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
627 {
628 // This is a fallback element to keep the client from loosing EventQueueGet
629 // Why does CAPS fail sometimes!?
630 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
631 string capuuid = path.Replace("/CAPS/EQG/","");
632 capuuid = capuuid.Substring(0, capuuid.Length - 1);
633
634// UUID AvatarID = UUID.Zero;
635 UUID capUUID = UUID.Zero;
636 if (UUID.TryParse(capuuid, out capUUID))
637 {
638/* Don't remove this yet code cleaners!
639 * Still testing this!
640 *
641 lock (m_QueueUUIDAvatarMapping)
642 {
643 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
644 {
645 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
646 }
647 }
648
649
650 if (AvatarID != UUID.Zero)
651 {
652 // Repair the CAP!
653 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
654 //string capsBase = "/CAPS/EQG/";
655 //caps.RegisterHandler("EventQueueGet",
656 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
657 //delegate(Hashtable m_dhttpMethod)
658 //{
659 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
660 //}));
661 // start new ID sequence.
662 Random rnd = new Random(System.Environment.TickCount);
663 lock (m_ids)
664 {
665 if (!m_ids.ContainsKey(AvatarID))
666 m_ids.Add(AvatarID, rnd.Next(30000000));
667 }
668
669
670 int thisID = 0;
671 lock (m_ids)
672 thisID = m_ids[AvatarID];
673
674 BlockingLLSDQueue queue = GetQueue(AvatarID);
675 OSDArray array = new OSDArray();
676 LLSD element = queue.Dequeue(15000); // 15s timeout
677 if (element == null)
678 {
679
680 array.Add(EventQueueHelper.KeepAliveEvent());
681 }
682 else
683 {
684 array.Add(element);
685 while (queue.Count() > 0)
686 {
687 array.Add(queue.Dequeue(1));
688 thisID++;
689 }
690 }
691 OSDMap events = new OSDMap();
692 events.Add("events", array);
693
694 events.Add("id", new LLSDInteger(thisID));
695
696 lock (m_ids)
697 {
698 m_ids[AvatarID] = thisID + 1;
699 }
700
701 return events;
702 }
703 else
704 {
705 return new LLSD();
706 }
707*
708*/
709 }
710 else
711 {
712 //return new LLSD();
713 }
714
715 return new OSDString("shutdown404!");
716 }
717
718 public void DisableSimulator(ulong handle, UUID avatarID) 504 public void DisableSimulator(ulong handle, UUID avatarID)
719 { 505 {
720 OSD item = EventQueueHelper.DisableSimulator(handle); 506 OSD item = EventQueueHelper.DisableSimulator(handle);
721 Enqueue(item, avatarID); 507 Enqueue(item, avatarID);
722 } 508 }
723 509*/
724 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) 510 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
725 { 511 {
726 if (DebugLevel > 0) 512 if (DebugLevel > 0)
@@ -732,7 +518,7 @@ namespace OpenSim.Region.ClientStack.Linden
732 } 518 }
733 519
734 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, 520 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
735 ulong regionHandle, int regionSizeX, int regionSizeY) 521 ulong regionHandle, int regionSizeX, int regionSizeY)
736 { 522 {
737 if (DebugLevel > 0) 523 if (DebugLevel > 0)
738 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}", 524 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
@@ -742,9 +528,9 @@ namespace OpenSim.Region.ClientStack.Linden
742 Enqueue(item, avatarID); 528 Enqueue(item, avatarID);
743 } 529 }
744 530
745 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess, 531 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
746 IPEndPoint regionExternalEndPoint, 532 IPEndPoint regionExternalEndPoint,
747 uint locationID, uint flags, string capsURL, 533 uint locationID, uint flags, string capsURL,
748 UUID avatarID, int regionSizeX, int regionSizeY) 534 UUID avatarID, int regionSizeX, int regionSizeY)
749 { 535 {
750 if (DebugLevel > 0) 536 if (DebugLevel > 0)
@@ -774,33 +560,40 @@ namespace OpenSim.Region.ClientStack.Linden
774 uint timeStamp, bool offline, int parentEstateID, Vector3 position, 560 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
775 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket) 561 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
776 { 562 {
777 OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog, 563 OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog,
778 timeStamp, offline, parentEstateID, position, ttl, transactionID, 564 timeStamp, offline, parentEstateID, position, ttl, transactionID,
779 fromGroup, binaryBucket); 565 fromGroup, binaryBucket);
780 Enqueue(item, toAgent); 566 Enqueue(item, toAgent);
781 //m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item); 567 //m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item);
782 568
783 } 569 }
784 570
785 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat, 571 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat,
786 bool isModerator, bool textMute) 572 bool isModerator, bool textMute, bool isEnterorLeave)
787 { 573 {
788 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 574 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
789 isModerator, textMute); 575 isModerator, textMute, isEnterorLeave);
790 Enqueue(item, fromAgent); 576 Enqueue(item, toAgent);
791 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 577 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
792 } 578 }
793 579
580 public void ChatterBoxForceClose(UUID toAgent, UUID sessionID, string reason)
581 {
582 OSD item = EventQueueHelper.ChatterBoxForceClose(sessionID, reason);
583
584 Enqueue(item, toAgent);
585 }
586
794 public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID) 587 public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID)
795 { 588 {
796 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage); 589 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage);
797 Enqueue(item, avatarID); 590 Enqueue(item, avatarID);
798 } 591 }
799 592
800 public void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID) 593 public void GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data)
801 { 594 {
802 OSD item = EventQueueHelper.GroupMembership(groupUpdate); 595 OSD item = EventQueueHelper.GroupMembershipData(receiverAgent, data);
803 Enqueue(item, avatarID); 596 Enqueue(item, receiverAgent);
804 } 597 }
805 598
806 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID) 599 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
@@ -827,4 +620,4 @@ namespace OpenSim.Region.ClientStack.Linden
827 Enqueue(item, avatarID); 620 Enqueue(item, avatarID);
828 } 621 }
829 } 622 }
830} \ No newline at end of file 623}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 384af74..461f776 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -32,6 +32,8 @@ using OpenMetaverse.Packets;
32using OpenMetaverse.StructuredData; 32using OpenMetaverse.StructuredData;
33using OpenMetaverse.Messages.Linden; 33using OpenMetaverse.Messages.Linden;
34 34
35using OpenSim.Framework;
36
35namespace OpenSim.Region.ClientStack.Linden 37namespace OpenSim.Region.ClientStack.Linden
36{ 38{
37 public class EventQueueHelper 39 public class EventQueueHelper
@@ -76,9 +78,9 @@ namespace OpenSim.Region.ClientStack.Linden
76 78
77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle))); 79 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes())); 80 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port)); 81 llsdSimInfo.Add("Port", OSD.FromInteger(endPoint.Port));
80 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX)); 82 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
81 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY)); 83 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
82 84
83 OSDArray arr = new OSDArray(1); 85 OSDArray arr = new OSDArray(1);
84 arr.Add(llsdSimInfo); 86 arr.Add(llsdSimInfo);
@@ -88,7 +90,7 @@ namespace OpenSim.Region.ClientStack.Linden
88 90
89 return BuildEvent("EnableSimulator", llsdBody); 91 return BuildEvent("EnableSimulator", llsdBody);
90 } 92 }
91 93/*
92 public static OSD DisableSimulator(ulong handle) 94 public static OSD DisableSimulator(ulong handle)
93 { 95 {
94 //OSDMap llsdSimInfo = new OSDMap(1); 96 //OSDMap llsdSimInfo = new OSDMap(1);
@@ -103,7 +105,7 @@ namespace OpenSim.Region.ClientStack.Linden
103 105
104 return BuildEvent("DisableSimulator", llsdBody); 106 return BuildEvent("DisableSimulator", llsdBody);
105 } 107 }
106 108*/
107 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, 109 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
108 IPEndPoint newRegionExternalEndPoint, 110 IPEndPoint newRegionExternalEndPoint,
109 string capsURL, UUID agentID, UUID sessionID, 111 string capsURL, UUID agentID, UUID sessionID,
@@ -157,6 +159,12 @@ namespace OpenSim.Region.ClientStack.Linden
157 uint locationID, uint flags, string capsURL, UUID agentID, 159 uint locationID, uint flags, string capsURL, UUID agentID,
158 int regionSizeX, int regionSizeY) 160 int regionSizeX, int regionSizeY)
159 { 161 {
162 // not sure why flags get overwritten here
163 if ((flags & (uint)TeleportFlags.IsFlying) != 0)
164 flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying;
165 else
166 flags = (uint)TeleportFlags.ViaLocation;
167
160 OSDMap info = new OSDMap(); 168 OSDMap info = new OSDMap();
161 info.Add("AgentID", OSD.FromUUID(agentID)); 169 info.Add("AgentID", OSD.FromUUID(agentID));
162 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this? 170 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
@@ -165,7 +173,8 @@ namespace OpenSim.Region.ClientStack.Linden
165 info.Add("SimAccess", OSD.FromInteger(simAccess)); 173 info.Add("SimAccess", OSD.FromInteger(simAccess));
166 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes())); 174 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
167 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); 175 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
168 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation 176// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
177 info.Add("TeleportFlags", OSD.FromUInteger(flags));
169 info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX)); 178 info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
170 info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY)); 179 info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
171 180
@@ -185,13 +194,13 @@ namespace OpenSim.Region.ClientStack.Linden
185 script.Add("ItemID", OSD.FromUUID(itemID)); 194 script.Add("ItemID", OSD.FromUUID(itemID));
186 script.Add("Running", OSD.FromBoolean(running)); 195 script.Add("Running", OSD.FromBoolean(running));
187 script.Add("Mono", OSD.FromBoolean(mono)); 196 script.Add("Mono", OSD.FromBoolean(mono));
188 197
189 OSDArray scriptArr = new OSDArray(); 198 OSDArray scriptArr = new OSDArray();
190 scriptArr.Add(script); 199 scriptArr.Add(script);
191 200
192 OSDMap body = new OSDMap(); 201 OSDMap body = new OSDMap();
193 body.Add("Script", scriptArr); 202 body.Add("Script", scriptArr);
194 203
195 return BuildEvent("ScriptRunningReply", body); 204 return BuildEvent("ScriptRunningReply", body);
196 } 205 }
197 206
@@ -204,8 +213,8 @@ namespace OpenSim.Region.ClientStack.Linden
204 {"sim-ip-and-port", new OSDString(simIpAndPort)}, 213 {"sim-ip-and-port", new OSDString(simIpAndPort)},
205 {"seed-capability", new OSDString(seedcap)}, 214 {"seed-capability", new OSDString(seedcap)},
206 {"region-handle", OSD.FromULong(regionHandle)}, 215 {"region-handle", OSD.FromULong(regionHandle)},
207 {"region-size-x", OSD.FromInteger(regionSizeX)}, 216 {"region-size-x", OSD.FromUInteger((uint)regionSizeX)},
208 {"region-size-y", OSD.FromInteger(regionSizeY)} 217 {"region-size-y", OSD.FromUInteger((uint)regionSizeY)}
209 }; 218 };
210 219
211 return BuildEvent("EstablishAgentCommunication", body); 220 return BuildEvent("EstablishAgentCommunication", body);
@@ -234,7 +243,7 @@ namespace OpenSim.Region.ClientStack.Linden
234 { 243 {
235 OSDMap messageParams = new OSDMap(15); 244 OSDMap messageParams = new OSDMap(15);
236 messageParams.Add("type", new OSDInteger((int)dialog)); 245 messageParams.Add("type", new OSDInteger((int)dialog));
237 246
238 OSDArray positionArray = new OSDArray(3); 247 OSDArray positionArray = new OSDArray(3);
239 positionArray.Add(OSD.FromReal(position.X)); 248 positionArray.Add(OSD.FromReal(position.X));
240 positionArray.Add(OSD.FromReal(position.Y)); 249 positionArray.Add(OSD.FromReal(position.Y));
@@ -299,20 +308,29 @@ namespace OpenSim.Region.ClientStack.Linden
299 } 308 }
300 309
301 public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID, 310 public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID,
302 UUID agentID, bool canVoiceChat, bool isModerator, bool textMute) 311 UUID agentID, bool canVoiceChat, bool isModerator, bool textMute, bool isEnterorLeave)
303 { 312 {
304 OSDMap body = new OSDMap(); 313 OSDMap body = new OSDMap();
305 OSDMap agentUpdates = new OSDMap(); 314 OSDMap agentUpdates = new OSDMap();
306 OSDMap infoDetail = new OSDMap(); 315 OSDMap infoDetail = new OSDMap();
307 OSDMap mutes = new OSDMap(); 316 OSDMap mutes = new OSDMap();
308 317
318 // this should be a list of agents and parameters
319 // foreach agent
309 mutes.Add("text", OSD.FromBoolean(textMute)); 320 mutes.Add("text", OSD.FromBoolean(textMute));
310 infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat)); 321 infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat));
311 infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator)); 322 infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator));
312 infoDetail.Add("mutes", mutes); 323 infoDetail.Add("mutes", mutes);
313 OSDMap info = new OSDMap(); 324 OSDMap info = new OSDMap();
314 info.Add("info", infoDetail); 325 info.Add("info", infoDetail);
326 if(isEnterorLeave)
327 info.Add("transition",OSD.FromString("ENTER"));
328 else
329 info.Add("transition",OSD.FromString("LEAVE"));
315 agentUpdates.Add(agentID.ToString(), info); 330 agentUpdates.Add(agentID.ToString(), info);
331
332 // foreach end
333
316 body.Add("agent_updates", agentUpdates); 334 body.Add("agent_updates", agentUpdates);
317 body.Add("session_id", OSD.FromUUID(sessionID)); 335 body.Add("session_id", OSD.FromUUID(sessionID));
318 body.Add("updates", new OSD()); 336 body.Add("updates", new OSD());
@@ -324,40 +342,54 @@ namespace OpenSim.Region.ClientStack.Linden
324 return chatterBoxSessionAgentListUpdates; 342 return chatterBoxSessionAgentListUpdates;
325 } 343 }
326 344
327 public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket) 345 public static OSD ChatterBoxForceClose(UUID sessionID, string reason)
328 { 346 {
329 OSDMap groupUpdate = new OSDMap(); 347 OSDMap body = new OSDMap(2);
330 groupUpdate.Add("message", OSD.FromString("AgentGroupDataUpdate")); 348 body.Add("session_id", new OSDUUID(sessionID));
349 body.Add("reason", new OSDString(reason));
331 350
332 OSDMap body = new OSDMap(); 351 OSDMap chatterBoxForceClose = new OSDMap(2);
333 OSDArray agentData = new OSDArray(); 352 chatterBoxForceClose.Add("message", new OSDString("ForceCloseChatterBoxSession"));
334 OSDMap agentDataMap = new OSDMap(); 353 chatterBoxForceClose.Add("body", body);
335 agentDataMap.Add("AgentID", OSD.FromUUID(groupUpdatePacket.AgentData.AgentID)); 354 return chatterBoxForceClose;
336 agentData.Add(agentDataMap); 355 }
337 body.Add("AgentData", agentData);
338 356
339 OSDArray groupData = new OSDArray(); 357 public static OSD GroupMembershipData(UUID receiverAgent, GroupMembershipData[] data)
358 {
359 OSDArray AgentData = new OSDArray(1);
360 OSDMap AgentDataMap = new OSDMap(1);
361 AgentDataMap.Add("AgentID", OSD.FromUUID(receiverAgent));
362 AgentData.Add(AgentDataMap);
340 363
341 foreach (AgentGroupDataUpdatePacket.GroupDataBlock groupDataBlock in groupUpdatePacket.GroupData) 364 OSDArray GroupData = new OSDArray(data.Length);
365 OSDArray NewGroupData = new OSDArray(data.Length);
366
367 foreach (GroupMembershipData membership in data)
342 { 368 {
343 OSDMap groupDataMap = new OSDMap(); 369 OSDMap GroupDataMap = new OSDMap(6);
344 groupDataMap.Add("ListInProfile", OSD.FromBoolean(false)); 370 OSDMap NewGroupDataMap = new OSDMap(1);
345 groupDataMap.Add("GroupID", OSD.FromUUID(groupDataBlock.GroupID)); 371
346 groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(groupDataBlock.GroupInsigniaID)); 372 GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID));
347 groupDataMap.Add("Contribution", OSD.FromInteger(groupDataBlock.Contribution)); 373 GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers));
348 groupDataMap.Add("GroupPowers", OSD.FromBinary(ulongToByteArray(groupDataBlock.GroupPowers))); 374 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices));
349 groupDataMap.Add("GroupName", OSD.FromString(Utils.BytesToString(groupDataBlock.GroupName))); 375 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture));
350 groupDataMap.Add("AcceptNotices", OSD.FromBoolean(groupDataBlock.AcceptNotices)); 376 GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution));
377 GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName));
378 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile));
379
380 GroupData.Add(GroupDataMap);
381 NewGroupData.Add(NewGroupDataMap);
382 }
351 383
352 groupData.Add(groupDataMap); 384 OSDMap llDataStruct = new OSDMap(3);
385 llDataStruct.Add("AgentData", AgentData);
386 llDataStruct.Add("GroupData", GroupData);
387 llDataStruct.Add("NewGroupData", NewGroupData);
353 388
354 } 389 return BuildEvent("AgentGroupDataUpdate", llDataStruct);
355 body.Add("GroupData", groupData);
356 groupUpdate.Add("body", body);
357 390
358 return groupUpdate;
359 } 391 }
360 392
361 public static OSD PlacesQuery(PlacesReplyPacket PlacesReply) 393 public static OSD PlacesQuery(PlacesReplyPacket PlacesReply)
362 { 394 {
363 OSDMap placesReply = new OSDMap(); 395 OSDMap placesReply = new OSDMap();
@@ -391,7 +423,7 @@ namespace OpenSim.Region.ClientStack.Linden
391 QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID)); 423 QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID));
392 QueryDataMap.Add("ProductSku", OSD.FromInteger(0)); 424 QueryDataMap.Add("ProductSku", OSD.FromInteger(0));
393 QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price)); 425 QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price));
394 426
395 QueryData.Add(QueryDataMap); 427 QueryData.Add(QueryDataMap);
396 } 428 }
397 body.Add("QueryData", QueryData); 429 body.Add("QueryData", QueryData);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index 16a902d..ee3f4f1 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -71,7 +71,6 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
71 71
72 IConfigSource config = new IniConfigSource(); 72 IConfigSource config = new IniConfigSource();
73 config.AddConfig("Startup"); 73 config.AddConfig("Startup");
74 config.Configs["Startup"].Set("EventQueue", "true");
75 74
76 CapabilitiesModule capsModule = new CapabilitiesModule(); 75 CapabilitiesModule capsModule = new CapabilitiesModule();
77 m_eqgMod = new EventQueueGetModule(); 76 m_eqgMod = new EventQueueGetModule();
@@ -126,6 +125,15 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
126 125
127 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); 126 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
128 127
128 // initial queue as null events
129 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
130 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK)
131 {
132 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
133 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK)
134 eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
135 }
136
129 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); 137 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
130 138
131// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); 139// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
@@ -172,7 +180,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
172 TestHelpers.InMethod(); 180 TestHelpers.InMethod();
173// TestHelpers.EnableLogging(); 181// TestHelpers.EnableLogging();
174 182
175 UUID npcId 183 UUID npcId
176 = m_npcMod.CreateNPC( 184 = m_npcMod.CreateNPC(
177 "John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance()); 185 "John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance());
178 186
@@ -187,4 +195,4 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
187 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway)); 195 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
188 } 196 }
189 } 197 }
190} \ No newline at end of file 198}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs
deleted file mode 100644
index 6617bbc..0000000
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs
+++ /dev/null
@@ -1,144 +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.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", Id = "GetDisplayNamesModule")]
55 public class GetDisplayNamesModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 private Scene m_scene;
61 private IUserManagement m_UserManager;
62
63 private bool m_Enabled = false;
64
65 private string m_URL;
66
67 #region ISharedRegionModule Members
68
69 public void Initialise(IConfigSource source)
70 {
71 IConfig config = source.Configs["ClientStack.LindenCaps"];
72 if (config == null)
73 return;
74
75 m_URL = config.GetString("Cap_GetDisplayNames", string.Empty);
76 if (m_URL != string.Empty)
77 m_Enabled = true;
78 }
79
80 public void AddRegion(Scene s)
81 {
82 if (!m_Enabled)
83 return;
84
85 m_scene = s;
86 }
87
88 public void RemoveRegion(Scene s)
89 {
90 if (!m_Enabled)
91 return;
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_UserManager = m_scene.RequestModuleInterface<IUserManagement>();
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 "GetDisplayNamesModule"; } }
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 if (m_URL == "localhost")
126 {
127 m_log.DebugFormat("[GET_DISPLAY_NAMES]: /CAPS/agents/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
128 caps.RegisterHandler(
129 "GetDisplayNames",
130 new GetDisplayNamesHandler("/CAPS/agents" + capID + "/", m_UserManager, "GetDisplayNames", agentID.ToString()));
131 }
132 else
133 {
134// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
135 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
136 if (handler != null)
137 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetDisplayNames", m_URL);
138 else
139 caps.RegisterHandler("GetDisplayNames", m_URL);
140 }
141 }
142
143 }
144}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index f57d857..ba917e39 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -27,11 +27,14 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Collections.Specialized; 31using System.Collections.Specialized;
31using System.Reflection; 32using System.Reflection;
32using System.IO; 33using System.IO;
34using System.Threading;
33using System.Web; 35using System.Web;
34using Mono.Addins; 36using Mono.Addins;
37using OpenSim.Framework.Monitoring;
35using log4net; 38using log4net;
36using Nini.Config; 39using Nini.Config;
37using OpenMetaverse; 40using OpenMetaverse;
@@ -52,15 +55,46 @@ namespace OpenSim.Region.ClientStack.Linden
52 { 55 {
53// private static readonly ILog m_log = 56// private static readonly ILog m_log =
54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 58
56 private Scene m_scene; 59 private Scene m_scene;
57 private IAssetService m_AssetService; 60 private IAssetService m_AssetService;
58 private bool m_Enabled = true; 61 private bool m_Enabled = true;
59 private string m_URL; 62 private string m_URL;
63
60 private string m_URL2; 64 private string m_URL2;
61 private string m_RedirectURL = null; 65 private string m_RedirectURL = null;
62 private string m_RedirectURL2 = null; 66 private string m_RedirectURL2 = null;
63 67
68 struct aPollRequest
69 {
70 public PollServiceMeshEventArgs thepoll;
71 public UUID reqID;
72 public Hashtable request;
73 }
74
75 public class aPollResponse
76 {
77 public Hashtable response;
78 public int bytes;
79 public int lod;
80 }
81
82
83 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
84
85 private static GetMeshHandler m_getMeshHandler;
86
87 private IAssetService m_assetService = null;
88
89 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
90 private static Thread[] m_workerThreads = null;
91 private static int m_NumberScenes = 0;
92 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue =
93 new OpenSim.Framework.BlockingQueue<aPollRequest>();
94
95 private Dictionary<UUID, PollServiceMeshEventArgs> m_pollservices = new Dictionary<UUID, PollServiceMeshEventArgs>();
96
97
64 #region Region Module interfaceBase Members 98 #region Region Module interfaceBase Members
65 99
66 public Type ReplaceableInterface 100 public Type ReplaceableInterface
@@ -87,6 +121,7 @@ namespace OpenSim.Region.ClientStack.Linden
87 if (m_URL2 != string.Empty) 121 if (m_URL2 != string.Empty)
88 { 122 {
89 m_Enabled = true; 123 m_Enabled = true;
124
90 m_RedirectURL2 = config.GetString("GetMesh2RedirectURL"); 125 m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
91 } 126 }
92 } 127 }
@@ -97,6 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
97 return; 132 return;
98 133
99 m_scene = pScene; 134 m_scene = pScene;
135
136 m_assetService = pScene.AssetService;
100 } 137 }
101 138
102 public void RemoveRegion(Scene scene) 139 public void RemoveRegion(Scene scene)
@@ -105,6 +142,9 @@ namespace OpenSim.Region.ClientStack.Linden
105 return; 142 return;
106 143
107 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 144 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
145 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
146 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
147 m_NumberScenes--;
108 m_scene = null; 148 m_scene = null;
109 } 149 }
110 150
@@ -115,55 +155,302 @@ namespace OpenSim.Region.ClientStack.Linden
115 155
116 m_AssetService = m_scene.RequestModuleInterface<IAssetService>(); 156 m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
117 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 157 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
118 } 158 // We'll reuse the same handler for all requests.
159 m_getMeshHandler = new GetMeshHandler(m_assetService);
160 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
161 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
119 162
163 m_NumberScenes++;
164
165 if (m_workerThreads == null)
166 {
167 m_workerThreads = new Thread[2];
168
169 for (uint i = 0; i < 2; i++)
170 {
171 m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests,
172 String.Format("GetMeshWorker{0}", i),
173 ThreadPriority.Normal,
174 true,
175 false,
176 null,
177 int.MaxValue);
178 }
179 }
180 }
120 181
121 public void Close() { } 182 public void Close()
183 {
184 if(m_NumberScenes <= 0 && m_workerThreads != null)
185 {
186 m_log.DebugFormat("[GetMeshModule] Closing");
187 foreach (Thread t in m_workerThreads)
188 Watchdog.AbortThread(t.ManagedThreadId);
189 // This will fail on region shutdown. Its harmless.
190 // Prevent red ink.
191 try
192 {
193 m_queue.Clear();
194 }
195 catch {}
196 }
197 }
122 198
123 public string Name { get { return "GetMeshModule"; } } 199 public string Name { get { return "GetMeshModule"; } }
124 200
125 #endregion 201 #endregion
126 202
203 private static void DoMeshRequests()
204 {
205 while(true)
206 {
207 aPollRequest poolreq = m_queue.Dequeue(4500);
208 Watchdog.UpdateThread();
209 if(m_NumberScenes <= 0)
210 return;
211 if(poolreq.reqID != UUID.Zero)
212 poolreq.thepoll.Process(poolreq);
213 }
214 }
127 215
128 public void RegisterCaps(UUID agentID, Caps caps) 216 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
217 public void ThrottleUpdate(ScenePresence p)
129 { 218 {
130 UUID capID = UUID.Random(); 219 UUID user = p.UUID;
131 bool getMeshRegistered = false; 220 int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset);
221 PollServiceMeshEventArgs args;
222 if (m_pollservices.TryGetValue(user, out args))
223 {
224 args.UpdateThrottle(imagethrottle);
225 }
226 }
227
228 private class PollServiceMeshEventArgs : PollServiceEventArgs
229 {
230 private List<Hashtable> requests =
231 new List<Hashtable>();
232 private Dictionary<UUID, aPollResponse> responses =
233 new Dictionary<UUID, aPollResponse>();
234
235 private Scene m_scene;
236 private MeshCapsDataThrottler m_throttler;
237 public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) :
238 base(null, uri, null, null, null, pId, int.MaxValue)
239 {
240 m_scene = scene;
241 m_throttler = new MeshCapsDataThrottler(100000);
242 // x is request id, y is userid
243 HasEvents = (x, y) =>
244 {
245 lock (responses)
246 {
247 bool ret = m_throttler.hasEvents(x, responses);
248 return ret;
249
250 }
251 };
252 GetEvents = (x, y) =>
253 {
254 lock (responses)
255 {
256 try
257 {
258 return responses[x].response;
259 }
260 finally
261 {
262 responses.Remove(x);
263 m_throttler.PassTime();
264 }
265 }
266 };
267 // x is request id, y is request data hashtable
268 Request = (x, y) =>
269 {
270 aPollRequest reqinfo = new aPollRequest();
271 reqinfo.thepoll = this;
272 reqinfo.reqID = x;
273 reqinfo.request = y;
274
275 m_queue.Enqueue(reqinfo);
276 m_throttler.PassTime();
277 };
132 278
133 if (m_URL == string.Empty) 279 // this should never happen except possible on shutdown
280 NoEvents = (x, y) =>
281 {
282 /*
283 lock (requests)
284 {
285 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
286 requests.Remove(request);
287 }
288 */
289 Hashtable response = new Hashtable();
290
291 response["int_response_code"] = 500;
292 response["str_response_string"] = "Script timeout";
293 response["content_type"] = "text/plain";
294 response["keepalive"] = false;
295 response["reusecontext"] = false;
296
297 return response;
298 };
299 }
300
301 public void Process(aPollRequest requestinfo)
134 { 302 {
303 Hashtable response;
304
305 UUID requestID = requestinfo.reqID;
306
307 if(m_scene.ShuttingDown)
308 return;
309
310 // If the avatar is gone, don't bother to get the texture
311 if (m_scene.GetScenePresence(Id) == null)
312 {
313 response = new Hashtable();
314
315 response["int_response_code"] = 500;
316 response["str_response_string"] = "Script timeout";
317 response["content_type"] = "text/plain";
318 response["keepalive"] = false;
319 response["reusecontext"] = false;
320
321 lock (responses)
322 responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
323
324 return;
325 }
326
327 response = m_getMeshHandler.Handle(requestinfo.request);
328 lock (responses)
329 {
330 responses[requestID] = new aPollResponse()
331 {
332 bytes = (int)response["int_bytes"],
333 lod = (int)response["int_lod"],
334 response = response
335 };
336
337 }
338 m_throttler.PassTime();
339 }
135 340
341 internal void UpdateThrottle(int pthrottle)
342 {
343 int tmp = 2 * pthrottle;
344 if(tmp < 10000)
345 tmp = 10000;
346 m_throttler.ThrottleBytes = tmp;
136 } 347 }
137 else if (m_URL == "localhost") 348 }
349
350 public void RegisterCaps(UUID agentID, Caps caps)
351 {
352// UUID capID = UUID.Random();
353 if (m_URL == "localhost")
138 { 354 {
139 getMeshRegistered = true; 355 string capUrl = "/CAPS/" + UUID.Random() + "/";
140 caps.RegisterHandler( 356
141 "GetMesh", 357 // Register this as a poll service
142 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL)); 358 PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(capUrl, agentID, m_scene);
359
360 args.Type = PollServiceEventArgs.EventType.Mesh;
361 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
362
363 string hostName = m_scene.RegionInfo.ExternalHostName;
364 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
365 string protocol = "http";
366
367 if (MainServer.Instance.UseSSL)
368 {
369 hostName = MainServer.Instance.SSLCommonName;
370 port = MainServer.Instance.SSLPort;
371 protocol = "https";
372 }
373 caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
374 m_pollservices[agentID] = args;
375 m_capsDict[agentID] = capUrl;
143 } 376 }
144 else 377 else
145 { 378 {
146 caps.RegisterHandler("GetMesh", m_URL); 379 caps.RegisterHandler("GetMesh", m_URL);
147 } 380 }
381 }
148 382
149 if(m_URL2 == string.Empty) 383 private void DeregisterCaps(UUID agentID, Caps caps)
384 {
385 string capUrl;
386 PollServiceMeshEventArgs args;
387 if (m_capsDict.TryGetValue(agentID, out capUrl))
388 {
389 MainServer.Instance.RemoveHTTPHandler("", capUrl);
390 m_capsDict.Remove(agentID);
391 }
392 if (m_pollservices.TryGetValue(agentID, out args))
150 { 393 {
394 m_pollservices.Remove(agentID);
395 }
396 }
397
398 internal sealed class MeshCapsDataThrottler
399 {
400 private double lastTimeElapsed = 0;
401 private double BytesSent = 0;
151 402
403 public MeshCapsDataThrottler(int pBytes)
404 {
405 if(pBytes < 10000)
406 pBytes = 10000;
407 ThrottleBytes = pBytes;
408 lastTimeElapsed = Util.GetTimeStampMS();
152 } 409 }
153 else if (m_URL2 == "localhost") 410
411 public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
154 { 412 {
155 if (!getMeshRegistered) 413 PassTime();
414 // Note, this is called IN LOCK
415 bool haskey = responses.ContainsKey(key);
416
417 if (!haskey)
418 {
419 return false;
420 }
421 aPollResponse response;
422 if (responses.TryGetValue(key, out response))
156 { 423 {
157 caps.RegisterHandler( 424 // Normal
158 "GetMesh2", 425 if (BytesSent <= ThrottleBytes)
159 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh2", agentID.ToString(), m_RedirectURL2)); 426 {
427 BytesSent += response.bytes;
428 return true;
429 }
430 else
431 {
432 return false;
433 }
160 } 434 }
435 return haskey;
161 } 436 }
162 else 437
438 public void PassTime()
163 { 439 {
164 caps.RegisterHandler("GetMesh2", m_URL2); 440 double currenttime = Util.GetTimeStampMS();
441 double timeElapsed = currenttime - lastTimeElapsed;
442 if(timeElapsed < 50.0)
443 return;
444 int add = (int)(ThrottleBytes * timeElapsed * 0.001);
445 if (add >= 1000)
446 {
447 lastTimeElapsed = currenttime;
448 BytesSent -= add;
449 if (BytesSent < 0) BytesSent = 0;
450 }
165 } 451 }
166 }
167 452
453 public int ThrottleBytes;
454 }
168 } 455 }
169} 456}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index bb932f2..b01c7dc 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,6 +42,7 @@ 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{
@@ -54,27 +50,49 @@ namespace OpenSim.Region.ClientStack.Linden
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 51 public class GetTextureModule : INonSharedRegionModule
56 { 52 {
57// private static readonly ILog m_log = 53
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 struct aPollRequest
59 55 {
56 public PollServiceTextureEventArgs thepoll;
57 public UUID reqID;
58 public Hashtable request;
59 public bool send503;
60 }
61
62 public class aPollResponse
63 {
64 public Hashtable response;
65 public int bytes;
66 }
67
68
69 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
70
60 private Scene m_scene; 71 private Scene m_scene;
61 private IAssetService m_assetService;
62 72
63 private bool m_Enabled = false; 73 private static GetTextureHandler m_getTextureHandler;
74
75 private IAssetService m_assetService = null;
76
77 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
78 private static Thread[] m_workerThreads = null;
79 private static int m_NumberScenes = 0;
80 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue =
81 new OpenSim.Framework.BlockingQueue<aPollRequest>();
64 82
65 // TODO: Change this to a config option 83 private Dictionary<UUID,PollServiceTextureEventArgs> m_pollservices = new Dictionary<UUID,PollServiceTextureEventArgs>();
66 private string m_RedirectURL = null;
67 84
68 private string m_URL; 85 private string m_Url = "localhost";
69 86
70 #region ISharedRegionModule Members 87 #region ISharedRegionModule Members
71 88
72 public void Initialise(IConfigSource source) 89 public void Initialise(IConfigSource source)
73 { 90 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"]; 91 IConfig config = source.Configs["ClientStack.LindenCaps"];
92
75 if (config == null) 93 if (config == null)
76 return; 94 return;
77 95/*
78 m_URL = config.GetString("Cap_GetTexture", string.Empty); 96 m_URL = config.GetString("Cap_GetTexture", string.Empty);
79 // Cap doesn't exist 97 // Cap doesn't exist
80 if (m_URL != string.Empty) 98 if (m_URL != string.Empty)
@@ -82,39 +100,108 @@ namespace OpenSim.Region.ClientStack.Linden
82 m_Enabled = true; 100 m_Enabled = true;
83 m_RedirectURL = config.GetString("GetTextureRedirectURL"); 101 m_RedirectURL = config.GetString("GetTextureRedirectURL");
84 } 102 }
103*/
104 m_Url = config.GetString("Cap_GetTexture", "localhost");
85 } 105 }
86 106
87 public void AddRegion(Scene s) 107 public void AddRegion(Scene s)
88 { 108 {
89 if (!m_Enabled)
90 return;
91
92 m_scene = s; 109 m_scene = s;
110 m_assetService = s.AssetService;
93 } 111 }
94 112
95 public void RemoveRegion(Scene s) 113 public void RemoveRegion(Scene s)
96 { 114 {
97 if (!m_Enabled)
98 return;
99
100 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 115 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
116 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
117 m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
118 m_NumberScenes--;
101 m_scene = null; 119 m_scene = null;
102 } 120 }
103 121
104 public void RegionLoaded(Scene s) 122 public void RegionLoaded(Scene s)
105 { 123 {
106 if (!m_Enabled) 124 // We'll reuse the same handler for all requests.
107 return; 125 m_getTextureHandler = new GetTextureHandler(m_assetService);
108 126
109 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
110 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 127 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
128 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
129 m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
130
131 m_NumberScenes++;
132
133 if (m_workerThreads == null)
134 {
135 m_workerThreads = new Thread[2];
136
137 for (uint i = 0; i < 2; i++)
138 {
139 m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests,
140 String.Format("GetTextureWorker{0}", i),
141 ThreadPriority.Normal,
142 true,
143 false,
144 null,
145 int.MaxValue);
146 }
147 }
148 }
149 private int ExtractImageThrottle(byte[] pthrottles)
150 {
151
152 byte[] adjData;
153 int pos = 0;
154
155 if (!BitConverter.IsLittleEndian)
156 {
157 byte[] newData = new byte[7 * 4];
158 Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
159
160 for (int i = 0; i < 7; i++)
161 Array.Reverse(newData, i * 4, 4);
162
163 adjData = newData;
164 }
165 else
166 {
167 adjData = pthrottles;
168 }
169
170 pos = pos + 20;
171 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
172 //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
173 return texture;
174 }
175
176 // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
177 public void ThrottleUpdate(ScenePresence p)
178 {
179 byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
180 UUID user = p.UUID;
181 int imagethrottle = ExtractImageThrottle(throttles);
182 PollServiceTextureEventArgs args;
183 if (m_pollservices.TryGetValue(user,out args))
184 {
185 args.UpdateThrottle(imagethrottle);
186 }
111 } 187 }
112 188
113 public void PostInitialise() 189 public void PostInitialise()
114 { 190 {
115 } 191 }
116 192
117 public void Close() { } 193 public void Close()
194 {
195 if(m_NumberScenes <= 0 && m_workerThreads != null)
196 {
197 m_log.DebugFormat("[GetTextureModule] Closing");
198
199 foreach (Thread t in m_workerThreads)
200 Watchdog.AbortThread(t.ManagedThreadId);
201
202 m_queue.Clear();
203 }
204 }
118 205
119 public string Name { get { return "GetTextureModule"; } } 206 public string Name { get { return "GetTextureModule"; } }
120 207
@@ -125,28 +212,277 @@ namespace OpenSim.Region.ClientStack.Linden
125 212
126 #endregion 213 #endregion
127 214
128 public void RegisterCaps(UUID agentID, Caps caps) 215 private class PollServiceTextureEventArgs : PollServiceEventArgs
129 { 216 {
130 UUID capID = UUID.Random(); 217 private List<Hashtable> requests =
218 new List<Hashtable>();
219 private Dictionary<UUID, aPollResponse> responses =
220 new Dictionary<UUID, aPollResponse>();
221
222 private Scene m_scene;
223 private CapsDataThrottler m_throttler = new CapsDataThrottler(100000);
224 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
225 base(null, "", null, null, null, pId, int.MaxValue)
226 {
227 m_scene = scene;
228 // x is request id, y is userid
229 HasEvents = (x, y) =>
230 {
231 lock (responses)
232 {
233 bool ret = m_throttler.hasEvents(x, responses);
234 return ret;
235
236 }
237 };
238 GetEvents = (x, y) =>
239 {
240 lock (responses)
241 {
242 try
243 {
244 return responses[x].response;
245 }
246 finally
247 {
248 responses.Remove(x);
249 m_throttler.PassTime();
250 }
251 }
252 };
253 // x is request id, y is request data hashtable
254 Request = (x, y) =>
255 {
256 aPollRequest reqinfo = new aPollRequest();
257 reqinfo.thepoll = this;
258 reqinfo.reqID = x;
259 reqinfo.request = y;
260 reqinfo.send503 = false;
261
262 lock (responses)
263 {
264 if (responses.Count > 0)
265 {
266 if (m_queue.Count() >= 4)
267 {
268 // Never allow more than 4 fetches to wait
269 reqinfo.send503 = true;
270 }
271 }
272 }
273 m_queue.Enqueue(reqinfo);
274 m_throttler.PassTime();
275 };
276
277 // this should never happen except possible on shutdown
278 NoEvents = (x, y) =>
279 {
280/*
281 lock (requests)
282 {
283 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
284 requests.Remove(request);
285 }
286*/
287 Hashtable response = new Hashtable();
131 288
132 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 289 response["int_response_code"] = 500;
133 if (m_URL == "localhost") 290 response["str_response_string"] = "Script timeout";
291 response["content_type"] = "text/plain";
292 response["keepalive"] = false;
293 response["reusecontext"] = false;
294
295 return response;
296 };
297 }
298
299 public void Process(aPollRequest requestinfo)
134 { 300 {
135// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 301 Hashtable response;
136 caps.RegisterHandler( 302
137 "GetTexture", 303 UUID requestID = requestinfo.reqID;
138 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL)); 304
305 if(m_scene.ShuttingDown)
306 return;
307
308 if (requestinfo.send503)
309 {
310 response = new Hashtable();
311
312 response["int_response_code"] = 503;
313 response["str_response_string"] = "Throttled";
314 response["content_type"] = "text/plain";
315 response["keepalive"] = false;
316 response["reusecontext"] = false;
317
318 Hashtable headers = new Hashtable();
319 headers["Retry-After"] = 30;
320 response["headers"] = headers;
321
322 lock (responses)
323 responses[requestID] = new aPollResponse() {bytes = 0, response = response};
324
325 return;
326 }
327
328 // If the avatar is gone, don't bother to get the texture
329 if (m_scene.GetScenePresence(Id) == null)
330 {
331 response = new Hashtable();
332
333 response["int_response_code"] = 500;
334 response["str_response_string"] = "Script timeout";
335 response["content_type"] = "text/plain";
336 response["keepalive"] = false;
337 response["reusecontext"] = false;
338
339 lock (responses)
340 responses[requestID] = new aPollResponse() {bytes = 0, response = response};
341
342 return;
343 }
344
345 response = m_getTextureHandler.Handle(requestinfo.request);
346 lock (responses)
347 {
348 responses[requestID] = new aPollResponse()
349 {
350 bytes = (int) response["int_bytes"],
351 response = response
352 };
353
354 }
355 m_throttler.PassTime();
139 } 356 }
140 else 357
358 internal void UpdateThrottle(int pimagethrottle)
141 { 359 {
142// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 360 int tmp = 2 * pimagethrottle;
361 if(tmp < 10000)
362 tmp = 10000;
363 m_throttler.ThrottleBytes = tmp;
364 }
365 }
366
367 private void RegisterCaps(UUID agentID, Caps caps)
368 {
369 if (m_Url == "localhost")
370 {
371 string capUrl = "/CAPS/" + UUID.Random() + "/";
372
373 // Register this as a poll service
374 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
375
376 args.Type = PollServiceEventArgs.EventType.Texture;
377 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
378
379 string hostName = m_scene.RegionInfo.ExternalHostName;
380 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
381 string protocol = "http";
382
383 if (MainServer.Instance.UseSSL)
384 {
385 hostName = MainServer.Instance.SSLCommonName;
386 port = MainServer.Instance.SSLPort;
387 protocol = "https";
388 }
143 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>(); 389 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
144 if (handler != null) 390 if (handler != null)
145 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL); 391 handler.RegisterExternalUserCapsHandler(agentID, caps, "GetTexture", capUrl);
146 else 392 else
147 caps.RegisterHandler("GetTexture", m_URL); 393 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
394 m_pollservices[agentID] = args;
395 m_capsDict[agentID] = capUrl;
396 }
397 else
398 {
399 caps.RegisterHandler("GetTexture", m_Url);
400 }
401 }
402
403 private void DeregisterCaps(UUID agentID, Caps caps)
404 {
405 PollServiceTextureEventArgs args;
406
407 MainServer.Instance.RemoveHTTPHandler("", m_Url);
408 m_capsDict.Remove(agentID);
409
410 if (m_pollservices.TryGetValue(agentID, out args))
411 {
412 m_pollservices.Remove(agentID);
413 }
414 }
415
416 private static void DoTextureRequests()
417 {
418 while (true)
419 {
420 aPollRequest poolreq = m_queue.Dequeue(4500);
421 Watchdog.UpdateThread();
422 if(m_NumberScenes <= 0)
423 return;
424 if(poolreq.reqID != UUID.Zero)
425 poolreq.thepoll.Process(poolreq);
148 } 426 }
149 } 427 }
150 428
429 internal sealed class CapsDataThrottler
430 {
431 private double lastTimeElapsed = 0;
432 private volatile int BytesSent = 0;
433 public CapsDataThrottler(int pBytes)
434 {
435 if(pBytes < 10000)
436 pBytes = 10000;
437 ThrottleBytes = pBytes;
438 lastTimeElapsed = Util.GetTimeStampMS();
439 }
440 public bool hasEvents(UUID key, Dictionary<UUID, GetTextureModule.aPollResponse> responses)
441 {
442 PassTime();
443 // Note, this is called IN LOCK
444 bool haskey = responses.ContainsKey(key);
445 if (!haskey)
446 {
447 return false;
448 }
449 GetTextureModule.aPollResponse response;
450 if (responses.TryGetValue(key, out response))
451 {
452 // This is any error response
453 if (response.bytes == 0)
454 return true;
455
456 // Normal
457 if (BytesSent <= ThrottleBytes)
458 {
459 BytesSent += response.bytes;
460 return true;
461 }
462 else
463 {
464 return false;
465 }
466 }
467
468 return haskey;
469 }
470
471 public void PassTime()
472 {
473 double currenttime = Util.GetTimeStampMS();
474 double timeElapsed = currenttime - lastTimeElapsed;
475 if(timeElapsed < 50.0)
476 return;
477 int add = (int)(ThrottleBytes * timeElapsed * 0.001);
478 if (add >= 1000)
479 {
480 lastTimeElapsed = currenttime;
481 BytesSent -= add;
482 if (BytesSent < 0) BytesSent = 0;
483 }
484 }
485 public int ThrottleBytes;
486 }
151 } 487 }
152} 488}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index 45d33cd..44bf1a5 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -129,23 +129,23 @@ namespace OpenSim.Region.ClientStack.Linden
129// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request"); 129// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
130 130
131 OSDMap data = new OSDMap(); 131 OSDMap data = new OSDMap();
132 ScenePresence sp = m_scene.GetScenePresence(agentID); 132// ScenePresence sp = m_scene.GetScenePresence(m_agentID);
133 data["username"] = sp.Firstname + "." + sp.Lastname; 133// data["username"] = sp.Firstname + "." + sp.Lastname;
134 data["display_name_next_update"] = new OSDDate(DateTime.Now); 134// data["display_name_next_update"] = new OSDDate(DateTime.Now);
135 data["legacy_first_name"] = sp.Firstname; 135// data["legacy_first_name"] = sp.Firstname;
136 data["mesh_upload_status"] = "valid"; 136 data["mesh_upload_status"] = "valid";
137 data["display_name"] = sp.Firstname + " " + sp.Lastname; 137// data["display_name"] = sp.Firstname + " " + sp.Lastname;
138 data["legacy_last_name"] = sp.Lastname; 138// data["legacy_last_name"] = sp.Lastname;
139 data["id"] = agentID; 139// data["id"] = m_agentID;
140 data["is_display_name_default"] = true; 140// data["is_display_name_default"] = true;
141 141
142 //Send back data 142 //Send back data
143 Hashtable responsedata = new Hashtable(); 143 Hashtable responsedata = new Hashtable();
144 responsedata["int_response_code"] = 200; 144 responsedata["int_response_code"] = 200;
145 responsedata["content_type"] = "text/plain"; 145 responsedata["content_type"] = "text/plain";
146 responsedata["keepalive"] = false; 146 responsedata["keepalive"] = false;
147 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data); 147 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
148 return responsedata; 148 return responsedata;
149 } 149 }
150 } 150 }
151} \ No newline at end of file 151}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
deleted file mode 100644
index f69a0bb..0000000
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ /dev/null
@@ -1,297 +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;
47using PermissionMask = OpenSim.Framework.PermissionMask;
48
49namespace OpenSim.Region.ClientStack.Linden
50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NewFileAgentInventoryVariablePriceModule")]
52 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
53 {
54// private static readonly ILog m_log = 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 private int m_levelUpload = 0;
61
62 #region Region Module interfaceBase Members
63
64
65 public Type ReplaceableInterface
66 {
67 get { return null; }
68 }
69
70 public void Initialise(IConfigSource source)
71 {
72 IConfig meshConfig = source.Configs["Mesh"];
73 if (meshConfig == null)
74 return;
75
76 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
77 m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
78 }
79
80 public void AddRegion(Scene pScene)
81 {
82 m_scene = pScene;
83 }
84
85 public void RemoveRegion(Scene scene)
86 {
87
88 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
89 m_scene = null;
90 }
91
92 public void RegionLoaded(Scene scene)
93 {
94
95// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
97 }
98
99 #endregion
100
101
102 #region Region Module interface
103
104
105
106 public void Close() { }
107
108 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
109
110
111 public void RegisterCaps(UUID agentID, Caps caps)
112 {
113 if(!m_enabled)
114 return;
115
116 UUID capID = UUID.Random();
117
118// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
119 caps.RegisterHandler(
120 "NewFileAgentInventoryVariablePrice",
121 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
122 "POST",
123 "/CAPS/" + capID.ToString(),
124 req => NewAgentInventoryRequest(req, agentID),
125 "NewFileAgentInventoryVariablePrice",
126 agentID.ToString()));
127 }
128
129 #endregion
130
131 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
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
135
136 //if (llsdRequest.asset_type == "texture" ||
137 // llsdRequest.asset_type == "animation" ||
138 // llsdRequest.asset_type == "sound")
139 // {
140 // check user level
141
142 ScenePresence avatar = null;
143 IClientAPI client = null;
144 m_scene.TryGetScenePresence(agentID, out avatar);
145
146 if (avatar != null)
147 {
148 client = avatar.ControllingClient;
149
150 if (avatar.UserLevel < m_levelUpload)
151 {
152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
154
155 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
156 errorResponse.rsvp = "";
157 errorResponse.state = "error";
158 return errorResponse;
159 }
160 }
161
162 // check funds
163 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
164
165 if (mm != null)
166 {
167 if (!mm.UploadCovered(agentID, mm.UploadCharge))
168 {
169 if (client != null)
170 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
171
172 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
173 errorResponse.rsvp = "";
174 errorResponse.state = "error";
175 return errorResponse;
176 }
177 }
178
179 // }
180
181 string assetName = llsdRequest.name;
182 string assetDes = llsdRequest.description;
183 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
184 UUID newAsset = UUID.Random();
185 UUID newInvItem = UUID.Random();
186 UUID parentFolder = llsdRequest.folder_id;
187 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
188
189 AssetUploader uploader =
190 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
191 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
192
193 MainServer.Instance.AddStreamHandler(
194 new BinaryStreamHandler(
195 "POST",
196 capsBase + uploaderPath,
197 uploader.uploaderCaps,
198 "NewFileAgentInventoryVariablePrice",
199 agentID.ToString()));
200
201 string protocol = "http://";
202
203 if (MainServer.Instance.UseSSL)
204 protocol = "https://";
205
206 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
207 uploaderPath;
208
209
210 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
211
212 uploadResponse.rsvp = uploaderURL;
213 uploadResponse.state = "upload";
214 uploadResponse.resource_cost = 0;
215 uploadResponse.upload_price = 0;
216
217 uploader.OnUpLoad += //UploadCompleteHandler;
218
219 delegate(
220 string passetName, string passetDescription, UUID passetID,
221 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
222 string passetType)
223 {
224 UploadCompleteHandler(passetName, passetDescription, passetID,
225 pinventoryItem, pparentFolder, pdata, pinventoryType,
226 passetType,agentID);
227 };
228
229 return uploadResponse;
230 }
231
232 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
233 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
234 string assetType,UUID AgentID)
235 {
236// m_log.DebugFormat(
237// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
238
239 sbyte assType = 0;
240 sbyte inType = 0;
241
242 if (inventoryType == "sound")
243 {
244 inType = 1;
245 assType = 1;
246 }
247 else if (inventoryType == "animation")
248 {
249 inType = 19;
250 assType = 20;
251 }
252 else if (inventoryType == "wearable")
253 {
254 inType = 18;
255 switch (assetType)
256 {
257 case "bodypart":
258 assType = 13;
259 break;
260 case "clothing":
261 assType = 5;
262 break;
263 }
264 }
265 else if (inventoryType == "mesh")
266 {
267 inType = (sbyte)InventoryType.Mesh;
268 assType = (sbyte)AssetType.Mesh;
269 }
270
271 AssetBase asset;
272 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
273 asset.Data = data;
274
275 if (m_scene.AssetService != null)
276 m_scene.AssetService.Store(asset);
277
278 InventoryItemBase item = new InventoryItemBase();
279 item.Owner = AgentID;
280 item.CreatorId = AgentID.ToString();
281 item.ID = inventoryItem;
282 item.AssetID = asset.FullID;
283 item.Description = assetDescription;
284 item.Name = assetName;
285 item.AssetType = assType;
286 item.InvType = inType;
287 item.Folder = parentFolder;
288 item.CurrentPermissions
289 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
290 item.BasePermissions = (uint)PermissionMask.All;
291 item.EveryOnePermissions = 0;
292 item.NextPermissions = (uint)PermissionMask.All;
293 item.CreationDate = Util.UnixTimeSinceEpoch();
294 m_scene.AddInventoryItem(item);
295 }
296 }
297}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 94f8bc1..b044e56 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.ClientStack.Linden
47 { 47 {
48// private static readonly ILog m_log = 48// private static readonly ILog m_log =
49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 private Scene m_scene; 51 private Scene m_scene;
52 52
53 #region INonSharedRegionModule Members 53 #region INonSharedRegionModule Members
@@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack.Linden
76 } 76 }
77 77
78 public void Close() 78 public void Close()
79 { 79 {
80 } 80 }
81 81
82 public string Name 82 public string Name
@@ -121,6 +121,9 @@ namespace OpenSim.Region.ClientStack.Linden
121 121
122 122
123 OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]); 123 OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
124 if (r.Type != OSDType.Map) // not a proper req
125 return responsedata;
126
124 //UUID session_id = UUID.Zero; 127 //UUID session_id = UUID.Zero;
125 bool bypass_raycast = false; 128 bool bypass_raycast = false;
126 uint everyone_mask = 0; 129 uint everyone_mask = 0;
@@ -157,9 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden
157 int state = 0; 160 int state = 0;
158 int lastattach = 0; 161 int lastattach = 0;
159 162
160 if (r.Type != OSDType.Map) // not a proper req
161 return responsedata;
162
163 OSDMap rm = (OSDMap)r; 163 OSDMap rm = (OSDMap)r;
164 164
165 if (rm.ContainsKey("ObjectData")) //v2 165 if (rm.ContainsKey("ObjectData")) //v2
@@ -307,8 +307,6 @@ namespace OpenSim.Region.ClientStack.Linden
307 } 307 }
308 } 308 }
309 309
310
311
312 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); 310 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);
313 311
314 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); 312 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
@@ -359,6 +357,8 @@ namespace OpenSim.Region.ClientStack.Linden
359 rootpart.NextOwnerMask = next_owner_mask; 357 rootpart.NextOwnerMask = next_owner_mask;
360 rootpart.Material = (byte)material; 358 rootpart.Material = (byte)material;
361 359
360 obj.InvalidateDeepEffectivePerms();
361
362 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); 362 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
363 363
364 responsedata["int_response_code"] = 200; //501; //410; //404; 364 responsedata["int_response_code"] = 200; //501; //410; //404;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 769fe28..116c51f 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -189,7 +189,7 @@ namespace OpenSim.Region.ClientStack.Linden
189 if (i == 0) 189 if (i == 0)
190 { 190 {
191 rootpos = obj.Position; 191 rootpos = obj.Position;
192// rootrot = obj.Rotation; 192// rootrot = obj.Rotation;
193 } 193 }
194 194
195 // Combine the extraparams data into it's ugly blob again.... 195 // Combine the extraparams data into it's ugly blob again....
@@ -284,6 +284,7 @@ namespace OpenSim.Region.ClientStack.Linden
284 prim.OwnerID = AgentId; 284 prim.OwnerID = AgentId;
285 prim.GroupID = obj.GroupID; 285 prim.GroupID = obj.GroupID;
286 prim.LastOwnerID = prim.OwnerID; 286 prim.LastOwnerID = prim.OwnerID;
287 prim.RezzerID = AgentId;
287 prim.CreationDate = Util.UnixTimeSinceEpoch(); 288 prim.CreationDate = Util.UnixTimeSinceEpoch();
288 prim.Name = obj.Name; 289 prim.Name = obj.Name;
289 prim.Description = ""; 290 prim.Description = "";
@@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.Linden
320 pbs.TextureEntry = tmp.GetBytes(); 321 pbs.TextureEntry = tmp.GetBytes();
321 prim.Shape = pbs; 322 prim.Shape = pbs;
322 prim.Scale = obj.Scale; 323 prim.Scale = obj.Scale;
323 324
324 SceneObjectGroup grp = new SceneObjectGroup(); 325 SceneObjectGroup grp = new SceneObjectGroup();
325 326
326 grp.SetRootPart(prim); 327 grp.SetRootPart(prim);
@@ -328,21 +329,22 @@ namespace OpenSim.Region.ClientStack.Linden
328 if (i == 0) 329 if (i == 0)
329 { 330 {
330 rootGroup = grp; 331 rootGroup = grp;
331 332
332 } 333 }
333 grp.AttachToScene(m_scene); 334 grp.AttachToScene(m_scene);
334 grp.AbsolutePosition = obj.Position; 335 grp.AbsolutePosition = obj.Position;
335 prim.RotationOffset = obj.Rotation; 336 prim.RotationOffset = obj.Rotation;
336 337
338
337 // Required for linking 339 // Required for linking
338 grp.RootPart.ClearUpdateSchedule(); 340 grp.RootPart.ClearUpdateSchedule();
339 341
340 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) 342 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
341 { 343 {
342 m_scene.AddSceneObject(grp); 344 m_scene.AddSceneObject(grp);
343 grp.AbsolutePosition = obj.Position; 345 grp.AbsolutePosition = obj.Position;
344 } 346 }
345 347
346 allparts[i] = grp; 348 allparts[i] = grp;
347 } 349 }
348 350
@@ -358,7 +360,7 @@ namespace OpenSim.Region.ClientStack.Linden
358 pos 360 pos
359 = m_scene.GetNewRezLocation( 361 = m_scene.GetNewRezLocation(
360 Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false); 362 Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false);
361 363
362 responsedata["int_response_code"] = 200; //501; //410; //404; 364 responsedata["int_response_code"] = 200; //501; //410; //404;
363 responsedata["content_type"] = "text/plain"; 365 responsedata["content_type"] = "text/plain";
364 responsedata["keepalive"] = false; 366 responsedata["keepalive"] = false;
@@ -366,7 +368,7 @@ namespace OpenSim.Region.ClientStack.Linden
366 368
367 return responsedata; 369 return responsedata;
368 } 370 }
369 371
370 private string ConvertUintToBytes(uint val) 372 private string ConvertUintToBytes(uint val)
371 { 373 {
372 byte[] resultbytes = Utils.UIntToBytes(val); 374 byte[] resultbytes = Utils.UIntToBytes(val);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
index 0adfa1a..f36826b 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
@@ -2,7 +2,7 @@
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5// General Information about an assembly is controlled through the following 5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information 6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly. 7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenCaps")] 8[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenCaps")]
@@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
14[assembly: AssemblyTrademark("")] 14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")] 15[assembly: AssemblyCulture("")]
16 16
17// Setting ComVisible to false makes the types in this assembly not visible 17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from 18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type. 19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)] 20[assembly: ComVisible(false)]
21 21
@@ -25,9 +25,9 @@ using System.Runtime.InteropServices;
25// Version information for an assembly consists of the following four values: 25// Version information for an assembly consists of the following four values:
26// 26//
27// Major Version 27// Major Version
28// Minor Version 28// Minor Version
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.8.3.*")] 32[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
33 33
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index a133a69..e8387e3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -58,12 +58,14 @@ namespace OpenSim.Region.ClientStack.Linden
58 { 58 {
59// private static readonly ILog m_log = 59// private static readonly ILog m_log =
60// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 60// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61 61
62 private Scene m_scene; 62 private Scene m_scene;
63 private IEventQueue m_eventQueue; 63 private IEventQueue m_eventQueue;
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);
@@ -102,7 +104,7 @@ namespace OpenSim.Region.ClientStack.Linden
102 104
103 public void RegisterCaps(UUID agentID, Caps caps) 105 public void RegisterCaps(UUID agentID, Caps caps)
104 { 106 {
105 if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID)) 107 if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID) && !m_scene.Permissions.IsGod(agentID))
106 return; 108 return;
107 109
108 UUID capID = UUID.Random(); 110 UUID capID = UUID.Random();
@@ -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)
@@ -148,7 +155,7 @@ namespace OpenSim.Region.ClientStack.Linden
148 155
149 SendConsoleOutput(agentID, reply); 156 SendConsoleOutput(agentID, reply);
150 } 157 }
151 158
152 public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) 159 public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn)
153 { 160 {
154 m_commands.AddCommand(module, shared, command, help, longhelp, fn); 161 m_commands.AddCommand(module, shared, command, help, longhelp, fn);
@@ -178,8 +185,9 @@ namespace OpenSim.Region.ClientStack.Linden
178 185
179 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 186 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
180 { 187 {
181 StreamReader reader = new StreamReader(request); 188 string message;
182 string message = reader.ReadToEnd(); 189 using(StreamReader reader = new StreamReader(request))
190 message = reader.ReadToEnd();
183 191
184 OSD osd = OSDParser.DeserializeLLSDXml(message); 192 OSD osd = OSDParser.DeserializeLLSDXml(message);
185 193
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index e258bcb..39f5baf 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -50,12 +50,12 @@ namespace OpenSim.Region.ClientStack.Linden
50 /// This is required for uploading Mesh. 50 /// This is required for uploading Mesh.
51 /// Since is accepts an open-ended response, we also send more information 51 /// Since is accepts an open-ended response, we also send more information
52 /// for viewers that care to interpret it. 52 /// for viewers that care to interpret it.
53 /// 53 ///
54 /// NOTE: Part of this code was adapted from the Aurora project, specifically 54 /// NOTE: Part of this code was adapted from the Aurora project, specifically
55 /// the normal part of the response in the capability handler. 55 /// the normal part of the response in the capability handler.
56 /// </remarks> 56 /// </remarks>
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")] 57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
58 public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule 58 public class SimulatorFeaturesModule : INonSharedRegionModule, ISimulatorFeaturesModule
59 { 59 {
60 private static readonly ILog m_log = 60 private static readonly ILog m_log =
61 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -82,7 +82,7 @@ namespace OpenSim.Region.ClientStack.Linden
82 IConfig config = source.Configs["SimulatorFeatures"]; 82 IConfig config = source.Configs["SimulatorFeatures"];
83 83
84 if (config != null) 84 if (config != null)
85 { 85 {
86 // 86 //
87 // All this is obsolete since getting these features from the grid service!! 87 // All this is obsolete since getting these features from the grid service!!
88 // Will be removed after the next release 88 // Will be removed after the next release
@@ -126,10 +126,6 @@ namespace OpenSim.Region.ClientStack.Linden
126 GetGridExtraFeatures(s); 126 GetGridExtraFeatures(s);
127 } 127 }
128 128
129 public void PostInitialise()
130 {
131 }
132
133 public void Close() { } 129 public void Close() { }
134 130
135 public string Name { get { return "SimulatorFeaturesModule"; } } 131 public string Name { get { return "SimulatorFeaturesModule"; } }
@@ -155,6 +151,7 @@ namespace OpenSim.Region.ClientStack.Linden
155 m_features["MeshRezEnabled"] = true; 151 m_features["MeshRezEnabled"] = true;
156 m_features["MeshUploadEnabled"] = true; 152 m_features["MeshUploadEnabled"] = true;
157 m_features["MeshXferEnabled"] = true; 153 m_features["MeshXferEnabled"] = true;
154
158 m_features["PhysicsMaterialsEnabled"] = true; 155 m_features["PhysicsMaterialsEnabled"] = true;
159 156
160 OSDMap typesMap = new OSDMap(); 157 OSDMap typesMap = new OSDMap();
@@ -173,6 +170,10 @@ namespace OpenSim.Region.ClientStack.Linden
173 else 170 else
174 extrasMap = new OSDMap(); 171 extrasMap = new OSDMap();
175 172
173 extrasMap["AvatarSkeleton"] = true;
174 extrasMap["AnimationSet"] = true;
175
176 // TODO: Take these out of here into their respective modules, like map-server-url
176 if (m_SearchURL != string.Empty) 177 if (m_SearchURL != string.Empty)
177 extrasMap["search-server-url"] = m_SearchURL; 178 extrasMap["search-server-url"] = m_SearchURL;
178 if (!string.IsNullOrEmpty(m_DestinationGuideURL)) 179 if (!string.IsNullOrEmpty(m_DestinationGuideURL))
@@ -250,7 +251,7 @@ namespace OpenSim.Region.ClientStack.Linden
250 251
251 //Send back data 252 //Send back data
252 Hashtable responsedata = new Hashtable(); 253 Hashtable responsedata = new Hashtable();
253 responsedata["int_response_code"] = 200; 254 responsedata["int_response_code"] = 200;
254 responsedata["content_type"] = "text/plain"; 255 responsedata["content_type"] = "text/plain";
255 responsedata["keepalive"] = false; 256 responsedata["keepalive"] = false;
256 257
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
index dd4a691..6ffed4d 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
@@ -52,6 +52,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52 52
53namespace OpenSim.Region.ClientStack.Linden.Caps.Tests 53namespace OpenSim.Region.ClientStack.Linden.Caps.Tests
54{ 54{
55 /*
55 [TestFixture] 56 [TestFixture]
56 public class WebFetchInvDescModuleTests : OpenSimTestCase 57 public class WebFetchInvDescModuleTests : OpenSimTestCase
57 { 58 {
@@ -150,10 +151,11 @@ namespace OpenSim.Region.ClientStack.Linden.Caps.Tests
150 OSDMap responseOsd = (OSDMap)OSDParser.DeserializeLLSDXml(context.ResponseBody); 151 OSDMap responseOsd = (OSDMap)OSDParser.DeserializeLLSDXml(context.ResponseBody);
151 OSDArray foldersOsd = (OSDArray)responseOsd["folders"]; 152 OSDArray foldersOsd = (OSDArray)responseOsd["folders"];
152 OSDMap folderOsd = (OSDMap)foldersOsd[0]; 153 OSDMap folderOsd = (OSDMap)foldersOsd[0];
153 154
154 // A sanity check that the response has the expected number of descendents for a default inventory 155 // A sanity check that the response has the expected number of descendents for a default inventory
155 // TODO: Need a more thorough check. 156 // TODO: Need a more thorough check.
156 Assert.That((int)folderOsd["descendents"], Is.EqualTo(16)); 157 Assert.That((int)folderOsd["descendents"], Is.EqualTo(16));
157 } 158 }
158 } 159 }
160 */
159} \ No newline at end of file 161} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index 8cdebcd..b406b37 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -63,23 +63,23 @@ namespace OpenSim.Region.ClientStack.Linden
63 private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. 63 private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
64 64
65 private Scene m_scene; 65 private Scene m_scene;
66 private bool m_persistBakedTextures;
67 66
68 private IBakedTextureModule m_BakedTextureModule; 67 private string m_URL;
69 68
70 public void Initialise(IConfigSource source) 69 public void Initialise(IConfigSource source)
71 { 70 {
72 IConfig appearanceConfig = source.Configs["Appearance"]; 71 IConfig config = source.Configs["ClientStack.LindenCaps"];
73 if (appearanceConfig != null) 72 if (config == null)
74 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); 73 return;
75 74
75 m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty);
76 76
77// IConfig appearanceConfig = source.Configs["Appearance"];
77 } 78 }
78 79
79 public void AddRegion(Scene s) 80 public void AddRegion(Scene s)
80 { 81 {
81 m_scene = s; 82 m_scene = s;
82
83 } 83 }
84 84
85 public void RemoveRegion(Scene s) 85 public void RemoveRegion(Scene s)
@@ -87,188 +87,28 @@ namespace OpenSim.Region.ClientStack.Linden
87 s.EventManager.OnRegisterCaps -= RegisterCaps; 87 s.EventManager.OnRegisterCaps -= RegisterCaps;
88 s.EventManager.OnNewPresence -= RegisterNewPresence; 88 s.EventManager.OnNewPresence -= RegisterNewPresence;
89 s.EventManager.OnRemovePresence -= DeRegisterPresence; 89 s.EventManager.OnRemovePresence -= DeRegisterPresence;
90 m_BakedTextureModule = null;
91 m_scene = null; 90 m_scene = null;
92 } 91 }
93 92
94
95
96 public void RegionLoaded(Scene s) 93 public void RegionLoaded(Scene s)
97 { 94 {
98 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 95 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
99 m_scene.EventManager.OnNewPresence += RegisterNewPresence; 96 m_scene.EventManager.OnNewPresence += RegisterNewPresence;
100 m_scene.EventManager.OnRemovePresence += DeRegisterPresence; 97 m_scene.EventManager.OnRemovePresence += DeRegisterPresence;
101
102 } 98 }
103 99
104 private void DeRegisterPresence(UUID agentId) 100 private void DeRegisterPresence(UUID agentId)
105 { 101 {
106 ScenePresence presence = null;
107 if (m_scene.TryGetScenePresence(agentId, out presence))
108 {
109 presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
110 }
111
112 } 102 }
113 103
114 private void RegisterNewPresence(ScenePresence presence) 104 private void RegisterNewPresence(ScenePresence presence)
115 { 105 {
116 presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
117
118 }
119
120 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
121 {
122 int maxCacheitemsLoop = cacheItems.Length;
123 if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES)
124 {
125 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
126 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
127 }
128
129 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
130 if (cacheItems.Length > 0)
131 {
132// m_log.Debug("[Cacheitems]: " + cacheItems.Length);
133// for (int iter = 0; iter < maxCacheitemsLoop; iter++)
134// {
135// m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
136// cacheItems[iter].TextureID);
137// }
138
139 ScenePresence p = null;
140 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
141 {
142
143 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
144 if (existingitems == null)
145 {
146 if (m_BakedTextureModule != null)
147 {
148 WearableCacheItem[] savedcache = null;
149 try
150 {
151 if (p.Appearance.WearableCacheItemsDirty)
152 {
153 savedcache = m_BakedTextureModule.Get(p.UUID);
154 p.Appearance.WearableCacheItems = savedcache;
155 p.Appearance.WearableCacheItemsDirty = false;
156 }
157
158 }
159 /*
160 * The following Catch types DO NOT WORK with m_BakedTextureModule.Get
161 * it jumps to the General Packet Exception Handler if you don't catch Exception!
162 *
163 catch (System.Net.Sockets.SocketException)
164 {
165 cacheItems = null;
166 }
167 catch (WebException)
168 {
169 cacheItems = null;
170 }
171 catch (InvalidOperationException)
172 {
173 cacheItems = null;
174 } */
175 catch (Exception)
176 {
177 // The service logs a sufficient error message.
178 }
179
180
181 if (savedcache != null)
182 existingitems = savedcache;
183 }
184 }
185 // Existing items null means it's a fully new appearance
186 if (existingitems == null)
187 {
188
189 for (int i = 0; i < maxCacheitemsLoop; i++)
190 {
191 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
192 {
193 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
194 if (face == null)
195 {
196 textureEntry.CreateFace(cacheItems[i].TextureIndex);
197 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
198 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
199 continue;
200 }
201 cacheItems[i].TextureID =face.TextureID;
202 if (m_scene.AssetService != null)
203 cacheItems[i].TextureAsset =
204 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
205 }
206 else
207 {
208 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
209 }
210
211
212 }
213 }
214 else
215
216
217 {
218 // for each uploaded baked texture
219 for (int i = 0; i < maxCacheitemsLoop; i++)
220 {
221 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
222 {
223 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
224 if (face == null)
225 {
226 textureEntry.CreateFace(cacheItems[i].TextureIndex);
227 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
228 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
229 continue;
230 }
231 cacheItems[i].TextureID =
232 face.TextureID;
233 }
234 else
235 {
236 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
237 }
238 }
239
240 for (int i = 0; i < maxCacheitemsLoop; i++)
241 {
242 if (cacheItems[i].TextureAsset == null)
243 {
244 cacheItems[i].TextureAsset =
245 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
246 }
247 }
248 }
249
250
251
252 p.Appearance.WearableCacheItems = cacheItems;
253
254
255
256 if (m_BakedTextureModule != null)
257 {
258 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
259 p.Appearance.WearableCacheItemsDirty = true;
260
261 }
262 }
263 }
264 } 106 }
265 107
266 public void PostInitialise() 108 public void PostInitialise()
267 { 109 {
268 } 110 }
269 111
270
271
272 public void Close() { } 112 public void Close() { }
273 113
274 public string Name { get { return "UploadBakedTextureModule"; } } 114 public string Name { get { return "UploadBakedTextureModule"; } }
@@ -280,23 +120,26 @@ namespace OpenSim.Region.ClientStack.Linden
280 120
281 public void RegisterCaps(UUID agentID, Caps caps) 121 public void RegisterCaps(UUID agentID, Caps caps)
282 { 122 {
283 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( 123 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
284 caps, m_scene.AssetService, m_persistBakedTextures); 124 if (m_URL == "localhost")
125 {
126 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
127 caps, m_scene.AssetService);
285 128
286 129 caps.RegisterHandler(
287
288 caps.RegisterHandler(
289 "UploadBakedTexture",
290 new RestStreamHandler(
291 "POST",
292 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
293 avatarhandler.UploadBakedTexture,
294 "UploadBakedTexture", 130 "UploadBakedTexture",
295 agentID.ToString())); 131 new RestStreamHandler(
296 132 "POST",
297 133 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
298 134 avatarhandler.UploadBakedTexture,
135 "UploadBakedTexture",
136 agentID.ToString()));
299 137
138 }
139 else
140 {
141 caps.RegisterHandler("UploadBakedTexture", m_URL);
142 }
300 } 143 }
301 } 144 }
302} 145}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 025ffea..8d4e561 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -34,9 +34,7 @@ using log4net;
34using Nini.Config; 34using Nini.Config;
35using Mono.Addins; 35using Mono.Addins;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework; 37using OpenSim.Framework;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
@@ -45,6 +43,9 @@ using OpenSim.Framework.Capabilities;
45using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps; 44using Caps = OpenSim.Framework.Capabilities.Caps;
47using OpenSim.Capabilities.Handlers; 45using OpenSim.Capabilities.Handlers;
46using OpenSim.Framework.Monitoring;
47
48using OpenMetaverse.StructuredData;
48 49
49namespace OpenSim.Region.ClientStack.Linden 50namespace OpenSim.Region.ClientStack.Linden
50{ 51{
@@ -63,7 +64,7 @@ namespace OpenSim.Region.ClientStack.Linden
63 public List<UUID> folders; 64 public List<UUID> folders;
64 } 65 }
65 66
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 67 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 68
68 /// <summary> 69 /// <summary>
69 /// Control whether requests will be processed asynchronously. 70 /// Control whether requests will be processed asynchronously.
@@ -92,14 +93,16 @@ namespace OpenSim.Region.ClientStack.Linden
92 private bool m_Enabled; 93 private bool m_Enabled;
93 94
94 private string m_fetchInventoryDescendents2Url; 95 private string m_fetchInventoryDescendents2Url;
95 private string m_webFetchInventoryDescendentsUrl; 96// private string m_webFetchInventoryDescendentsUrl;
96 97
97 private static FetchInvDescHandler m_webFetchHandler; 98 private static FetchInvDescHandler m_webFetchHandler;
98 99
99 private static Thread[] m_workerThreads = null; 100 private static Thread[] m_workerThreads = null;
100 101
101 private static DoubleQueue<aPollRequest> m_queue = 102 private static OpenSim.Framework.BlockingQueue<aPollRequest> m_queue =
102 new DoubleQueue<aPollRequest>(); 103 new OpenSim.Framework.BlockingQueue<aPollRequest>();
104
105 private static int m_NumberScenes = 0;
103 106
104 #region ISharedRegionModule Members 107 #region ISharedRegionModule Members
105 108
@@ -117,9 +120,10 @@ namespace OpenSim.Region.ClientStack.Linden
117 return; 120 return;
118 121
119 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty); 122 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
120 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty); 123// m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
121 124
122 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty) 125// if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
126 if (m_fetchInventoryDescendents2Url != string.Empty)
123 { 127 {
124 m_Enabled = true; 128 m_Enabled = true;
125 } 129 }
@@ -143,17 +147,7 @@ namespace OpenSim.Region.ClientStack.Linden
143 StatsManager.DeregisterStat(s_processedRequestsStat); 147 StatsManager.DeregisterStat(s_processedRequestsStat);
144 StatsManager.DeregisterStat(s_queuedRequestsStat); 148 StatsManager.DeregisterStat(s_queuedRequestsStat);
145 149
146 if (ProcessQueuedRequestsAsync) 150 m_NumberScenes--;
147 {
148 if (m_workerThreads != null)
149 {
150 foreach (Thread t in m_workerThreads)
151 Watchdog.AbortThread(t.ManagedThreadId);
152
153 m_workerThreads = null;
154 }
155 }
156
157 Scene = null; 151 Scene = null;
158 } 152 }
159 153
@@ -187,7 +181,7 @@ namespace OpenSim.Region.ClientStack.Linden
187 "httpfetch", 181 "httpfetch",
188 StatType.Pull, 182 StatType.Pull,
189 MeasuresOfInterest.AverageChangeOverTime, 183 MeasuresOfInterest.AverageChangeOverTime,
190 stat => { stat.Value = m_queue.Count; }, 184 stat => { stat.Value = m_queue.Count(); },
191 StatVerbosity.Debug); 185 StatVerbosity.Debug);
192 186
193 StatsManager.RegisterStat(s_processedRequestsStat); 187 StatsManager.RegisterStat(s_processedRequestsStat);
@@ -201,6 +195,8 @@ namespace OpenSim.Region.ClientStack.Linden
201 195
202 Scene.EventManager.OnRegisterCaps += RegisterCaps; 196 Scene.EventManager.OnRegisterCaps += RegisterCaps;
203 197
198 m_NumberScenes++;
199
204 int nworkers = 2; // was 2 200 int nworkers = 2; // was 2
205 if (ProcessQueuedRequestsAsync && m_workerThreads == null) 201 if (ProcessQueuedRequestsAsync && m_workerThreads == null)
206 { 202 {
@@ -211,7 +207,7 @@ namespace OpenSim.Region.ClientStack.Linden
211 m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, 207 m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests,
212 String.Format("InventoryWorkerThread{0}", i), 208 String.Format("InventoryWorkerThread{0}", i),
213 ThreadPriority.Normal, 209 ThreadPriority.Normal,
214 false, 210 true,
215 true, 211 true,
216 null, 212 null,
217 int.MaxValue); 213 int.MaxValue);
@@ -223,7 +219,23 @@ namespace OpenSim.Region.ClientStack.Linden
223 { 219 {
224 } 220 }
225 221
226 public void Close() { } 222 public void Close()
223 {
224 if (!m_Enabled)
225 return;
226
227 if (ProcessQueuedRequestsAsync)
228 {
229 if (m_NumberScenes <= 0 && m_workerThreads != null)
230 {
231 m_log.DebugFormat("[WebFetchInvDescModule] Closing");
232 foreach (Thread t in m_workerThreads)
233 Watchdog.AbortThread(t.ManagedThreadId);
234
235 m_workerThreads = null;
236 }
237 }
238 }
227 239
228 public string Name { get { return "WebFetchInvDescModule"; } } 240 public string Name { get { return "WebFetchInvDescModule"; } }
229 241
@@ -312,16 +324,17 @@ namespace OpenSim.Region.ClientStack.Linden
312 { 324 {
313 if (!reqinfo.folders.Contains(folderID)) 325 if (!reqinfo.folders.Contains(folderID))
314 { 326 {
315 //TODO: Port COF handling from Avination 327 if (sp.COF != UUID.Zero && sp.COF == folderID)
328 highPriority = true;
316 reqinfo.folders.Add(folderID); 329 reqinfo.folders.Add(folderID);
317 } 330 }
318 } 331 }
319 } 332 }
320 333
321 if (highPriority) 334 if (highPriority)
322 m_queue.EnqueueHigh(reqinfo); 335 m_queue.PriorityEnqueue(reqinfo);
323 else 336 else
324 m_queue.EnqueueLow(reqinfo); 337 m_queue.Enqueue(reqinfo);
325 }; 338 };
326 339
327 NoEvents = (x, y) => 340 NoEvents = (x, y) =>
@@ -347,6 +360,9 @@ namespace OpenSim.Region.ClientStack.Linden
347 360
348 public void Process(aPollRequest requestinfo) 361 public void Process(aPollRequest requestinfo)
349 { 362 {
363 if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown)
364 return;
365
350 UUID requestID = requestinfo.reqID; 366 UUID requestID = requestinfo.reqID;
351 367
352 Hashtable response = new Hashtable(); 368 Hashtable response = new Hashtable();
@@ -365,7 +381,8 @@ namespace OpenSim.Region.ClientStack.Linden
365 m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); 381 m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054");
366 responses[requestID] = response; 382 responses[requestID] = response;
367 } 383 }
368 384 requestinfo.folders.Clear();
385 requestinfo.request.Clear();
369 WebFetchInvDescModule.ProcessedRequestsCount++; 386 WebFetchInvDescModule.ProcessedRequestsCount++;
370 } 387 }
371 } 388 }
@@ -422,31 +439,25 @@ namespace OpenSim.Region.ClientStack.Linden
422// } 439// }
423// } 440// }
424 441
425 private void DoInventoryRequests() 442 private static void DoInventoryRequests()
426 { 443 {
427 while (true) 444 while (true)
428 { 445 {
446 aPollRequest poolreq = m_queue.Dequeue(4500);
429 Watchdog.UpdateThread(); 447 Watchdog.UpdateThread();
430 448
431 WaitProcessQueuedInventoryRequest(); 449 if (poolreq != null && poolreq.thepoll != null)
432 }
433 }
434
435 public void WaitProcessQueuedInventoryRequest()
436 {
437 aPollRequest poolreq = m_queue.Dequeue();
438
439 if (poolreq != null && poolreq.thepoll != null)
440 {
441 try
442 {
443 poolreq.thepoll.Process(poolreq);
444 }
445 catch (Exception e)
446 { 450 {
447 m_log.ErrorFormat( 451 try
448 "[INVENTORY]: Failed to process queued inventory request {0} for {1} in {2}. Exception {3}", 452 {
449 poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", Scene.Name, e); 453 poolreq.thepoll.Process(poolreq);
454 }
455 catch (Exception e)
456 {
457 m_log.ErrorFormat(
458 "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}",
459 poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e);
460 }
450 } 461 }
451 } 462 }
452 } 463 }