diff options
Diffstat (limited to '')
111 files changed, 3284 insertions, 2273 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 1b4d1ea..5a011ce 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | |||
@@ -94,7 +94,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
94 | 94 | ||
95 | public void Initialise() | 95 | public void Initialise() |
96 | { | 96 | { |
97 | m_log.Info("[RADMIN]: " + Name + " cannot be default-initialized!"); | 97 | m_log.Error("[RADMIN]: " + Name + " cannot be default-initialized!"); |
98 | throw new PluginNotInitialisedException(Name); | 98 | throw new PluginNotInitialisedException(Name); |
99 | } | 99 | } |
100 | 100 | ||
@@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
111 | else | 111 | else |
112 | { | 112 | { |
113 | m_config = m_configSource.Configs["RemoteAdmin"]; | 113 | m_config = m_configSource.Configs["RemoteAdmin"]; |
114 | m_log.Info("[RADMIN]: Remote Admin Plugin Enabled"); | 114 | m_log.Debug("[RADMIN]: Remote Admin Plugin Enabled"); |
115 | m_requiredPassword = m_config.GetString("access_password", String.Empty); | 115 | m_requiredPassword = m_config.GetString("access_password", String.Empty); |
116 | int port = m_config.GetInt("port", 0); | 116 | int port = m_config.GetInt("port", 0); |
117 | 117 | ||
@@ -130,6 +130,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
130 | availableMethods["admin_broadcast"] = XmlRpcAlertMethod; | 130 | availableMethods["admin_broadcast"] = XmlRpcAlertMethod; |
131 | availableMethods["admin_restart"] = XmlRpcRestartMethod; | 131 | availableMethods["admin_restart"] = XmlRpcRestartMethod; |
132 | availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; | 132 | availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; |
133 | availableMethods["admin_save_heightmap"] = XmlRpcSaveHeightmapMethod; | ||
133 | // User management | 134 | // User management |
134 | availableMethods["admin_create_user"] = XmlRpcCreateUserMethod; | 135 | availableMethods["admin_create_user"] = XmlRpcCreateUserMethod; |
135 | availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod; | 136 | availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod; |
@@ -230,8 +231,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
230 | } | 231 | } |
231 | catch (Exception e) | 232 | catch (Exception e) |
232 | { | 233 | { |
233 | m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0}", e.Message); | 234 | m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); |
234 | m_log.DebugFormat("[RADMIN]: Restart region: failed: {0}", e.ToString()); | ||
235 | responseData["accepted"] = false; | 235 | responseData["accepted"] = false; |
236 | responseData["success"] = false; | 236 | responseData["success"] = false; |
237 | responseData["rebooting"] = false; | 237 | responseData["rebooting"] = false; |
@@ -277,8 +277,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
277 | } | 277 | } |
278 | catch (Exception e) | 278 | catch (Exception e) |
279 | { | 279 | { |
280 | m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message); | 280 | m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message, e.StackTrace); |
281 | m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString()); | ||
282 | 281 | ||
283 | responseData["accepted"] = false; | 282 | responseData["accepted"] = false; |
284 | responseData["success"] = false; | 283 | responseData["success"] = false; |
@@ -301,7 +300,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
301 | { | 300 | { |
302 | Hashtable requestData = (Hashtable) request.Params[0]; | 301 | Hashtable requestData = (Hashtable) request.Params[0]; |
303 | 302 | ||
304 | m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request.ToString()); | 303 | m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request); |
305 | // foreach (string k in requestData.Keys) | 304 | // foreach (string k in requestData.Keys) |
306 | // { | 305 | // { |
307 | // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}", | 306 | // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}", |
@@ -348,8 +347,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
348 | } | 347 | } |
349 | catch (Exception e) | 348 | catch (Exception e) |
350 | { | 349 | { |
351 | m_log.ErrorFormat("[RADMIN]: Terrain Loading: failed: {0}", e.Message); | 350 | m_log.ErrorFormat("[RADMIN]: Terrain Loading: failed: {0} {1}", e.Message, e.StackTrace); |
352 | m_log.DebugFormat("[RADMIN]: Terrain Loading: failed: {0}", e.ToString()); | ||
353 | 351 | ||
354 | responseData["success"] = false; | 352 | responseData["success"] = false; |
355 | responseData["error"] = e.Message; | 353 | responseData["error"] = e.Message; |
@@ -360,6 +358,61 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
360 | return response; | 358 | return response; |
361 | } | 359 | } |
362 | 360 | ||
361 | public XmlRpcResponse XmlRpcSaveHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) | ||
362 | |||
363 | { | ||
364 | XmlRpcResponse response = new XmlRpcResponse(); | ||
365 | Hashtable responseData = new Hashtable(); | ||
366 | |||
367 | m_log.Info("[RADMIN]: Save height maps request started"); | ||
368 | |||
369 | try | ||
370 | { | ||
371 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
372 | |||
373 | m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); | ||
374 | |||
375 | CheckStringParameters(request, new string[] { "password", "filename", "regionid" }); | ||
376 | |||
377 | if (m_requiredPassword != String.Empty && | ||
378 | (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword)) | ||
379 | throw new Exception("wrong password"); | ||
380 | |||
381 | string file = (string)requestData["filename"]; | ||
382 | UUID regionID = (UUID)(string)requestData["regionid"]; | ||
383 | m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); | ||
384 | |||
385 | responseData["accepted"] = true; | ||
386 | |||
387 | Scene region = null; | ||
388 | |||
389 | if (!m_application.SceneManager.TryGetScene(regionID, out region)) | ||
390 | throw new Exception("1: unable to get a scene with that name"); | ||
391 | |||
392 | ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>(); | ||
393 | if (null == terrainModule) throw new Exception("terrain module not available"); | ||
394 | |||
395 | terrainModule.SaveToFile(file); | ||
396 | |||
397 | responseData["success"] = false; | ||
398 | |||
399 | response.Value = responseData; | ||
400 | } | ||
401 | catch (Exception e) | ||
402 | { | ||
403 | m_log.ErrorFormat("[RADMIN]: Terrain Saving: failed: {0}", e.Message); | ||
404 | m_log.DebugFormat("[RADMIN]: Terrain Saving: failed: {0}", e.ToString()); | ||
405 | |||
406 | responseData["success"] = false; | ||
407 | responseData["error"] = e.Message; | ||
408 | |||
409 | } | ||
410 | |||
411 | m_log.Info("[RADMIN]: Save height maps request complete"); | ||
412 | |||
413 | return response; | ||
414 | } | ||
415 | |||
363 | public XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request, IPEndPoint remoteClient) | 416 | public XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request, IPEndPoint remoteClient) |
364 | { | 417 | { |
365 | m_log.Info("[RADMIN]: Received Shutdown Administrator Request"); | 418 | m_log.Info("[RADMIN]: Received Shutdown Administrator Request"); |
@@ -417,14 +470,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
417 | } | 470 | } |
418 | catch (Exception e) | 471 | catch (Exception e) |
419 | { | 472 | { |
420 | m_log.ErrorFormat("[RADMIN] Shutdown: failed: {0}", e.Message); | 473 | m_log.ErrorFormat("[RADMIN]: Shutdown: failed: {0} {1}", e.Message, e.StackTrace); |
421 | m_log.DebugFormat("[RADMIN] Shutdown: failed: {0}", e.ToString()); | ||
422 | 474 | ||
423 | responseData["accepted"] = false; | 475 | responseData["accepted"] = false; |
424 | responseData["error"] = e.Message; | 476 | responseData["error"] = e.Message; |
425 | 477 | ||
426 | response.Value = responseData; | 478 | response.Value = responseData; |
427 | } | 479 | } |
480 | |||
428 | m_log.Info("[RADMIN]: Shutdown Administrator Request complete"); | 481 | m_log.Info("[RADMIN]: Shutdown Administrator Request complete"); |
429 | return response; | 482 | return response; |
430 | } | 483 | } |
@@ -725,8 +778,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
725 | } | 778 | } |
726 | catch (Exception e) | 779 | catch (Exception e) |
727 | { | 780 | { |
728 | m_log.ErrorFormat("[RADMIN] CreateRegion: failed {0}", e.Message); | 781 | m_log.ErrorFormat("[RADMIN] CreateRegion: failed {0} {1}", e.Message, e.StackTrace); |
729 | m_log.DebugFormat("[RADMIN] CreateRegion: failed {0}", e.ToString()); | ||
730 | 782 | ||
731 | responseData["success"] = false; | 783 | responseData["success"] = false; |
732 | responseData["error"] = e.Message; | 784 | responseData["error"] = e.Message; |
@@ -792,8 +844,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
792 | } | 844 | } |
793 | catch (Exception e) | 845 | catch (Exception e) |
794 | { | 846 | { |
795 | m_log.ErrorFormat("[RADMIN] DeleteRegion: failed {0}", e.Message); | 847 | m_log.ErrorFormat("[RADMIN] DeleteRegion: failed {0} {1}", e.Message, e.StackTrace); |
796 | m_log.DebugFormat("[RADMIN] DeleteRegion: failed {0}", e.ToString()); | ||
797 | 848 | ||
798 | responseData["success"] = false; | 849 | responseData["success"] = false; |
799 | responseData["error"] = e.Message; | 850 | responseData["error"] = e.Message; |
@@ -884,8 +935,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
884 | } | 935 | } |
885 | catch (Exception e) | 936 | catch (Exception e) |
886 | { | 937 | { |
887 | m_log.ErrorFormat("[RADMIN] CloseRegion: failed {0}", e.Message); | 938 | m_log.ErrorFormat("[RADMIN]: CloseRegion: failed {0} {1}", e.Message, e.StackTrace); |
888 | m_log.DebugFormat("[RADMIN] CloseRegion: failed {0}", e.ToString()); | ||
889 | 939 | ||
890 | responseData["success"] = false; | 940 | responseData["success"] = false; |
891 | responseData["error"] = e.Message; | 941 | responseData["error"] = e.Message; |
@@ -982,8 +1032,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
982 | } | 1032 | } |
983 | catch (Exception e) | 1033 | catch (Exception e) |
984 | { | 1034 | { |
985 | m_log.ErrorFormat("[RADMIN] ModifyRegion: failed {0}", e.Message); | 1035 | m_log.ErrorFormat("[RADMIN] ModifyRegion: failed {0} {1}", e.Message, e.StackTrace); |
986 | m_log.DebugFormat("[RADMIN] ModifyRegion: failed {0}", e.ToString()); | ||
987 | 1036 | ||
988 | responseData["success"] = false; | 1037 | responseData["success"] = false; |
989 | responseData["error"] = e.Message; | 1038 | responseData["error"] = e.Message; |
@@ -1106,8 +1155,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1106 | } | 1155 | } |
1107 | catch (Exception e) | 1156 | catch (Exception e) |
1108 | { | 1157 | { |
1109 | m_log.ErrorFormat("[RADMIN] CreateUser: failed: {0}", e.Message); | 1158 | m_log.ErrorFormat("[RADMIN]: CreateUser: failed: {0} {1}", e.Message, e.StackTrace); |
1110 | m_log.DebugFormat("[RADMIN] CreateUser: failed: {0}", e.ToString()); | ||
1111 | 1159 | ||
1112 | responseData["success"] = false; | 1160 | responseData["success"] = false; |
1113 | responseData["avatar_uuid"] = UUID.Zero.ToString(); | 1161 | responseData["avatar_uuid"] = UUID.Zero.ToString(); |
@@ -1198,8 +1246,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1198 | } | 1246 | } |
1199 | catch (Exception e) | 1247 | catch (Exception e) |
1200 | { | 1248 | { |
1201 | m_log.ErrorFormat("[RADMIN] UserExists: failed: {0}", e.Message); | 1249 | m_log.ErrorFormat("[RADMIN]: UserExists: failed: {0} {1}", e.Message, e.StackTrace); |
1202 | m_log.DebugFormat("[RADMIN] UserExists: failed: {0}", e.ToString()); | ||
1203 | 1250 | ||
1204 | responseData["success"] = false; | 1251 | responseData["success"] = false; |
1205 | responseData["error"] = e.Message; | 1252 | responseData["error"] = e.Message; |
@@ -1372,9 +1419,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1372 | } | 1419 | } |
1373 | catch (Exception e) | 1420 | catch (Exception e) |
1374 | { | 1421 | { |
1375 | 1422 | m_log.ErrorFormat("[RADMIN] UpdateUserAccount: failed: {0} {1}", e.Message, e.StackTrace); | |
1376 | m_log.ErrorFormat("[RADMIN] UpdateUserAccount: failed: {0}", e.Message); | ||
1377 | m_log.DebugFormat("[RADMIN] UpdateUserAccount: failed: {0}", e.ToString()); | ||
1378 | 1423 | ||
1379 | responseData["success"] = false; | 1424 | responseData["success"] = false; |
1380 | responseData["avatar_uuid"] = UUID.Zero.ToString(); | 1425 | responseData["avatar_uuid"] = UUID.Zero.ToString(); |
@@ -1382,6 +1427,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1382 | 1427 | ||
1383 | response.Value = responseData; | 1428 | response.Value = responseData; |
1384 | } | 1429 | } |
1430 | |||
1385 | m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); | 1431 | m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); |
1386 | return response; | 1432 | return response; |
1387 | } | 1433 | } |
@@ -1397,7 +1443,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1397 | 1443 | ||
1398 | private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) | 1444 | private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) |
1399 | { | 1445 | { |
1400 | m_log.DebugFormat("[RADMIN] updateUserAppearance"); | 1446 | m_log.DebugFormat("[RADMIN]: updateUserAppearance"); |
1401 | 1447 | ||
1402 | string defaultMale = m_config.GetString("default_male", "Default Male"); | 1448 | string defaultMale = m_config.GetString("default_male", "Default Male"); |
1403 | string defaultFemale = m_config.GetString("default_female", "Default Female"); | 1449 | string defaultFemale = m_config.GetString("default_female", "Default Female"); |
@@ -1437,16 +1483,16 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1437 | 1483 | ||
1438 | if (String.IsNullOrEmpty(model)) | 1484 | if (String.IsNullOrEmpty(model)) |
1439 | { | 1485 | { |
1440 | m_log.DebugFormat("[RADMIN] Appearance update not requested"); | 1486 | m_log.DebugFormat("[RADMIN]: Appearance update not requested"); |
1441 | return; | 1487 | return; |
1442 | } | 1488 | } |
1443 | 1489 | ||
1444 | m_log.DebugFormat("[RADMIN] Setting appearance for avatar {0}, using model <{1}>", userid, model); | 1490 | m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model); |
1445 | 1491 | ||
1446 | string[] modelSpecifiers = model.Split(); | 1492 | string[] modelSpecifiers = model.Split(); |
1447 | if (modelSpecifiers.Length != 2) | 1493 | if (modelSpecifiers.Length != 2) |
1448 | { | 1494 | { |
1449 | m_log.WarnFormat("[RADMIN] User appearance not set for {0}. Invalid model name : <{1}>", userid, model); | 1495 | m_log.WarnFormat("[RADMIN]: User appearance not set for {0}. Invalid model name : <{1}>", userid, model); |
1450 | // modelSpecifiers = dmodel.Split(); | 1496 | // modelSpecifiers = dmodel.Split(); |
1451 | return; | 1497 | return; |
1452 | } | 1498 | } |
@@ -1457,7 +1503,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1457 | 1503 | ||
1458 | if (modelProfile == null) | 1504 | if (modelProfile == null) |
1459 | { | 1505 | { |
1460 | m_log.WarnFormat("[RADMIN] Requested model ({0}) not found. Appearance unchanged", model); | 1506 | m_log.WarnFormat("[RADMIN]: Requested model ({0}) not found. Appearance unchanged", model); |
1461 | return; | 1507 | return; |
1462 | } | 1508 | } |
1463 | 1509 | ||
@@ -1467,7 +1513,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1467 | 1513 | ||
1468 | EstablishAppearance(userid, modelProfile.PrincipalID); | 1514 | EstablishAppearance(userid, modelProfile.PrincipalID); |
1469 | 1515 | ||
1470 | m_log.DebugFormat("[RADMIN] Finished setting appearance for avatar {0}, using model {1}", | 1516 | m_log.DebugFormat("[RADMIN]: Finished setting appearance for avatar {0}, using model {1}", |
1471 | userid, model); | 1517 | userid, model); |
1472 | } | 1518 | } |
1473 | 1519 | ||
@@ -1479,7 +1525,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1479 | 1525 | ||
1480 | private void EstablishAppearance(UUID destination, UUID source) | 1526 | private void EstablishAppearance(UUID destination, UUID source) |
1481 | { | 1527 | { |
1482 | m_log.DebugFormat("[RADMIN] Initializing inventory for {0} from {1}", destination, source); | 1528 | m_log.DebugFormat("[RADMIN]: Initializing inventory for {0} from {1}", destination, source); |
1483 | Scene scene = m_application.SceneManager.CurrentOrFirstScene; | 1529 | Scene scene = m_application.SceneManager.CurrentOrFirstScene; |
1484 | 1530 | ||
1485 | // If the model has no associated appearance we're done. | 1531 | // If the model has no associated appearance we're done. |
@@ -1501,7 +1547,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1501 | } | 1547 | } |
1502 | catch (Exception e) | 1548 | catch (Exception e) |
1503 | { | 1549 | { |
1504 | m_log.WarnFormat("[RADMIN] Error transferring appearance for {0} : {1}", | 1550 | m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", |
1505 | destination, e.Message); | 1551 | destination, e.Message); |
1506 | } | 1552 | } |
1507 | 1553 | ||
@@ -1532,7 +1578,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1532 | } | 1578 | } |
1533 | catch (Exception e) | 1579 | catch (Exception e) |
1534 | { | 1580 | { |
1535 | m_log.WarnFormat("[RADMIN] Error transferring appearance for {0} : {1}", | 1581 | m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", |
1536 | destination, e.Message); | 1582 | destination, e.Message); |
1537 | } | 1583 | } |
1538 | 1584 | ||
@@ -1567,7 +1613,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1567 | destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; | 1613 | destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; |
1568 | destinationFolder.Version = 1; | 1614 | destinationFolder.Version = 1; |
1569 | inventoryService.AddFolder(destinationFolder); // store base record | 1615 | inventoryService.AddFolder(destinationFolder); // store base record |
1570 | m_log.ErrorFormat("[RADMIN] Created folder for destination {0}", source); | 1616 | m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); |
1571 | } | 1617 | } |
1572 | 1618 | ||
1573 | // Wearables | 1619 | // Wearables |
@@ -1587,6 +1633,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1587 | { | 1633 | { |
1588 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); | 1634 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); |
1589 | destinationItem.Name = item.Name; | 1635 | destinationItem.Name = item.Name; |
1636 | destinationItem.Owner = destination; | ||
1590 | destinationItem.Description = item.Description; | 1637 | destinationItem.Description = item.Description; |
1591 | destinationItem.InvType = item.InvType; | 1638 | destinationItem.InvType = item.InvType; |
1592 | destinationItem.CreatorId = item.CreatorId; | 1639 | destinationItem.CreatorId = item.CreatorId; |
@@ -1606,6 +1653,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1606 | destinationItem.Flags = item.Flags; | 1653 | destinationItem.Flags = item.Flags; |
1607 | destinationItem.CreationDate = item.CreationDate; | 1654 | destinationItem.CreationDate = item.CreationDate; |
1608 | destinationItem.Folder = destinationFolder.ID; | 1655 | destinationItem.Folder = destinationFolder.ID; |
1656 | ApplyNextOwnerPermissions(destinationItem); | ||
1609 | 1657 | ||
1610 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); | 1658 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); |
1611 | m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); | 1659 | m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); |
@@ -1640,6 +1688,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1640 | { | 1688 | { |
1641 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); | 1689 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); |
1642 | destinationItem.Name = item.Name; | 1690 | destinationItem.Name = item.Name; |
1691 | destinationItem.Owner = destination; | ||
1643 | destinationItem.Description = item.Description; | 1692 | destinationItem.Description = item.Description; |
1644 | destinationItem.InvType = item.InvType; | 1693 | destinationItem.InvType = item.InvType; |
1645 | destinationItem.CreatorId = item.CreatorId; | 1694 | destinationItem.CreatorId = item.CreatorId; |
@@ -1659,6 +1708,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1659 | destinationItem.Flags = item.Flags; | 1708 | destinationItem.Flags = item.Flags; |
1660 | destinationItem.CreationDate = item.CreationDate; | 1709 | destinationItem.CreationDate = item.CreationDate; |
1661 | destinationItem.Folder = destinationFolder.ID; | 1710 | destinationItem.Folder = destinationFolder.ID; |
1711 | ApplyNextOwnerPermissions(destinationItem); | ||
1662 | 1712 | ||
1663 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); | 1713 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); |
1664 | m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); | 1714 | m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); |
@@ -1716,13 +1766,17 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1716 | { | 1766 | { |
1717 | destinationFolder = new InventoryFolderBase(); | 1767 | destinationFolder = new InventoryFolderBase(); |
1718 | destinationFolder.ID = UUID.Random(); | 1768 | destinationFolder.ID = UUID.Random(); |
1719 | destinationFolder.Name = assetType.ToString(); | 1769 | if (assetType == AssetType.Clothing) { |
1770 | destinationFolder.Name = "Clothing"; | ||
1771 | } else { | ||
1772 | destinationFolder.Name = "Body Parts"; | ||
1773 | } | ||
1720 | destinationFolder.Owner = destination; | 1774 | destinationFolder.Owner = destination; |
1721 | destinationFolder.Type = (short)assetType; | 1775 | destinationFolder.Type = (short)assetType; |
1722 | destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; | 1776 | destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; |
1723 | destinationFolder.Version = 1; | 1777 | destinationFolder.Version = 1; |
1724 | inventoryService.AddFolder(destinationFolder); // store base record | 1778 | inventoryService.AddFolder(destinationFolder); // store base record |
1725 | m_log.ErrorFormat("[RADMIN] Created folder for destination {0}", source); | 1779 | m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); |
1726 | } | 1780 | } |
1727 | 1781 | ||
1728 | InventoryFolderBase extraFolder; | 1782 | InventoryFolderBase extraFolder; |
@@ -1740,7 +1794,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1740 | extraFolder.ParentID = destinationFolder.ID; | 1794 | extraFolder.ParentID = destinationFolder.ID; |
1741 | inventoryService.AddFolder(extraFolder); | 1795 | inventoryService.AddFolder(extraFolder); |
1742 | 1796 | ||
1743 | m_log.DebugFormat("[RADMIN] Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); | 1797 | m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); |
1744 | 1798 | ||
1745 | List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items; | 1799 | List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items; |
1746 | 1800 | ||
@@ -1748,6 +1802,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1748 | { | 1802 | { |
1749 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); | 1803 | InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); |
1750 | destinationItem.Name = item.Name; | 1804 | destinationItem.Name = item.Name; |
1805 | destinationItem.Owner = destination; | ||
1751 | destinationItem.Description = item.Description; | 1806 | destinationItem.Description = item.Description; |
1752 | destinationItem.InvType = item.InvType; | 1807 | destinationItem.InvType = item.InvType; |
1753 | destinationItem.CreatorId = item.CreatorId; | 1808 | destinationItem.CreatorId = item.CreatorId; |
@@ -1767,6 +1822,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1767 | destinationItem.Flags = item.Flags; | 1822 | destinationItem.Flags = item.Flags; |
1768 | destinationItem.CreationDate = item.CreationDate; | 1823 | destinationItem.CreationDate = item.CreationDate; |
1769 | destinationItem.Folder = extraFolder.ID; | 1824 | destinationItem.Folder = extraFolder.ID; |
1825 | ApplyNextOwnerPermissions(destinationItem); | ||
1770 | 1826 | ||
1771 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); | 1827 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); |
1772 | inventoryMap.Add(item.ID, destinationItem.ID); | 1828 | inventoryMap.Add(item.ID, destinationItem.ID); |
@@ -1784,6 +1840,29 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1784 | } | 1840 | } |
1785 | 1841 | ||
1786 | /// <summary> | 1842 | /// <summary> |
1843 | /// Apply next owner permissions. | ||
1844 | /// </summary> | ||
1845 | |||
1846 | private void ApplyNextOwnerPermissions(InventoryItemBase item) | ||
1847 | { | ||
1848 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | ||
1849 | { | ||
1850 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1851 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1852 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1853 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1854 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1855 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1856 | } | ||
1857 | item.CurrentPermissions &= item.NextPermissions; | ||
1858 | item.BasePermissions &= item.NextPermissions; | ||
1859 | item.EveryOnePermissions &= item.NextPermissions; | ||
1860 | // item.OwnerChanged = true; | ||
1861 | // item.PermsMask = 0; | ||
1862 | // item.PermsGranter = UUID.Zero; | ||
1863 | } | ||
1864 | |||
1865 | /// <summary> | ||
1787 | /// This method is called if a given model avatar name can not be found. If the external | 1866 | /// This method is called if a given model avatar name can not be found. If the external |
1788 | /// file has already been loaded once, then control returns immediately. If not, then it | 1867 | /// file has already been loaded once, then control returns immediately. If not, then it |
1789 | /// looks for a default appearance file. This file contains XML definitions of zero or more named | 1868 | /// looks for a default appearance file. This file contains XML definitions of zero or more named |
@@ -1792,7 +1871,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1792 | /// indicate which outfit is the default, and this outfit will be automatically worn. The | 1871 | /// indicate which outfit is the default, and this outfit will be automatically worn. The |
1793 | /// other outfits are provided to allow "real" avatars a way to easily change their outfits. | 1872 | /// other outfits are provided to allow "real" avatars a way to easily change their outfits. |
1794 | /// </summary> | 1873 | /// </summary> |
1795 | |||
1796 | private bool CreateDefaultAvatars() | 1874 | private bool CreateDefaultAvatars() |
1797 | { | 1875 | { |
1798 | // Only load once | 1876 | // Only load once |
@@ -1801,7 +1879,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1801 | return false; | 1879 | return false; |
1802 | } | 1880 | } |
1803 | 1881 | ||
1804 | m_log.DebugFormat("[RADMIN] Creating default avatar entries"); | 1882 | m_log.DebugFormat("[RADMIN]: Creating default avatar entries"); |
1805 | 1883 | ||
1806 | m_defaultAvatarsLoaded = true; | 1884 | m_defaultAvatarsLoaded = true; |
1807 | 1885 | ||
@@ -1857,7 +1935,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1857 | 1935 | ||
1858 | foreach (XmlElement avatar in avatars) | 1936 | foreach (XmlElement avatar in avatars) |
1859 | { | 1937 | { |
1860 | m_log.DebugFormat("[RADMIN] Loading appearance for {0}, gender = {1}", | 1938 | m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}", |
1861 | GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); | 1939 | GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); |
1862 | 1940 | ||
1863 | // Create the user identified by the avatar entry | 1941 | // Create the user identified by the avatar entry |
@@ -1879,7 +1957,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1879 | account = CreateUser(scopeID, names[0], names[1], password, email); | 1957 | account = CreateUser(scopeID, names[0], names[1], password, email); |
1880 | if (null == account) | 1958 | if (null == account) |
1881 | { | 1959 | { |
1882 | m_log.ErrorFormat("[RADMIN] Avatar {0} {1} was not created", names[0], names[1]); | 1960 | m_log.ErrorFormat("[RADMIN]: Avatar {0} {1} was not created", names[0], names[1]); |
1883 | return false; | 1961 | return false; |
1884 | } | 1962 | } |
1885 | } | 1963 | } |
@@ -1897,12 +1975,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1897 | 1975 | ||
1898 | ID = account.PrincipalID; | 1976 | ID = account.PrincipalID; |
1899 | 1977 | ||
1900 | m_log.DebugFormat("[RADMIN] User {0}[{1}] created or retrieved", name, ID); | 1978 | m_log.DebugFormat("[RADMIN]: User {0}[{1}] created or retrieved", name, ID); |
1901 | include = true; | 1979 | include = true; |
1902 | } | 1980 | } |
1903 | catch (Exception e) | 1981 | catch (Exception e) |
1904 | { | 1982 | { |
1905 | m_log.DebugFormat("[RADMIN] Error creating user {0} : {1}", name, e.Message); | 1983 | m_log.DebugFormat("[RADMIN]: Error creating user {0} : {1}", name, e.Message); |
1906 | include = false; | 1984 | include = false; |
1907 | } | 1985 | } |
1908 | 1986 | ||
@@ -1942,7 +2020,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1942 | clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID; | 2020 | clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID; |
1943 | clothingFolder.Version = 1; | 2021 | clothingFolder.Version = 1; |
1944 | inventoryService.AddFolder(clothingFolder); // store base record | 2022 | inventoryService.AddFolder(clothingFolder); // store base record |
1945 | m_log.ErrorFormat("[RADMIN] Created clothing folder for {0}/{1}", name, ID); | 2023 | m_log.ErrorFormat("[RADMIN]: Created clothing folder for {0}/{1}", name, ID); |
1946 | } | 2024 | } |
1947 | 2025 | ||
1948 | // OK, now we have an inventory for the user, read in the outfits from the | 2026 | // OK, now we have an inventory for the user, read in the outfits from the |
@@ -1955,7 +2033,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1955 | 2033 | ||
1956 | foreach (XmlElement outfit in outfits) | 2034 | foreach (XmlElement outfit in outfits) |
1957 | { | 2035 | { |
1958 | m_log.DebugFormat("[RADMIN] Loading outfit {0} for {1}", | 2036 | m_log.DebugFormat("[RADMIN]: Loading outfit {0} for {1}", |
1959 | GetStringAttribute(outfit,"name","?"), GetStringAttribute(avatar,"name","?")); | 2037 | GetStringAttribute(outfit,"name","?"), GetStringAttribute(avatar,"name","?")); |
1960 | 2038 | ||
1961 | outfitName = GetStringAttribute(outfit,"name",""); | 2039 | outfitName = GetStringAttribute(outfit,"name",""); |
@@ -1979,7 +2057,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1979 | // Otherwise, we must create the folder. | 2057 | // Otherwise, we must create the folder. |
1980 | if (extraFolder == null) | 2058 | if (extraFolder == null) |
1981 | { | 2059 | { |
1982 | m_log.DebugFormat("[RADMIN] Creating outfit folder {0} for {1}", outfitName, name); | 2060 | m_log.DebugFormat("[RADMIN]: Creating outfit folder {0} for {1}", outfitName, name); |
1983 | extraFolder = new InventoryFolderBase(); | 2061 | extraFolder = new InventoryFolderBase(); |
1984 | extraFolder.ID = UUID.Random(); | 2062 | extraFolder.ID = UUID.Random(); |
1985 | extraFolder.Name = outfitName; | 2063 | extraFolder.Name = outfitName; |
@@ -1988,7 +2066,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
1988 | extraFolder.Version = 1; | 2066 | extraFolder.Version = 1; |
1989 | extraFolder.ParentID = clothingFolder.ID; | 2067 | extraFolder.ParentID = clothingFolder.ID; |
1990 | inventoryService.AddFolder(extraFolder); | 2068 | inventoryService.AddFolder(extraFolder); |
1991 | m_log.DebugFormat("[RADMIN] Adding outfile folder {0} to folder {1}", extraFolder.ID, clothingFolder.ID); | 2069 | m_log.DebugFormat("[RADMIN]: Adding outfile folder {0} to folder {1}", extraFolder.ID, clothingFolder.ID); |
1992 | } | 2070 | } |
1993 | 2071 | ||
1994 | // Now get the pieces that make up the outfit | 2072 | // Now get the pieces that make up the outfit |
@@ -2003,7 +2081,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2003 | switch (child.Name) | 2081 | switch (child.Name) |
2004 | { | 2082 | { |
2005 | case "Permissions" : | 2083 | case "Permissions" : |
2006 | m_log.DebugFormat("[RADMIN] Permissions specified"); | 2084 | m_log.DebugFormat("[RADMIN]: Permissions specified"); |
2007 | perms = child; | 2085 | perms = child; |
2008 | break; | 2086 | break; |
2009 | case "Asset" : | 2087 | case "Asset" : |
@@ -2053,7 +2131,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2053 | inventoryItem.Folder = extraFolder.ID; // Parent folder | 2131 | inventoryItem.Folder = extraFolder.ID; // Parent folder |
2054 | 2132 | ||
2055 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(inventoryItem); | 2133 | m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(inventoryItem); |
2056 | m_log.DebugFormat("[RADMIN] Added item {0} to folder {1}", inventoryItem.ID, extraFolder.ID); | 2134 | m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", inventoryItem.ID, extraFolder.ID); |
2057 | } | 2135 | } |
2058 | 2136 | ||
2059 | // Attach item, if attachpoint is specified | 2137 | // Attach item, if attachpoint is specified |
@@ -2061,7 +2139,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2061 | if (attachpoint != 0) | 2139 | if (attachpoint != 0) |
2062 | { | 2140 | { |
2063 | avatarAppearance.SetAttachment(attachpoint, inventoryItem.ID, inventoryItem.AssetID); | 2141 | avatarAppearance.SetAttachment(attachpoint, inventoryItem.ID, inventoryItem.AssetID); |
2064 | m_log.DebugFormat("[RADMIN] Attached {0}", inventoryItem.ID); | 2142 | m_log.DebugFormat("[RADMIN]: Attached {0}", inventoryItem.ID); |
2065 | } | 2143 | } |
2066 | 2144 | ||
2067 | // Record whether or not the item is to be initially worn | 2145 | // Record whether or not the item is to be initially worn |
@@ -2074,32 +2152,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2074 | } | 2152 | } |
2075 | catch (Exception e) | 2153 | catch (Exception e) |
2076 | { | 2154 | { |
2077 | m_log.WarnFormat("[RADMIN] Error wearing item {0} : {1}", inventoryItem.ID, e.Message); | 2155 | m_log.WarnFormat("[RADMIN]: Error wearing item {0} : {1}", inventoryItem.ID, e.Message); |
2078 | } | 2156 | } |
2079 | } // foreach item in outfit | 2157 | } // foreach item in outfit |
2080 | m_log.DebugFormat("[RADMIN] Outfit {0} load completed", outfitName); | 2158 | m_log.DebugFormat("[RADMIN]: Outfit {0} load completed", outfitName); |
2081 | } // foreach outfit | 2159 | } // foreach outfit |
2082 | m_log.DebugFormat("[RADMIN] Inventory update complete for {0}", name); | 2160 | m_log.DebugFormat("[RADMIN]: Inventory update complete for {0}", name); |
2083 | scene.AvatarService.SetAppearance(ID, avatarAppearance); | 2161 | scene.AvatarService.SetAppearance(ID, avatarAppearance); |
2084 | } | 2162 | } |
2085 | catch (Exception e) | 2163 | catch (Exception e) |
2086 | { | 2164 | { |
2087 | m_log.WarnFormat("[RADMIN] Inventory processing incomplete for user {0} : {1}", | 2165 | m_log.WarnFormat("[RADMIN]: Inventory processing incomplete for user {0} : {1}", |
2088 | name, e.Message); | 2166 | name, e.Message); |
2089 | } | 2167 | } |
2090 | } // End of include | 2168 | } // End of include |
2091 | } | 2169 | } |
2092 | m_log.DebugFormat("[RADMIN] Default avatar loading complete"); | 2170 | m_log.DebugFormat("[RADMIN]: Default avatar loading complete"); |
2093 | } | 2171 | } |
2094 | else | 2172 | else |
2095 | { | 2173 | { |
2096 | m_log.DebugFormat("[RADMIN] No default avatar information available"); | 2174 | m_log.DebugFormat("[RADMIN]: No default avatar information available"); |
2097 | return false; | 2175 | return false; |
2098 | } | 2176 | } |
2099 | } | 2177 | } |
2100 | catch (Exception e) | 2178 | catch (Exception e) |
2101 | { | 2179 | { |
2102 | m_log.WarnFormat("[RADMIN] Exception whilst loading default avatars ; {0}", e.Message); | 2180 | m_log.WarnFormat("[RADMIN]: Exception whilst loading default avatars ; {0}", e.Message); |
2103 | return false; | 2181 | return false; |
2104 | } | 2182 | } |
2105 | 2183 | ||
@@ -2194,8 +2272,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2194 | } | 2272 | } |
2195 | catch (Exception e) | 2273 | catch (Exception e) |
2196 | { | 2274 | { |
2197 | m_log.InfoFormat("[RADMIN] LoadOAR: {0}", e.Message); | 2275 | m_log.ErrorFormat("[RADMIN]: LoadOAR: {0} {1}", e.Message, e.StackTrace); |
2198 | m_log.DebugFormat("[RADMIN] LoadOAR: {0}", e.ToString()); | ||
2199 | 2276 | ||
2200 | responseData["loaded"] = false; | 2277 | responseData["loaded"] = false; |
2201 | responseData["error"] = e.Message; | 2278 | responseData["error"] = e.Message; |
@@ -2300,8 +2377,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2300 | } | 2377 | } |
2301 | catch (Exception e) | 2378 | catch (Exception e) |
2302 | { | 2379 | { |
2303 | m_log.InfoFormat("[RADMIN] SaveOAR: {0}", e.Message); | 2380 | m_log.ErrorFormat("[RADMIN]: SaveOAR: {0} {1}", e.Message, e.StackTrace); |
2304 | m_log.DebugFormat("[RADMIN] SaveOAR: {0}", e.ToString()); | ||
2305 | 2381 | ||
2306 | responseData["saved"] = false; | 2382 | responseData["saved"] = false; |
2307 | responseData["error"] = e.Message; | 2383 | responseData["error"] = e.Message; |
@@ -2315,7 +2391,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2315 | 2391 | ||
2316 | private void RemoteAdminOarSaveCompleted(Guid uuid, string name) | 2392 | private void RemoteAdminOarSaveCompleted(Guid uuid, string name) |
2317 | { | 2393 | { |
2318 | m_log.DebugFormat("[RADMIN] File processing complete for {0}", name); | 2394 | m_log.DebugFormat("[RADMIN]: File processing complete for {0}", name); |
2319 | lock (m_saveOarLock) Monitor.Pulse(m_saveOarLock); | 2395 | lock (m_saveOarLock) Monitor.Pulse(m_saveOarLock); |
2320 | } | 2396 | } |
2321 | 2397 | ||
@@ -2353,14 +2429,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2353 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2429 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2354 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2430 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2355 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2431 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2356 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2432 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2357 | } | 2433 | } |
2358 | else if (requestData.Contains("region_name")) | 2434 | else if (requestData.Contains("region_name")) |
2359 | { | 2435 | { |
2360 | string region_name = (string) requestData["region_name"]; | 2436 | string region_name = (string) requestData["region_name"]; |
2361 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2437 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2362 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2438 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2363 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2439 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2364 | } | 2440 | } |
2365 | else throw new Exception("neither region_name nor region_uuid given"); | 2441 | else throw new Exception("neither region_name nor region_uuid given"); |
2366 | 2442 | ||
@@ -2391,8 +2467,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2391 | } | 2467 | } |
2392 | catch (Exception e) | 2468 | catch (Exception e) |
2393 | { | 2469 | { |
2394 | m_log.InfoFormat("[RADMIN] LoadXml: {0}", e.Message); | 2470 | m_log.ErrorFormat("[RADMIN] LoadXml: {0} {1}", e.Message, e.StackTrace); |
2395 | m_log.DebugFormat("[RADMIN] LoadXml: {0}", e.ToString()); | ||
2396 | 2471 | ||
2397 | responseData["loaded"] = false; | 2472 | responseData["loaded"] = false; |
2398 | responseData["switched"] = false; | 2473 | responseData["switched"] = false; |
@@ -2438,14 +2513,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2438 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2513 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2439 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2514 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2440 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2515 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2441 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2516 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2442 | } | 2517 | } |
2443 | else if (requestData.Contains("region_name")) | 2518 | else if (requestData.Contains("region_name")) |
2444 | { | 2519 | { |
2445 | string region_name = (string) requestData["region_name"]; | 2520 | string region_name = (string) requestData["region_name"]; |
2446 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2521 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2447 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2522 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2448 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2523 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2449 | } | 2524 | } |
2450 | else throw new Exception("neither region_name nor region_uuid given"); | 2525 | else throw new Exception("neither region_name nor region_uuid given"); |
2451 | 2526 | ||
@@ -2477,8 +2552,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2477 | } | 2552 | } |
2478 | catch (Exception e) | 2553 | catch (Exception e) |
2479 | { | 2554 | { |
2480 | m_log.InfoFormat("[RADMIN] SaveXml: {0}", e.Message); | 2555 | m_log.ErrorFormat("[RADMIN]: SaveXml: {0} {1}", e.Message, e.StackTrace); |
2481 | m_log.DebugFormat("[RADMIN] SaveXml: {0}", e.ToString()); | ||
2482 | 2556 | ||
2483 | responseData["saved"] = false; | 2557 | responseData["saved"] = false; |
2484 | responseData["switched"] = false; | 2558 | responseData["switched"] = false; |
@@ -2517,14 +2591,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2517 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2591 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2518 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2592 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2519 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2593 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2520 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2594 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2521 | } | 2595 | } |
2522 | else if (requestData.Contains("region_name")) | 2596 | else if (requestData.Contains("region_name")) |
2523 | { | 2597 | { |
2524 | string region_name = (string) requestData["region_name"]; | 2598 | string region_name = (string) requestData["region_name"]; |
2525 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2599 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2526 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2600 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2527 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2601 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2528 | } | 2602 | } |
2529 | else throw new Exception("neither region_name nor region_uuid given"); | 2603 | else throw new Exception("neither region_name nor region_uuid given"); |
2530 | 2604 | ||
@@ -2536,7 +2610,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2536 | } | 2610 | } |
2537 | catch (Exception e) | 2611 | catch (Exception e) |
2538 | { | 2612 | { |
2539 | m_log.InfoFormat("[RADMIN] RegionQuery: {0}", e.Message); | 2613 | m_log.InfoFormat("[RADMIN]: RegionQuery: {0}", e.Message); |
2540 | 2614 | ||
2541 | responseData["success"] = false; | 2615 | responseData["success"] = false; |
2542 | responseData["error"] = e.Message; | 2616 | responseData["error"] = e.Message; |
@@ -2577,7 +2651,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2577 | } | 2651 | } |
2578 | catch (Exception e) | 2652 | catch (Exception e) |
2579 | { | 2653 | { |
2580 | m_log.InfoFormat("[RADMIN] ConsoleCommand: {0}", e.Message); | 2654 | m_log.InfoFormat("[RADMIN]: ConsoleCommand: {0}", e.Message); |
2581 | 2655 | ||
2582 | responseData["success"] = false; | 2656 | responseData["success"] = false; |
2583 | responseData["error"] = e.Message; | 2657 | responseData["error"] = e.Message; |
@@ -2614,14 +2688,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2614 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2688 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2615 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2689 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2616 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2690 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2617 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2691 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2618 | } | 2692 | } |
2619 | else if (requestData.Contains("region_name")) | 2693 | else if (requestData.Contains("region_name")) |
2620 | { | 2694 | { |
2621 | string region_name = (string) requestData["region_name"]; | 2695 | string region_name = (string) requestData["region_name"]; |
2622 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2696 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2623 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2697 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2624 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2698 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2625 | } | 2699 | } |
2626 | else throw new Exception("neither region_name nor region_uuid given"); | 2700 | else throw new Exception("neither region_name nor region_uuid given"); |
2627 | 2701 | ||
@@ -2632,7 +2706,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2632 | } | 2706 | } |
2633 | catch (Exception e) | 2707 | catch (Exception e) |
2634 | { | 2708 | { |
2635 | m_log.InfoFormat("[RADMIN] Access List Clear Request: {0}", e.Message); | 2709 | m_log.ErrorFormat("[RADMIN]: Access List Clear Request: {0} {1}", e.Message, e.StackTrace); |
2636 | 2710 | ||
2637 | responseData["success"] = false; | 2711 | responseData["success"] = false; |
2638 | responseData["error"] = e.Message; | 2712 | responseData["error"] = e.Message; |
@@ -2671,14 +2745,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2671 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2745 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2672 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2746 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2673 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2747 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2674 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2748 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2675 | } | 2749 | } |
2676 | else if (requestData.Contains("region_name")) | 2750 | else if (requestData.Contains("region_name")) |
2677 | { | 2751 | { |
2678 | string region_name = (string) requestData["region_name"]; | 2752 | string region_name = (string) requestData["region_name"]; |
2679 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2753 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2680 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2754 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2681 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2755 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2682 | } | 2756 | } |
2683 | else throw new Exception("neither region_name nor region_uuid given"); | 2757 | else throw new Exception("neither region_name nor region_uuid given"); |
2684 | 2758 | ||
@@ -2698,7 +2772,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2698 | if (account != null) | 2772 | if (account != null) |
2699 | { | 2773 | { |
2700 | uuids.Add(account.PrincipalID); | 2774 | uuids.Add(account.PrincipalID); |
2701 | m_log.DebugFormat("[RADMIN] adding \"{0}\" to ACL for \"{1}\"", name, scene.RegionInfo.RegionName); | 2775 | m_log.DebugFormat("[RADMIN]: adding \"{0}\" to ACL for \"{1}\"", name, scene.RegionInfo.RegionName); |
2702 | } | 2776 | } |
2703 | } | 2777 | } |
2704 | List<UUID> accessControlList = new List<UUID>(scene.RegionInfo.EstateSettings.EstateAccess); | 2778 | List<UUID> accessControlList = new List<UUID>(scene.RegionInfo.EstateSettings.EstateAccess); |
@@ -2719,7 +2793,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2719 | } | 2793 | } |
2720 | catch (Exception e) | 2794 | catch (Exception e) |
2721 | { | 2795 | { |
2722 | m_log.InfoFormat("[RADMIN] Access List Add Request: {0}", e.Message); | 2796 | m_log.ErrorFormat("[RADMIN]: Access List Add Request: {0} {1}", e.Message, e.StackTrace); |
2723 | 2797 | ||
2724 | responseData["success"] = false; | 2798 | responseData["success"] = false; |
2725 | responseData["error"] = e.Message; | 2799 | responseData["error"] = e.Message; |
@@ -2758,14 +2832,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2758 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2832 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2759 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2833 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2760 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2834 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2761 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2835 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2762 | } | 2836 | } |
2763 | else if (requestData.Contains("region_name")) | 2837 | else if (requestData.Contains("region_name")) |
2764 | { | 2838 | { |
2765 | string region_name = (string) requestData["region_name"]; | 2839 | string region_name = (string) requestData["region_name"]; |
2766 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2840 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2767 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2841 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2768 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2842 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2769 | } | 2843 | } |
2770 | else throw new Exception("neither region_name nor region_uuid given"); | 2844 | else throw new Exception("neither region_name nor region_uuid given"); |
2771 | 2845 | ||
@@ -2806,7 +2880,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2806 | } | 2880 | } |
2807 | catch (Exception e) | 2881 | catch (Exception e) |
2808 | { | 2882 | { |
2809 | m_log.InfoFormat("[RADMIN] Access List Remove Request: {0}", e.Message); | 2883 | m_log.ErrorFormat("[RADMIN]: Access List Remove Request: {0} {1}", e.Message, e.StackTrace); |
2810 | 2884 | ||
2811 | responseData["success"] = false; | 2885 | responseData["success"] = false; |
2812 | responseData["error"] = e.Message; | 2886 | responseData["error"] = e.Message; |
@@ -2845,14 +2919,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2845 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; | 2919 | UUID region_uuid = (UUID) (string) requestData["region_uuid"]; |
2846 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) | 2920 | if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) |
2847 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); | 2921 | throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); |
2848 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString()); | 2922 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); |
2849 | } | 2923 | } |
2850 | else if (requestData.Contains("region_name")) | 2924 | else if (requestData.Contains("region_name")) |
2851 | { | 2925 | { |
2852 | string region_name = (string) requestData["region_name"]; | 2926 | string region_name = (string) requestData["region_name"]; |
2853 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) | 2927 | if (!m_application.SceneManager.TrySetCurrentScene(region_name)) |
2854 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); | 2928 | throw new Exception(String.Format("failed to switch to region {0}", region_name)); |
2855 | m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name); | 2929 | m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); |
2856 | } | 2930 | } |
2857 | else throw new Exception("neither region_name nor region_uuid given"); | 2931 | else throw new Exception("neither region_name nor region_uuid given"); |
2858 | 2932 | ||
@@ -2874,7 +2948,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController | |||
2874 | } | 2948 | } |
2875 | catch (Exception e) | 2949 | catch (Exception e) |
2876 | { | 2950 | { |
2877 | m_log.InfoFormat("[RADMIN] Acces List List: {0}", e.Message); | 2951 | m_log.ErrorFormat("[RADMIN]: Access List List: {0} {1}", e.Message, e.StackTrace); |
2878 | 2952 | ||
2879 | responseData["success"] = false; | 2953 | responseData["success"] = false; |
2880 | responseData["error"] = e.Message; | 2954 | responseData["error"] = e.Message; |
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index d1a0440..a604a2e 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs | |||
@@ -1337,12 +1337,12 @@ namespace OpenSim.Client.MXP.ClientStack | |||
1337 | // Need to translate to MXP somehow | 1337 | // Need to translate to MXP somehow |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) | 1340 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
1341 | { | 1341 | { |
1342 | //throw new System.NotImplementedException(); | 1342 | //throw new System.NotImplementedException(); |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) | 1345 | public void SendObjectPropertiesReply(ISceneEntity entity) |
1346 | { | 1346 | { |
1347 | //throw new System.NotImplementedException(); | 1347 | //throw new System.NotImplementedException(); |
1348 | } | 1348 | } |
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index fc27f01..d8cd0ac 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs | |||
@@ -884,12 +884,12 @@ namespace OpenSim.Client.VWoHTTP.ClientStack | |||
884 | throw new System.NotImplementedException(); | 884 | throw new System.NotImplementedException(); |
885 | } | 885 | } |
886 | 886 | ||
887 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) | 887 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
888 | { | 888 | { |
889 | throw new System.NotImplementedException(); | 889 | throw new System.NotImplementedException(); |
890 | } | 890 | } |
891 | 891 | ||
892 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) | 892 | public void SendObjectPropertiesReply(ISceneEntity entity) |
893 | { | 893 | { |
894 | throw new System.NotImplementedException(); | 894 | throw new System.NotImplementedException(); |
895 | } | 895 | } |
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 8efe4e9..50b6dbe 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | |||
@@ -39,6 +39,8 @@ namespace OpenSim.Data.MySQL | |||
39 | { | 39 | { |
40 | public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new() | 40 | public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new() |
41 | { | 41 | { |
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
43 | |||
42 | protected Dictionary<string, FieldInfo> m_Fields = | 44 | protected Dictionary<string, FieldInfo> m_Fields = |
43 | new Dictionary<string, FieldInfo>(); | 45 | new Dictionary<string, FieldInfo>(); |
44 | 46 | ||
@@ -217,7 +219,6 @@ namespace OpenSim.Data.MySQL | |||
217 | { | 219 | { |
218 | using (MySqlCommand cmd = new MySqlCommand()) | 220 | using (MySqlCommand cmd = new MySqlCommand()) |
219 | { | 221 | { |
220 | |||
221 | string query = ""; | 222 | string query = ""; |
222 | List<String> names = new List<String>(); | 223 | List<String> names = new List<String>(); |
223 | List<String> values = new List<String>(); | 224 | List<String> values = new List<String>(); |
@@ -226,6 +227,16 @@ namespace OpenSim.Data.MySQL | |||
226 | { | 227 | { |
227 | names.Add(fi.Name); | 228 | names.Add(fi.Name); |
228 | values.Add("?" + fi.Name); | 229 | values.Add("?" + fi.Name); |
230 | |||
231 | // Temporarily return more information about what field is unexpectedly null for | ||
232 | // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the | ||
233 | // InventoryTransferModule or we may be required to substitute a DBNull here. | ||
234 | if (fi.GetValue(row) == null) | ||
235 | throw new NullReferenceException( | ||
236 | string.Format( | ||
237 | "[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", | ||
238 | fi.Name, row)); | ||
239 | |||
229 | cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); | 240 | cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); |
230 | } | 241 | } |
231 | 242 | ||
@@ -268,4 +279,4 @@ namespace OpenSim.Data.MySQL | |||
268 | } | 279 | } |
269 | } | 280 | } |
270 | } | 281 | } |
271 | } | 282 | } \ No newline at end of file |
diff --git a/OpenSim/Data/Null/NullEstateData.cs b/OpenSim/Data/Null/NullEstateData.cs index 0cebff5..8db8064 100755 --- a/OpenSim/Data/Null/NullEstateData.cs +++ b/OpenSim/Data/Null/NullEstateData.cs | |||
@@ -38,9 +38,9 @@ namespace OpenSim.Data.Null | |||
38 | { | 38 | { |
39 | public class NullEstateStore : IEstateDataStore | 39 | public class NullEstateStore : IEstateDataStore |
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 42 | ||
43 | private string m_connectionString; | 43 | // private string m_connectionString; |
44 | 44 | ||
45 | protected virtual Assembly Assembly | 45 | protected virtual Assembly Assembly |
46 | { | 46 | { |
@@ -58,7 +58,7 @@ namespace OpenSim.Data.Null | |||
58 | 58 | ||
59 | public void Initialise(string connectionString) | 59 | public void Initialise(string connectionString) |
60 | { | 60 | { |
61 | m_connectionString = connectionString; | 61 | // m_connectionString = connectionString; |
62 | } | 62 | } |
63 | 63 | ||
64 | private string[] FieldList | 64 | private string[] FieldList |
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 52bcd55..be36cf2 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs | |||
@@ -592,9 +592,7 @@ namespace OpenSim.Framework.Console | |||
592 | string line = ReadLine(m_defaultPrompt + "# ", true, true); | 592 | string line = ReadLine(m_defaultPrompt + "# ", true, true); |
593 | 593 | ||
594 | if (line != String.Empty) | 594 | if (line != String.Empty) |
595 | { | 595 | Output("Invalid command"); |
596 | m_log.Info("[CONSOLE] Invalid command"); | ||
597 | } | ||
598 | } | 596 | } |
599 | 597 | ||
600 | public void RunCommand(string cmd) | 598 | public void RunCommand(string cmd) |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 5bf0b7b..f573c32 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -570,16 +570,35 @@ namespace OpenSim.Framework | |||
570 | public float dwell; | 570 | public float dwell; |
571 | } | 571 | } |
572 | 572 | ||
573 | public class EntityUpdate | 573 | public class IEntityUpdate |
574 | { | 574 | { |
575 | public ISceneEntity Entity; | 575 | public ISceneEntity Entity; |
576 | public PrimUpdateFlags Flags; | 576 | public uint Flags; |
577 | public float TimeDilation; | ||
578 | 577 | ||
579 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) | 578 | public virtual void Update(IEntityUpdate update) |
579 | { | ||
580 | this.Flags |= update.Flags; | ||
581 | } | ||
582 | |||
583 | public IEntityUpdate(ISceneEntity entity, uint flags) | ||
580 | { | 584 | { |
581 | Entity = entity; | 585 | Entity = entity; |
582 | Flags = flags; | 586 | Flags = flags; |
587 | } | ||
588 | } | ||
589 | |||
590 | |||
591 | public class EntityUpdate : IEntityUpdate | ||
592 | { | ||
593 | // public ISceneEntity Entity; | ||
594 | // public PrimUpdateFlags Flags; | ||
595 | public float TimeDilation; | ||
596 | |||
597 | public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) | ||
598 | : base(entity,(uint)flags) | ||
599 | { | ||
600 | //Entity = entity; | ||
601 | // Flags = flags; | ||
583 | TimeDilation = timedilation; | 602 | TimeDilation = timedilation; |
584 | } | 603 | } |
585 | } | 604 | } |
@@ -1211,20 +1230,9 @@ namespace OpenSim.Framework | |||
1211 | /// <param name="stats"></param> | 1230 | /// <param name="stats"></param> |
1212 | void SendSimStats(SimStats stats); | 1231 | void SendSimStats(SimStats stats); |
1213 | 1232 | ||
1214 | void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, | 1233 | void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags); |
1215 | uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, | 1234 | |
1216 | uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, | 1235 | void SendObjectPropertiesReply(ISceneEntity Entity); |
1217 | uint Category, | ||
1218 | UUID LastOwnerID, string ObjectName, string Description); | ||
1219 | |||
1220 | void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, | ||
1221 | UUID FromTaskUUID, | ||
1222 | UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, | ||
1223 | UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, | ||
1224 | string ItemName, | ||
1225 | string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, | ||
1226 | uint EveryoneMask, | ||
1227 | uint BaseMask, byte saleType, int salePrice); | ||
1228 | 1236 | ||
1229 | void SendAgentOffline(UUID[] agentIDs); | 1237 | void SendAgentOffline(UUID[] agentIDs); |
1230 | 1238 | ||
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index daf0a25..239ce3d 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -369,6 +369,7 @@ namespace OpenSim.Framework | |||
369 | private int m_physPrimMax = 0; | 369 | private int m_physPrimMax = 0; |
370 | private bool m_clampPrimSize = false; | 370 | private bool m_clampPrimSize = false; |
371 | private int m_objectCapacity = 0; | 371 | private int m_objectCapacity = 0; |
372 | private int m_agentCapacity = 0; | ||
372 | private string m_regionType = String.Empty; | 373 | private string m_regionType = String.Empty; |
373 | private RegionLightShareData m_windlight = new RegionLightShareData(); | 374 | private RegionLightShareData m_windlight = new RegionLightShareData(); |
374 | protected uint m_httpPort; | 375 | protected uint m_httpPort; |
@@ -547,6 +548,11 @@ namespace OpenSim.Framework | |||
547 | get { return m_objectCapacity; } | 548 | get { return m_objectCapacity; } |
548 | } | 549 | } |
549 | 550 | ||
551 | public int AgentCapacity | ||
552 | { | ||
553 | get { return m_agentCapacity; } | ||
554 | } | ||
555 | |||
550 | public byte AccessLevel | 556 | public byte AccessLevel |
551 | { | 557 | { |
552 | get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); } | 558 | get { return (byte)Util.ConvertMaturityToAccessLevel((uint)RegionSettings.Maturity); } |
@@ -821,6 +827,8 @@ namespace OpenSim.Framework | |||
821 | 827 | ||
822 | m_objectCapacity = config.GetInt("MaxPrims", 15000); | 828 | m_objectCapacity = config.GetInt("MaxPrims", 15000); |
823 | 829 | ||
830 | m_agentCapacity = config.GetInt("MaxAgents", 100); | ||
831 | |||
824 | 832 | ||
825 | // Multi-tenancy | 833 | // Multi-tenancy |
826 | // | 834 | // |
@@ -857,6 +865,9 @@ namespace OpenSim.Framework | |||
857 | if (m_objectCapacity != 0) | 865 | if (m_objectCapacity != 0) |
858 | config.Set("MaxPrims", m_objectCapacity); | 866 | config.Set("MaxPrims", m_objectCapacity); |
859 | 867 | ||
868 | if (m_agentCapacity != 0) | ||
869 | config.Set("MaxAgents", m_agentCapacity); | ||
870 | |||
860 | if (ScopeID != UUID.Zero) | 871 | if (ScopeID != UUID.Zero) |
861 | config.Set("ScopeID", ScopeID.ToString()); | 872 | config.Set("ScopeID", ScopeID.ToString()); |
862 | 873 | ||
@@ -943,6 +954,9 @@ namespace OpenSim.Framework | |||
943 | configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | 954 | configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, |
944 | "Max objects this sim will hold", m_objectCapacity.ToString(), true); | 955 | "Max objects this sim will hold", m_objectCapacity.ToString(), true); |
945 | 956 | ||
957 | configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, | ||
958 | "Max avatars this sim will hold", m_agentCapacity.ToString(), true); | ||
959 | |||
946 | configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, | 960 | configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID, |
947 | "Scope ID for this region", ScopeID.ToString(), true); | 961 | "Scope ID for this region", ScopeID.ToString(), true); |
948 | 962 | ||
@@ -1055,6 +1069,9 @@ namespace OpenSim.Framework | |||
1055 | case "object_capacity": | 1069 | case "object_capacity": |
1056 | m_objectCapacity = (int)configuration_result; | 1070 | m_objectCapacity = (int)configuration_result; |
1057 | break; | 1071 | break; |
1072 | case "agent_capacity": | ||
1073 | m_agentCapacity = (int)configuration_result; | ||
1074 | break; | ||
1058 | case "scope_id": | 1075 | case "scope_id": |
1059 | ScopeID = (UUID)configuration_result; | 1076 | ScopeID = (UUID)configuration_result; |
1060 | break; | 1077 | break; |
diff --git a/OpenSim/Framework/Servers/HttpServer/AsynchronousRestObjectRequester.cs b/OpenSim/Framework/Servers/HttpServer/AsynchronousRestObjectRequester.cs deleted file mode 100644 index 03c12dd..0000000 --- a/OpenSim/Framework/Servers/HttpServer/AsynchronousRestObjectRequester.cs +++ /dev/null | |||
@@ -1,192 +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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Xml; | ||
34 | using System.Xml.Serialization; | ||
35 | using log4net; | ||
36 | |||
37 | namespace OpenSim.Framework.Servers.HttpServer | ||
38 | { | ||
39 | public class AsynchronousRestObjectRequester | ||
40 | { | ||
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | |||
43 | /// <summary> | ||
44 | /// Perform an asynchronous REST request. | ||
45 | /// </summary> | ||
46 | /// <param name="verb">GET or POST</param> | ||
47 | /// <param name="requestUrl"></param> | ||
48 | /// <param name="obj"></param> | ||
49 | /// <param name="action"></param> | ||
50 | /// <returns></returns> | ||
51 | /// | ||
52 | /// <exception cref="System.Net.WebException">Thrown if we encounter a | ||
53 | /// network issue while posting the request. You'll want to make | ||
54 | /// sure you deal with this as they're not uncommon</exception> | ||
55 | // | ||
56 | public static void MakeRequest<TRequest, TResponse>(string verb, | ||
57 | string requestUrl, TRequest obj, Action<TResponse> action) | ||
58 | { | ||
59 | // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); | ||
60 | |||
61 | Type type = typeof (TRequest); | ||
62 | |||
63 | WebRequest request = WebRequest.Create(requestUrl); | ||
64 | WebResponse response = null; | ||
65 | TResponse deserial = default(TResponse); | ||
66 | XmlSerializer deserializer = new XmlSerializer(typeof (TResponse)); | ||
67 | |||
68 | request.Method = verb; | ||
69 | |||
70 | if (verb == "POST") | ||
71 | { | ||
72 | request.ContentType = "text/xml"; | ||
73 | |||
74 | MemoryStream buffer = new MemoryStream(); | ||
75 | |||
76 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
77 | settings.Encoding = Encoding.UTF8; | ||
78 | |||
79 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
80 | { | ||
81 | XmlSerializer serializer = new XmlSerializer(type); | ||
82 | serializer.Serialize(writer, obj); | ||
83 | writer.Flush(); | ||
84 | } | ||
85 | |||
86 | int length = (int) buffer.Length; | ||
87 | request.ContentLength = length; | ||
88 | |||
89 | request.BeginGetRequestStream(delegate(IAsyncResult res) | ||
90 | { | ||
91 | Stream requestStream = request.EndGetRequestStream(res); | ||
92 | |||
93 | requestStream.Write(buffer.ToArray(), 0, length); | ||
94 | requestStream.Close(); | ||
95 | |||
96 | request.BeginGetResponse(delegate(IAsyncResult ar) | ||
97 | { | ||
98 | response = request.EndGetResponse(ar); | ||
99 | Stream respStream = null; | ||
100 | try | ||
101 | { | ||
102 | respStream = response.GetResponseStream(); | ||
103 | deserial = (TResponse)deserializer.Deserialize( | ||
104 | respStream); | ||
105 | } | ||
106 | catch (System.InvalidOperationException) | ||
107 | { | ||
108 | } | ||
109 | finally | ||
110 | { | ||
111 | // Let's not close this | ||
112 | //buffer.Close(); | ||
113 | respStream.Close(); | ||
114 | response.Close(); | ||
115 | } | ||
116 | |||
117 | action(deserial); | ||
118 | |||
119 | }, null); | ||
120 | }, null); | ||
121 | |||
122 | |||
123 | return; | ||
124 | } | ||
125 | |||
126 | request.BeginGetResponse(delegate(IAsyncResult res2) | ||
127 | { | ||
128 | try | ||
129 | { | ||
130 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | ||
131 | // documented in MSDN | ||
132 | response = request.EndGetResponse(res2); | ||
133 | |||
134 | Stream respStream = null; | ||
135 | try | ||
136 | { | ||
137 | respStream = response.GetResponseStream(); | ||
138 | deserial = (TResponse)deserializer.Deserialize(respStream); | ||
139 | } | ||
140 | catch (System.InvalidOperationException) | ||
141 | { | ||
142 | } | ||
143 | finally | ||
144 | { | ||
145 | respStream.Close(); | ||
146 | response.Close(); | ||
147 | } | ||
148 | } | ||
149 | catch (WebException e) | ||
150 | { | ||
151 | if (e.Status == WebExceptionStatus.ProtocolError) | ||
152 | { | ||
153 | if (e.Response is HttpWebResponse) | ||
154 | { | ||
155 | HttpWebResponse httpResponse = (HttpWebResponse)e.Response; | ||
156 | |||
157 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) | ||
158 | { | ||
159 | // We don't appear to be handling any other status codes, so log these feailures to that | ||
160 | // people don't spend unnecessary hours hunting phantom bugs. | ||
161 | m_log.DebugFormat( | ||
162 | "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | ||
163 | verb, requestUrl, httpResponse.StatusCode); | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message); | ||
170 | } | ||
171 | } | ||
172 | catch (Exception e) | ||
173 | { | ||
174 | m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e); | ||
175 | } | ||
176 | |||
177 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | ||
178 | |||
179 | try | ||
180 | { | ||
181 | action(deserial); | ||
182 | } | ||
183 | catch (Exception e) | ||
184 | { | ||
185 | m_log.ErrorFormat( | ||
186 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e); | ||
187 | } | ||
188 | |||
189 | }, null); | ||
190 | } | ||
191 | } | ||
192 | } | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index ccec9b7..ba89e21 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | |||
@@ -430,7 +430,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
430 | string path = request.RawUrl; | 430 | string path = request.RawUrl; |
431 | string handlerKey = GetHandlerKey(request.HttpMethod, path); | 431 | string handlerKey = GetHandlerKey(request.HttpMethod, path); |
432 | 432 | ||
433 | //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); | 433 | // m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); |
434 | 434 | ||
435 | if (TryGetStreamHandler(handlerKey, out requestHandler)) | 435 | if (TryGetStreamHandler(handlerKey, out requestHandler)) |
436 | { | 436 | { |
diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs deleted file mode 100644 index 41ece86..0000000 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ /dev/null | |||
@@ -1,131 +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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Xml; | ||
34 | using System.Xml.Serialization; | ||
35 | |||
36 | using log4net; | ||
37 | |||
38 | namespace OpenSim.Framework.Servers.HttpServer | ||
39 | { | ||
40 | public class SynchronousRestFormsRequester | ||
41 | { | ||
42 | private static readonly ILog m_log = | ||
43 | LogManager.GetLogger( | ||
44 | MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
46 | /// <summary> | ||
47 | /// Perform a synchronous REST request. | ||
48 | /// </summary> | ||
49 | /// <param name="verb"></param> | ||
50 | /// <param name="requestUrl"></param> | ||
51 | /// <param name="obj"> </param> | ||
52 | /// <returns></returns> | ||
53 | /// | ||
54 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | ||
55 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | ||
56 | public static string MakeRequest(string verb, string requestUrl, string obj) | ||
57 | { | ||
58 | WebRequest request = WebRequest.Create(requestUrl); | ||
59 | request.Method = verb; | ||
60 | string respstring = String.Empty; | ||
61 | |||
62 | using (MemoryStream buffer = new MemoryStream()) | ||
63 | { | ||
64 | if ((verb == "POST") || (verb == "PUT")) | ||
65 | { | ||
66 | request.ContentType = "text/www-form-urlencoded"; | ||
67 | |||
68 | int length = 0; | ||
69 | using (StreamWriter writer = new StreamWriter(buffer)) | ||
70 | { | ||
71 | writer.Write(obj); | ||
72 | writer.Flush(); | ||
73 | } | ||
74 | |||
75 | length = (int)obj.Length; | ||
76 | request.ContentLength = length; | ||
77 | |||
78 | Stream requestStream = null; | ||
79 | try | ||
80 | { | ||
81 | requestStream = request.GetRequestStream(); | ||
82 | requestStream.Write(buffer.ToArray(), 0, length); | ||
83 | } | ||
84 | catch (Exception e) | ||
85 | { | ||
86 | m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); | ||
87 | } | ||
88 | finally | ||
89 | { | ||
90 | if (requestStream != null) | ||
91 | requestStream.Close(); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | try | ||
96 | { | ||
97 | using (WebResponse resp = request.GetResponse()) | ||
98 | { | ||
99 | if (resp.ContentLength != 0) | ||
100 | { | ||
101 | Stream respStream = null; | ||
102 | try | ||
103 | { | ||
104 | respStream = resp.GetResponseStream(); | ||
105 | using (StreamReader reader = new StreamReader(respStream)) | ||
106 | { | ||
107 | respstring = reader.ReadToEnd(); | ||
108 | } | ||
109 | } | ||
110 | catch (Exception e) | ||
111 | { | ||
112 | m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); | ||
113 | } | ||
114 | finally | ||
115 | { | ||
116 | if (respStream != null) | ||
117 | respStream.Close(); | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | catch (System.InvalidOperationException) | ||
123 | { | ||
124 | // This is what happens when there is invalid XML | ||
125 | m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); | ||
126 | } | ||
127 | } | ||
128 | return respstring; | ||
129 | } | ||
130 | } | ||
131 | } | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs deleted file mode 100644 index eab463c..0000000 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs +++ /dev/null | |||
@@ -1,122 +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 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Text; | ||
32 | using System.Xml; | ||
33 | using System.Xml.Serialization; | ||
34 | |||
35 | namespace OpenSim.Framework.Servers.HttpServer | ||
36 | { | ||
37 | public class SynchronousRestObjectPoster | ||
38 | { | ||
39 | [Obsolete] | ||
40 | public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) | ||
41 | { | ||
42 | return SynchronousRestObjectRequester.MakeRequest<TRequest, TResponse>(verb, requestUrl, obj); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | public class SynchronousRestObjectRequester | ||
47 | { | ||
48 | /// <summary> | ||
49 | /// Perform a synchronous REST request. | ||
50 | /// </summary> | ||
51 | /// <param name="verb"></param> | ||
52 | /// <param name="requestUrl"></param> | ||
53 | /// <param name="obj"> </param> | ||
54 | /// <returns></returns> | ||
55 | /// | ||
56 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | ||
57 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | ||
58 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) | ||
59 | { | ||
60 | Type type = typeof (TRequest); | ||
61 | TResponse deserial = default(TResponse); | ||
62 | |||
63 | WebRequest request = WebRequest.Create(requestUrl); | ||
64 | request.Method = verb; | ||
65 | |||
66 | if ((verb == "POST") || (verb == "PUT")) | ||
67 | { | ||
68 | request.ContentType = "text/xml"; | ||
69 | |||
70 | MemoryStream buffer = new MemoryStream(); | ||
71 | |||
72 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
73 | settings.Encoding = Encoding.UTF8; | ||
74 | |||
75 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
76 | { | ||
77 | XmlSerializer serializer = new XmlSerializer(type); | ||
78 | serializer.Serialize(writer, obj); | ||
79 | writer.Flush(); | ||
80 | } | ||
81 | |||
82 | int length = (int) buffer.Length; | ||
83 | request.ContentLength = length; | ||
84 | |||
85 | Stream requestStream = null; | ||
86 | try | ||
87 | { | ||
88 | requestStream = request.GetRequestStream(); | ||
89 | requestStream.Write(buffer.ToArray(), 0, length); | ||
90 | } | ||
91 | catch (Exception) | ||
92 | { | ||
93 | return deserial; | ||
94 | } | ||
95 | finally | ||
96 | { | ||
97 | if (requestStream != null) | ||
98 | requestStream.Close(); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | try | ||
103 | { | ||
104 | using (WebResponse resp = request.GetResponse()) | ||
105 | { | ||
106 | if (resp.ContentLength > 0) | ||
107 | { | ||
108 | Stream respStream = resp.GetResponseStream(); | ||
109 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||
110 | deserial = (TResponse)deserializer.Deserialize(respStream); | ||
111 | respStream.Close(); | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | catch (System.InvalidOperationException) | ||
116 | { | ||
117 | // This is what happens when there is invalid XML | ||
118 | } | ||
119 | return deserial; | ||
120 | } | ||
121 | } | ||
122 | } | ||
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 1feeeb3..9d70f63 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -36,6 +36,9 @@ using System.Net.Security; | |||
36 | using System.Reflection; | 36 | using System.Reflection; |
37 | using System.Text; | 37 | using System.Text; |
38 | using System.Web; | 38 | using System.Web; |
39 | using System.Xml; | ||
40 | using System.Xml.Serialization; | ||
41 | |||
39 | using log4net; | 42 | using log4net; |
40 | using OpenSim.Framework.Servers.HttpServer; | 43 | using OpenSim.Framework.Servers.HttpServer; |
41 | using OpenMetaverse.StructuredData; | 44 | using OpenMetaverse.StructuredData; |
@@ -219,8 +222,8 @@ namespace OpenSim.Framework | |||
219 | m_log.InfoFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", | 222 | m_log.InfoFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", |
220 | reqnum,url,method,tickdiff,tickdata); | 223 | reqnum,url,method,tickdiff,tickdata); |
221 | } | 224 | } |
222 | 225 | ||
223 | m_log.WarnFormat("[WEB UTIL] <{0}> osd request failed: {1}",reqnum,errorMessage); | 226 | m_log.WarnFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); |
224 | return ErrorResponseMap(errorMessage); | 227 | return ErrorResponseMap(errorMessage); |
225 | } | 228 | } |
226 | 229 | ||
@@ -625,4 +628,336 @@ namespace OpenSim.Framework | |||
625 | 628 | ||
626 | 629 | ||
627 | } | 630 | } |
631 | |||
632 | public static class AsynchronousRestObjectRequester | ||
633 | { | ||
634 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
635 | |||
636 | /// <summary> | ||
637 | /// Perform an asynchronous REST request. | ||
638 | /// </summary> | ||
639 | /// <param name="verb">GET or POST</param> | ||
640 | /// <param name="requestUrl"></param> | ||
641 | /// <param name="obj"></param> | ||
642 | /// <param name="action"></param> | ||
643 | /// <returns></returns> | ||
644 | /// | ||
645 | /// <exception cref="System.Net.WebException">Thrown if we encounter a | ||
646 | /// network issue while posting the request. You'll want to make | ||
647 | /// sure you deal with this as they're not uncommon</exception> | ||
648 | // | ||
649 | public static void MakeRequest<TRequest, TResponse>(string verb, | ||
650 | string requestUrl, TRequest obj, Action<TResponse> action) | ||
651 | { | ||
652 | // m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); | ||
653 | |||
654 | Type type = typeof(TRequest); | ||
655 | |||
656 | WebRequest request = WebRequest.Create(requestUrl); | ||
657 | WebResponse response = null; | ||
658 | TResponse deserial = default(TResponse); | ||
659 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||
660 | |||
661 | request.Method = verb; | ||
662 | |||
663 | if (verb == "POST") | ||
664 | { | ||
665 | request.ContentType = "text/xml"; | ||
666 | |||
667 | MemoryStream buffer = new MemoryStream(); | ||
668 | |||
669 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
670 | settings.Encoding = Encoding.UTF8; | ||
671 | |||
672 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
673 | { | ||
674 | XmlSerializer serializer = new XmlSerializer(type); | ||
675 | serializer.Serialize(writer, obj); | ||
676 | writer.Flush(); | ||
677 | } | ||
678 | |||
679 | int length = (int)buffer.Length; | ||
680 | request.ContentLength = length; | ||
681 | |||
682 | request.BeginGetRequestStream(delegate(IAsyncResult res) | ||
683 | { | ||
684 | Stream requestStream = request.EndGetRequestStream(res); | ||
685 | |||
686 | requestStream.Write(buffer.ToArray(), 0, length); | ||
687 | requestStream.Close(); | ||
688 | |||
689 | request.BeginGetResponse(delegate(IAsyncResult ar) | ||
690 | { | ||
691 | response = request.EndGetResponse(ar); | ||
692 | Stream respStream = null; | ||
693 | try | ||
694 | { | ||
695 | respStream = response.GetResponseStream(); | ||
696 | deserial = (TResponse)deserializer.Deserialize( | ||
697 | respStream); | ||
698 | } | ||
699 | catch (System.InvalidOperationException) | ||
700 | { | ||
701 | } | ||
702 | finally | ||
703 | { | ||
704 | // Let's not close this | ||
705 | //buffer.Close(); | ||
706 | respStream.Close(); | ||
707 | response.Close(); | ||
708 | } | ||
709 | |||
710 | action(deserial); | ||
711 | |||
712 | }, null); | ||
713 | }, null); | ||
714 | |||
715 | |||
716 | return; | ||
717 | } | ||
718 | |||
719 | request.BeginGetResponse(delegate(IAsyncResult res2) | ||
720 | { | ||
721 | try | ||
722 | { | ||
723 | // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | ||
724 | // documented in MSDN | ||
725 | response = request.EndGetResponse(res2); | ||
726 | |||
727 | Stream respStream = null; | ||
728 | try | ||
729 | { | ||
730 | respStream = response.GetResponseStream(); | ||
731 | deserial = (TResponse)deserializer.Deserialize(respStream); | ||
732 | } | ||
733 | catch (System.InvalidOperationException) | ||
734 | { | ||
735 | } | ||
736 | finally | ||
737 | { | ||
738 | respStream.Close(); | ||
739 | response.Close(); | ||
740 | } | ||
741 | } | ||
742 | catch (WebException e) | ||
743 | { | ||
744 | if (e.Status == WebExceptionStatus.ProtocolError) | ||
745 | { | ||
746 | if (e.Response is HttpWebResponse) | ||
747 | { | ||
748 | HttpWebResponse httpResponse = (HttpWebResponse)e.Response; | ||
749 | |||
750 | if (httpResponse.StatusCode != HttpStatusCode.NotFound) | ||
751 | { | ||
752 | // We don't appear to be handling any other status codes, so log these feailures to that | ||
753 | // people don't spend unnecessary hours hunting phantom bugs. | ||
754 | m_log.DebugFormat( | ||
755 | "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | ||
756 | verb, requestUrl, httpResponse.StatusCode); | ||
757 | } | ||
758 | } | ||
759 | } | ||
760 | else | ||
761 | { | ||
762 | m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message); | ||
763 | } | ||
764 | } | ||
765 | catch (Exception e) | ||
766 | { | ||
767 | m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e); | ||
768 | } | ||
769 | |||
770 | // m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | ||
771 | |||
772 | try | ||
773 | { | ||
774 | action(deserial); | ||
775 | } | ||
776 | catch (Exception e) | ||
777 | { | ||
778 | m_log.ErrorFormat( | ||
779 | "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e); | ||
780 | } | ||
781 | |||
782 | }, null); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | public static class SynchronousRestFormsRequester | ||
787 | { | ||
788 | private static readonly ILog m_log = | ||
789 | LogManager.GetLogger( | ||
790 | MethodBase.GetCurrentMethod().DeclaringType); | ||
791 | |||
792 | /// <summary> | ||
793 | /// Perform a synchronous REST request. | ||
794 | /// </summary> | ||
795 | /// <param name="verb"></param> | ||
796 | /// <param name="requestUrl"></param> | ||
797 | /// <param name="obj"> </param> | ||
798 | /// <returns></returns> | ||
799 | /// | ||
800 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | ||
801 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | ||
802 | public static string MakeRequest(string verb, string requestUrl, string obj) | ||
803 | { | ||
804 | WebRequest request = WebRequest.Create(requestUrl); | ||
805 | request.Method = verb; | ||
806 | string respstring = String.Empty; | ||
807 | |||
808 | using (MemoryStream buffer = new MemoryStream()) | ||
809 | { | ||
810 | if ((verb == "POST") || (verb == "PUT")) | ||
811 | { | ||
812 | request.ContentType = "text/www-form-urlencoded"; | ||
813 | |||
814 | int length = 0; | ||
815 | using (StreamWriter writer = new StreamWriter(buffer)) | ||
816 | { | ||
817 | writer.Write(obj); | ||
818 | writer.Flush(); | ||
819 | } | ||
820 | |||
821 | length = (int)obj.Length; | ||
822 | request.ContentLength = length; | ||
823 | |||
824 | Stream requestStream = null; | ||
825 | try | ||
826 | { | ||
827 | requestStream = request.GetRequestStream(); | ||
828 | requestStream.Write(buffer.ToArray(), 0, length); | ||
829 | } | ||
830 | catch (Exception e) | ||
831 | { | ||
832 | m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); | ||
833 | } | ||
834 | finally | ||
835 | { | ||
836 | if (requestStream != null) | ||
837 | requestStream.Close(); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | try | ||
842 | { | ||
843 | using (WebResponse resp = request.GetResponse()) | ||
844 | { | ||
845 | if (resp.ContentLength != 0) | ||
846 | { | ||
847 | Stream respStream = null; | ||
848 | try | ||
849 | { | ||
850 | respStream = resp.GetResponseStream(); | ||
851 | using (StreamReader reader = new StreamReader(respStream)) | ||
852 | { | ||
853 | respstring = reader.ReadToEnd(); | ||
854 | } | ||
855 | } | ||
856 | catch (Exception e) | ||
857 | { | ||
858 | m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); | ||
859 | } | ||
860 | finally | ||
861 | { | ||
862 | if (respStream != null) | ||
863 | respStream.Close(); | ||
864 | } | ||
865 | } | ||
866 | } | ||
867 | } | ||
868 | catch (System.InvalidOperationException) | ||
869 | { | ||
870 | // This is what happens when there is invalid XML | ||
871 | m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); | ||
872 | } | ||
873 | } | ||
874 | return respstring; | ||
875 | } | ||
876 | } | ||
877 | |||
878 | public class SynchronousRestObjectPoster | ||
879 | { | ||
880 | [Obsolete] | ||
881 | public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) | ||
882 | { | ||
883 | return SynchronousRestObjectRequester.MakeRequest<TRequest, TResponse>(verb, requestUrl, obj); | ||
884 | } | ||
885 | } | ||
886 | |||
887 | public class SynchronousRestObjectRequester | ||
888 | { | ||
889 | /// <summary> | ||
890 | /// Perform a synchronous REST request. | ||
891 | /// </summary> | ||
892 | /// <param name="verb"></param> | ||
893 | /// <param name="requestUrl"></param> | ||
894 | /// <param name="obj"> </param> | ||
895 | /// <returns></returns> | ||
896 | /// | ||
897 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | ||
898 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | ||
899 | public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) | ||
900 | { | ||
901 | Type type = typeof(TRequest); | ||
902 | TResponse deserial = default(TResponse); | ||
903 | |||
904 | WebRequest request = WebRequest.Create(requestUrl); | ||
905 | request.Method = verb; | ||
906 | |||
907 | if ((verb == "POST") || (verb == "PUT")) | ||
908 | { | ||
909 | request.ContentType = "text/xml"; | ||
910 | |||
911 | MemoryStream buffer = new MemoryStream(); | ||
912 | |||
913 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
914 | settings.Encoding = Encoding.UTF8; | ||
915 | |||
916 | using (XmlWriter writer = XmlWriter.Create(buffer, settings)) | ||
917 | { | ||
918 | XmlSerializer serializer = new XmlSerializer(type); | ||
919 | serializer.Serialize(writer, obj); | ||
920 | writer.Flush(); | ||
921 | } | ||
922 | |||
923 | int length = (int)buffer.Length; | ||
924 | request.ContentLength = length; | ||
925 | |||
926 | Stream requestStream = null; | ||
927 | try | ||
928 | { | ||
929 | requestStream = request.GetRequestStream(); | ||
930 | requestStream.Write(buffer.ToArray(), 0, length); | ||
931 | } | ||
932 | catch (Exception) | ||
933 | { | ||
934 | return deserial; | ||
935 | } | ||
936 | finally | ||
937 | { | ||
938 | if (requestStream != null) | ||
939 | requestStream.Close(); | ||
940 | } | ||
941 | } | ||
942 | |||
943 | try | ||
944 | { | ||
945 | using (WebResponse resp = request.GetResponse()) | ||
946 | { | ||
947 | if (resp.ContentLength > 0) | ||
948 | { | ||
949 | Stream respStream = resp.GetResponseStream(); | ||
950 | XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||
951 | deserial = (TResponse)deserializer.Deserialize(respStream); | ||
952 | respStream.Close(); | ||
953 | } | ||
954 | } | ||
955 | } | ||
956 | catch (System.InvalidOperationException) | ||
957 | { | ||
958 | // This is what happens when there is invalid XML | ||
959 | } | ||
960 | return deserial; | ||
961 | } | ||
962 | } | ||
628 | } | 963 | } |
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index ec1fb04..39004d4 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -341,10 +341,15 @@ namespace OpenSim | |||
341 | 341 | ||
342 | m_console.Commands.AddCommand("region", false, "config get", | 342 | m_console.Commands.AddCommand("region", false, "config get", |
343 | "config get [<section>] [<key>]", | 343 | "config get [<section>] [<key>]", |
344 | "Show a config option", | 344 | "Synonym for config show", |
345 | HandleConfig); | ||
346 | |||
347 | m_console.Commands.AddCommand("region", false, "config show", | ||
348 | "config show [<section>] [<key>]", | ||
349 | "Show config information", | ||
345 | "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine | 350 | "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine |
346 | + "If a section is given but not a field, then all fields in that section are printed.", | 351 | + "If a section is given but not a field, then all fields in that section are printed.", |
347 | HandleConfig); | 352 | HandleConfig); |
348 | 353 | ||
349 | m_console.Commands.AddCommand("region", false, "config save", | 354 | m_console.Commands.AddCommand("region", false, "config save", |
350 | "config save <path>", | 355 | "config save <path>", |
@@ -593,7 +598,9 @@ namespace OpenSim | |||
593 | 598 | ||
594 | if (cmdparams.Length > 0) | 599 | if (cmdparams.Length > 0) |
595 | { | 600 | { |
596 | switch (cmdparams[0].ToLower()) | 601 | string firstParam = cmdparams[0].ToLower(); |
602 | |||
603 | switch (firstParam) | ||
597 | { | 604 | { |
598 | case "set": | 605 | case "set": |
599 | if (cmdparams.Length < 4) | 606 | if (cmdparams.Length < 4) |
@@ -618,6 +625,7 @@ namespace OpenSim | |||
618 | break; | 625 | break; |
619 | 626 | ||
620 | case "get": | 627 | case "get": |
628 | case "show": | ||
621 | if (cmdparams.Length == 1) | 629 | if (cmdparams.Length == 1) |
622 | { | 630 | { |
623 | foreach (IConfig config in m_config.Source.Configs) | 631 | foreach (IConfig config in m_config.Source.Configs) |
@@ -654,8 +662,8 @@ namespace OpenSim | |||
654 | } | 662 | } |
655 | else | 663 | else |
656 | { | 664 | { |
657 | Notice("Syntax: config get [<section>] [<key>]"); | 665 | Notice("Syntax: config {0} [<section>] [<key>]", firstParam); |
658 | Notice("Example: config get ScriptEngine.DotNetEngine NumberOfScriptThreads"); | 666 | Notice("Example: config {0} ScriptEngine.DotNetEngine NumberOfScriptThreads", firstParam); |
659 | } | 667 | } |
660 | 668 | ||
661 | break; | 669 | break; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 34d72ac..1f7e66d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -49,6 +49,8 @@ using Timer = System.Timers.Timer; | |||
49 | using AssetLandmark = OpenSim.Framework.AssetLandmark; | 49 | using AssetLandmark = OpenSim.Framework.AssetLandmark; |
50 | using Nini.Config; | 50 | using Nini.Config; |
51 | 51 | ||
52 | using System.IO; | ||
53 | |||
52 | namespace OpenSim.Region.ClientStack.LindenUDP | 54 | namespace OpenSim.Region.ClientStack.LindenUDP |
53 | { | 55 | { |
54 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); | 56 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); |
@@ -313,6 +315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
313 | 315 | ||
314 | private int m_cachedTextureSerial; | 316 | private int m_cachedTextureSerial; |
315 | private PriorityQueue m_entityUpdates; | 317 | private PriorityQueue m_entityUpdates; |
318 | private PriorityQueue m_entityProps; | ||
316 | private Prioritizer m_prioritizer; | 319 | private Prioritizer m_prioritizer; |
317 | private bool m_disableFacelights = false; | 320 | private bool m_disableFacelights = false; |
318 | 321 | ||
@@ -360,9 +363,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
360 | protected IAssetService m_assetService; | 363 | protected IAssetService m_assetService; |
361 | private const bool m_checkPackets = true; | 364 | private const bool m_checkPackets = true; |
362 | 365 | ||
363 | private Timer m_propertiesPacketTimer; | ||
364 | private List<ObjectPropertiesPacket.ObjectDataBlock> m_propertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>(); | ||
365 | |||
366 | #endregion Class Members | 366 | #endregion Class Members |
367 | 367 | ||
368 | #region Properties | 368 | #region Properties |
@@ -438,6 +438,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
438 | m_scene = scene; | 438 | m_scene = scene; |
439 | 439 | ||
440 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); | 440 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); |
441 | m_entityProps = new PriorityQueue(m_scene.Entities.Count); | ||
441 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); | 442 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); |
442 | m_killRecord = new HashSet<uint>(); | 443 | m_killRecord = new HashSet<uint>(); |
443 | // m_attachmentsSent = new HashSet<uint>(); | 444 | // m_attachmentsSent = new HashSet<uint>(); |
@@ -461,9 +462,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
461 | m_udpClient.OnQueueEmpty += HandleQueueEmpty; | 462 | m_udpClient.OnQueueEmpty += HandleQueueEmpty; |
462 | m_udpClient.OnPacketStats += PopulateStats; | 463 | m_udpClient.OnPacketStats += PopulateStats; |
463 | 464 | ||
464 | m_propertiesPacketTimer = new Timer(100); | ||
465 | m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; | ||
466 | |||
467 | m_prioritizer = new Prioritizer(m_scene); | 465 | m_prioritizer = new Prioritizer(m_scene); |
468 | 466 | ||
469 | RegisterLocalPacketHandlers(); | 467 | RegisterLocalPacketHandlers(); |
@@ -1537,7 +1535,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1537 | } | 1535 | } |
1538 | else | 1536 | else |
1539 | { | 1537 | { |
1540 | OutPacket(kill, ThrottleOutPacketType.State); | 1538 | // OutPacket(kill, ThrottleOutPacketType.State); |
1539 | OutPacket(kill, ThrottleOutPacketType.Task); | ||
1541 | } | 1540 | } |
1542 | } | 1541 | } |
1543 | 1542 | ||
@@ -2367,7 +2366,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2367 | 2366 | ||
2368 | packet.Effect = effectBlocks; | 2367 | packet.Effect = effectBlocks; |
2369 | 2368 | ||
2370 | OutPacket(packet, ThrottleOutPacketType.State); | 2369 | // OutPacket(packet, ThrottleOutPacketType.State); |
2370 | OutPacket(packet, ThrottleOutPacketType.Task); | ||
2371 | } | 2371 | } |
2372 | 2372 | ||
2373 | public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, | 2373 | public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, |
@@ -3547,16 +3547,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3547 | 3547 | ||
3548 | #region Primitive Packet/Data Sending Methods | 3548 | #region Primitive Packet/Data Sending Methods |
3549 | 3549 | ||
3550 | |||
3550 | /// <summary> | 3551 | /// <summary> |
3551 | /// Generate one of the object update packets based on PrimUpdateFlags | 3552 | /// Generate one of the object update packets based on PrimUpdateFlags |
3552 | /// and broadcast the packet to clients | 3553 | /// and broadcast the packet to clients |
3553 | /// </summary> | 3554 | /// </summary> |
3554 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) | 3555 | public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) |
3555 | { | 3556 | { |
3556 | double priority = m_prioritizer.GetUpdatePriority(this, entity); | 3557 | //double priority = m_prioritizer.GetUpdatePriority(this, entity); |
3558 | uint priority = m_prioritizer.GetUpdatePriority(this, entity); | ||
3557 | 3559 | ||
3558 | lock (m_entityUpdates.SyncRoot) | 3560 | lock (m_entityUpdates.SyncRoot) |
3559 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation), entity.LocalId); | 3561 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); |
3560 | } | 3562 | } |
3561 | 3563 | ||
3562 | private void ProcessEntityUpdates(int maxUpdates) | 3564 | private void ProcessEntityUpdates(int maxUpdates) |
@@ -3566,7 +3568,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3566 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3568 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3567 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3569 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3568 | 3570 | ||
3569 | if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; | 3571 | // Check to see if this is a flush |
3572 | if (maxUpdates <= 0) | ||
3573 | { | ||
3574 | maxUpdates = Int32.MaxValue; | ||
3575 | } | ||
3576 | |||
3570 | int updatesThisCall = 0; | 3577 | int updatesThisCall = 0; |
3571 | 3578 | ||
3572 | // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race | 3579 | // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race |
@@ -3574,12 +3581,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3574 | lock (m_killRecord) | 3581 | lock (m_killRecord) |
3575 | { | 3582 | { |
3576 | float avgTimeDilation = 1.0f; | 3583 | float avgTimeDilation = 1.0f; |
3577 | EntityUpdate update; | 3584 | IEntityUpdate iupdate; |
3585 | Int32 timeinqueue; // this is just debugging code & can be dropped later | ||
3586 | |||
3578 | while (updatesThisCall < maxUpdates) | 3587 | while (updatesThisCall < maxUpdates) |
3579 | { | 3588 | { |
3580 | lock (m_entityUpdates.SyncRoot) | 3589 | lock (m_entityUpdates.SyncRoot) |
3581 | if (!m_entityUpdates.TryDequeue(out update)) | 3590 | if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue)) |
3582 | break; | 3591 | break; |
3592 | |||
3593 | EntityUpdate update = (EntityUpdate)iupdate; | ||
3594 | |||
3583 | avgTimeDilation += update.TimeDilation; | 3595 | avgTimeDilation += update.TimeDilation; |
3584 | avgTimeDilation *= 0.5f; | 3596 | avgTimeDilation *= 0.5f; |
3585 | 3597 | ||
@@ -3619,7 +3631,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3619 | 3631 | ||
3620 | #region UpdateFlags to packet type conversion | 3632 | #region UpdateFlags to packet type conversion |
3621 | 3633 | ||
3622 | PrimUpdateFlags updateFlags = update.Flags; | 3634 | PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; |
3623 | 3635 | ||
3624 | bool canUseCompressed = true; | 3636 | bool canUseCompressed = true; |
3625 | bool canUseImproved = true; | 3637 | bool canUseImproved = true; |
@@ -3679,36 +3691,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3679 | } | 3691 | } |
3680 | else | 3692 | else |
3681 | { | 3693 | { |
3682 | // if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) | 3694 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); |
3683 | // { | ||
3684 | // SceneObjectPart sop = (SceneObjectPart)update.Entity; | ||
3685 | // string text = sop.Text; | ||
3686 | // if (text.IndexOf("\n") >= 0) | ||
3687 | // text = text.Remove(text.IndexOf("\n")); | ||
3688 | // | ||
3689 | // if (m_attachmentsSent.Contains(sop.ParentID)) | ||
3690 | // { | ||
3691 | //// m_log.DebugFormat( | ||
3692 | //// "[CLIENT]: Sending full info about attached prim {0} text {1}", | ||
3693 | //// sop.LocalId, text); | ||
3694 | // | ||
3695 | // objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId)); | ||
3696 | // | ||
3697 | // m_attachmentsSent.Add(sop.LocalId); | ||
3698 | // } | ||
3699 | // else | ||
3700 | // { | ||
3701 | // m_log.DebugFormat( | ||
3702 | // "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet", | ||
3703 | // sop.LocalId, text, sop.ParentID); | ||
3704 | // | ||
3705 | // m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId); | ||
3706 | // } | ||
3707 | // } | ||
3708 | // else | ||
3709 | // { | ||
3710 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||
3711 | // } | ||
3712 | } | 3695 | } |
3713 | } | 3696 | } |
3714 | else if (!canUseImproved) | 3697 | else if (!canUseImproved) |
@@ -3727,6 +3710,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3727 | 3710 | ||
3728 | #endregion Block Construction | 3711 | #endregion Block Construction |
3729 | } | 3712 | } |
3713 | |||
3730 | 3714 | ||
3731 | #region Packet Sending | 3715 | #region Packet Sending |
3732 | 3716 | ||
@@ -3802,26 +3786,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3802 | 3786 | ||
3803 | public void ReprioritizeUpdates() | 3787 | public void ReprioritizeUpdates() |
3804 | { | 3788 | { |
3805 | //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName); | ||
3806 | |||
3807 | lock (m_entityUpdates.SyncRoot) | 3789 | lock (m_entityUpdates.SyncRoot) |
3808 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); | 3790 | m_entityUpdates.Reprioritize(UpdatePriorityHandler); |
3809 | } | 3791 | } |
3810 | 3792 | ||
3811 | private bool UpdatePriorityHandler(ref double priority, uint localID) | 3793 | private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) |
3812 | { | 3794 | { |
3813 | EntityBase entity; | 3795 | if (entity != null) |
3814 | if (m_scene.Entities.TryGetValue(localID, out entity)) | ||
3815 | { | 3796 | { |
3816 | priority = m_prioritizer.GetUpdatePriority(this, entity); | 3797 | priority = m_prioritizer.GetUpdatePriority(this, entity); |
3798 | return true; | ||
3817 | } | 3799 | } |
3818 | 3800 | ||
3819 | return priority != double.NaN; | 3801 | return false; |
3820 | } | 3802 | } |
3821 | 3803 | ||
3822 | public void FlushPrimUpdates() | 3804 | public void FlushPrimUpdates() |
3823 | { | 3805 | { |
3824 | m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName); | 3806 | m_log.WarnFormat("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName); |
3825 | 3807 | ||
3826 | while (m_entityUpdates.Count > 0) | 3808 | while (m_entityUpdates.Count > 0) |
3827 | ProcessEntityUpdates(-1); | 3809 | ProcessEntityUpdates(-1); |
@@ -3829,12 +3811,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3829 | 3811 | ||
3830 | #endregion Primitive Packet/Data Sending Methods | 3812 | #endregion Primitive Packet/Data Sending Methods |
3831 | 3813 | ||
3814 | // These are used to implement an adaptive backoff in the number | ||
3815 | // of updates converted to packets. Since we don't want packets | ||
3816 | // to sit in the queue with old data, only convert enough updates | ||
3817 | // to packets that can be sent in 200ms. | ||
3818 | private Int32 m_LastQueueFill = 0; | ||
3819 | private Int32 m_maxUpdates = 0; | ||
3820 | |||
3832 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) | 3821 | void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) |
3833 | { | 3822 | { |
3834 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) | 3823 | if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) |
3835 | { | 3824 | { |
3825 | if (m_maxUpdates == 0 || m_LastQueueFill == 0) | ||
3826 | { | ||
3827 | m_maxUpdates = m_udpServer.PrimUpdatesPerCallback; | ||
3828 | } | ||
3829 | else | ||
3830 | { | ||
3831 | if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200) | ||
3832 | m_maxUpdates += 5; | ||
3833 | else | ||
3834 | m_maxUpdates = m_maxUpdates >> 1; | ||
3835 | } | ||
3836 | m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500); | ||
3837 | m_LastQueueFill = Util.EnvironmentTickCount(); | ||
3838 | |||
3836 | if (m_entityUpdates.Count > 0) | 3839 | if (m_entityUpdates.Count > 0) |
3837 | ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); | 3840 | ProcessEntityUpdates(m_maxUpdates); |
3841 | |||
3842 | if (m_entityProps.Count > 0) | ||
3843 | ProcessEntityPropertyRequests(m_maxUpdates); | ||
3838 | } | 3844 | } |
3839 | 3845 | ||
3840 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) | 3846 | if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) |
@@ -3948,132 +3954,206 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3948 | OutPacket(pack, ThrottleOutPacketType.Task); | 3954 | OutPacket(pack, ThrottleOutPacketType.Task); |
3949 | } | 3955 | } |
3950 | 3956 | ||
3951 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, | 3957 | private class ObjectPropertyUpdate : IEntityUpdate |
3952 | uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, | ||
3953 | uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, | ||
3954 | UUID LastOwnerID, string ObjectName, string Description) | ||
3955 | { | 3958 | { |
3956 | ObjectPropertiesFamilyPacket objPropFamilyPack = (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); | 3959 | internal bool SendFamilyProps; |
3957 | // TODO: don't create new blocks if recycling an old packet | 3960 | internal bool SendObjectProps; |
3958 | 3961 | ||
3959 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); | 3962 | public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj) |
3960 | objPropDB.RequestFlags = RequestFlags; | 3963 | : base(entity,flags) |
3961 | objPropDB.ObjectID = ObjectUUID; | 3964 | { |
3962 | if (OwnerID == GroupID) | 3965 | SendFamilyProps = sendfam; |
3963 | objPropDB.OwnerID = UUID.Zero; | 3966 | SendObjectProps = sendobj; |
3964 | else | 3967 | } |
3965 | objPropDB.OwnerID = OwnerID; | 3968 | public void Update(ObjectPropertyUpdate update) |
3966 | objPropDB.GroupID = GroupID; | 3969 | { |
3967 | objPropDB.BaseMask = BaseMask; | 3970 | SendFamilyProps = SendFamilyProps || update.SendFamilyProps; |
3968 | objPropDB.OwnerMask = OwnerMask; | 3971 | SendObjectProps = SendObjectProps || update.SendObjectProps; |
3969 | objPropDB.GroupMask = GroupMask; | 3972 | Flags |= update.Flags; |
3970 | objPropDB.EveryoneMask = EveryoneMask; | 3973 | } |
3971 | objPropDB.NextOwnerMask = NextOwnerMask; | 3974 | } |
3975 | |||
3976 | public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags) | ||
3977 | { | ||
3978 | uint priority = 0; // time based ordering only | ||
3979 | lock (m_entityProps.SyncRoot) | ||
3980 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); | ||
3981 | } | ||
3972 | 3982 | ||
3973 | // TODO: More properties are needed in SceneObjectPart! | 3983 | public void SendObjectPropertiesReply(ISceneEntity entity) |
3974 | objPropDB.OwnershipCost = OwnershipCost; | ||
3975 | objPropDB.SaleType = SaleType; | ||
3976 | objPropDB.SalePrice = SalePrice; | ||
3977 | objPropDB.Category = Category; | ||
3978 | objPropDB.LastOwnerID = LastOwnerID; | ||
3979 | objPropDB.Name = Util.StringToBytes256(ObjectName); | ||
3980 | objPropDB.Description = Util.StringToBytes256(Description); | ||
3981 | objPropFamilyPack.ObjectData = objPropDB; | ||
3982 | objPropFamilyPack.Header.Zerocoded = true; | ||
3983 | OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task); | ||
3984 | } | ||
3985 | |||
3986 | public void SendObjectPropertiesReply( | ||
3987 | UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, | ||
3988 | UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, | ||
3989 | UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, | ||
3990 | string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, | ||
3991 | uint BaseMask, byte saleType, int salePrice) | ||
3992 | { | 3984 | { |
3993 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 3985 | uint priority = 0; // time based ordering only |
3994 | // TODO: don't create new blocks if recycling an old packet | 3986 | lock (m_entityProps.SyncRoot) |
3987 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); | ||
3988 | } | ||
3995 | 3989 | ||
3996 | ObjectPropertiesPacket.ObjectDataBlock block = | 3990 | private void ProcessEntityPropertyRequests(int maxUpdates) |
3997 | new ObjectPropertiesPacket.ObjectDataBlock(); | 3991 | { |
3992 | OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks = | ||
3993 | new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>(); | ||
3998 | 3994 | ||
3999 | block.ItemID = ItemID; | 3995 | OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = |
4000 | block.CreationDate = CreationDate; | 3996 | new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); |
4001 | block.CreatorID = CreatorUUID; | ||
4002 | block.FolderID = FolderUUID; | ||
4003 | block.FromTaskID = FromTaskUUID; | ||
4004 | block.GroupID = GroupUUID; | ||
4005 | block.InventorySerial = InventorySerial; | ||
4006 | 3997 | ||
4007 | block.LastOwnerID = LastOwnerUUID; | 3998 | IEntityUpdate iupdate; |
4008 | // proper.ObjectData[0].LastOwnerID = UUID.Zero; | 3999 | Int32 timeinqueue; // this is just debugging code & can be dropped later |
4009 | 4000 | ||
4010 | block.ObjectID = ObjectUUID; | 4001 | int updatesThisCall = 0; |
4011 | if (OwnerUUID == GroupUUID) | 4002 | while (updatesThisCall < m_maxUpdates) |
4012 | block.OwnerID = UUID.Zero; | ||
4013 | else | ||
4014 | block.OwnerID = OwnerUUID; | ||
4015 | block.TouchName = Util.StringToBytes256(TouchTitle); | ||
4016 | block.TextureID = TextureID; | ||
4017 | block.SitName = Util.StringToBytes256(SitTitle); | ||
4018 | block.Name = Util.StringToBytes256(ItemName); | ||
4019 | block.Description = Util.StringToBytes256(ItemDescription); | ||
4020 | block.OwnerMask = OwnerMask; | ||
4021 | block.NextOwnerMask = NextOwnerMask; | ||
4022 | block.GroupMask = GroupMask; | ||
4023 | block.EveryoneMask = EveryoneMask; | ||
4024 | block.BaseMask = BaseMask; | ||
4025 | // proper.ObjectData[0].AggregatePerms = 53; | ||
4026 | // proper.ObjectData[0].AggregatePermTextures = 0; | ||
4027 | // proper.ObjectData[0].AggregatePermTexturesOwner = 0; | ||
4028 | block.SaleType = saleType; | ||
4029 | block.SalePrice = salePrice; | ||
4030 | |||
4031 | lock (m_propertiesPacketTimer) | ||
4032 | { | 4003 | { |
4033 | m_propertiesBlocks.Add(block); | 4004 | lock (m_entityProps.SyncRoot) |
4005 | if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) | ||
4006 | break; | ||
4034 | 4007 | ||
4035 | int length = 0; | 4008 | ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; |
4036 | foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) | 4009 | if (update.SendFamilyProps) |
4037 | { | 4010 | { |
4038 | length += b.Length; | 4011 | if (update.Entity is SceneObjectPart) |
4012 | { | ||
4013 | SceneObjectPart sop = (SceneObjectPart)update.Entity; | ||
4014 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); | ||
4015 | objectFamilyBlocks.Value.Add(objPropDB); | ||
4016 | } | ||
4039 | } | 4017 | } |
4040 | if (length > 1100) // FIXME: use real MTU | 4018 | |
4019 | if (update.SendObjectProps) | ||
4041 | { | 4020 | { |
4042 | ProcessObjectPropertiesPacket(null, null); | 4021 | if (update.Entity is SceneObjectPart) |
4043 | m_propertiesPacketTimer.Stop(); | 4022 | { |
4044 | return; | 4023 | SceneObjectPart sop = (SceneObjectPart)update.Entity; |
4024 | ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); | ||
4025 | objectPropertiesBlocks.Value.Add(objPropDB); | ||
4026 | } | ||
4045 | } | 4027 | } |
4046 | 4028 | ||
4047 | m_propertiesPacketTimer.Stop(); | 4029 | updatesThisCall++; |
4048 | m_propertiesPacketTimer.Start(); | ||
4049 | } | 4030 | } |
4031 | |||
4050 | 4032 | ||
4051 | //proper.Header.Zerocoded = true; | 4033 | Int32 ppcnt = 0; |
4052 | //OutPacket(proper, ThrottleOutPacketType.Task); | 4034 | Int32 pbcnt = 0; |
4053 | } | 4035 | |
4036 | if (objectPropertiesBlocks.IsValueCreated) | ||
4037 | { | ||
4038 | List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; | ||
4054 | 4039 | ||
4055 | private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) | 4040 | ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
4056 | { | 4041 | packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; |
4057 | ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 4042 | for (int i = 0; i < blocks.Count; i++) |
4043 | packet.ObjectData[i] = blocks[i]; | ||
4058 | 4044 | ||
4059 | lock (m_propertiesPacketTimer) | 4045 | packet.Header.Zerocoded = true; |
4060 | { | 4046 | OutPacket(packet, ThrottleOutPacketType.Task, true); |
4061 | m_propertiesPacketTimer.Stop(); | ||
4062 | 4047 | ||
4063 | proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; | 4048 | pbcnt += blocks.Count; |
4049 | ppcnt++; | ||
4050 | } | ||
4051 | |||
4052 | Int32 fpcnt = 0; | ||
4053 | Int32 fbcnt = 0; | ||
4054 | |||
4055 | if (objectFamilyBlocks.IsValueCreated) | ||
4056 | { | ||
4057 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; | ||
4064 | 4058 | ||
4065 | int index = 0; | 4059 | // ObjectPropertiesFamilyPacket objPropFamilyPack = |
4060 | // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); | ||
4061 | // | ||
4062 | // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count]; | ||
4063 | // for (int i = 0; i < blocks.Count; i++) | ||
4064 | // objPropFamilyPack.ObjectData[i] = blocks[i]; | ||
4065 | // | ||
4066 | // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true); | ||
4066 | 4067 | ||
4067 | foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) | 4068 | // one packet per object block... uggh... |
4069 | for (int i = 0; i < blocks.Count; i++) | ||
4068 | { | 4070 | { |
4069 | proper.ObjectData[index++] = b; | 4071 | ObjectPropertiesFamilyPacket packet = |
4070 | } | 4072 | (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); |
4073 | |||
4074 | packet.ObjectData = blocks[i]; | ||
4075 | packet.Header.Zerocoded = true; | ||
4076 | OutPacket(packet, ThrottleOutPacketType.Task); | ||
4071 | 4077 | ||
4072 | m_propertiesBlocks.Clear(); | 4078 | fpcnt++; |
4079 | fbcnt++; | ||
4080 | } | ||
4081 | |||
4073 | } | 4082 | } |
4083 | |||
4084 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); | ||
4085 | // m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt); | ||
4086 | } | ||
4087 | |||
4088 | private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags) | ||
4089 | { | ||
4090 | ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); | ||
4074 | 4091 | ||
4075 | proper.Header.Zerocoded = true; | 4092 | block.RequestFlags = requestFlags; |
4076 | OutPacket(proper, ThrottleOutPacketType.Task); | 4093 | block.ObjectID = sop.UUID; |
4094 | if (sop.OwnerID == sop.GroupID) | ||
4095 | block.OwnerID = UUID.Zero; | ||
4096 | else | ||
4097 | block.OwnerID = sop.OwnerID; | ||
4098 | block.GroupID = sop.GroupID; | ||
4099 | block.BaseMask = sop.BaseMask; | ||
4100 | block.OwnerMask = sop.OwnerMask; | ||
4101 | block.GroupMask = sop.GroupMask; | ||
4102 | block.EveryoneMask = sop.EveryoneMask; | ||
4103 | block.NextOwnerMask = sop.NextOwnerMask; | ||
4104 | |||
4105 | // TODO: More properties are needed in SceneObjectPart! | ||
4106 | block.OwnershipCost = sop.OwnershipCost; | ||
4107 | block.SaleType = sop.ObjectSaleType; | ||
4108 | block.SalePrice = sop.SalePrice; | ||
4109 | block.Category = sop.Category; | ||
4110 | block.LastOwnerID = sop.CreatorID; // copied from old SOG call... is this right? | ||
4111 | block.Name = Util.StringToBytes256(sop.Name); | ||
4112 | block.Description = Util.StringToBytes256(sop.Description); | ||
4113 | |||
4114 | return block; | ||
4115 | } | ||
4116 | |||
4117 | private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) | ||
4118 | { | ||
4119 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | ||
4120 | // TODO: don't create new blocks if recycling an old packet | ||
4121 | |||
4122 | ObjectPropertiesPacket.ObjectDataBlock block = | ||
4123 | new ObjectPropertiesPacket.ObjectDataBlock(); | ||
4124 | |||
4125 | block.ObjectID = sop.UUID; | ||
4126 | block.Name = Util.StringToBytes256(sop.Name); | ||
4127 | block.Description = Util.StringToBytes256(sop.Description); | ||
4128 | |||
4129 | block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds | ||
4130 | block.CreatorID = sop.CreatorID; | ||
4131 | block.GroupID = sop.GroupID; | ||
4132 | block.LastOwnerID = sop.LastOwnerID; | ||
4133 | if (sop.OwnerID == sop.GroupID) | ||
4134 | block.OwnerID = UUID.Zero; | ||
4135 | else | ||
4136 | block.OwnerID = sop.OwnerID; | ||
4137 | |||
4138 | block.ItemID = sop.FromUserInventoryItemID; | ||
4139 | block.FolderID = UUID.Zero; // sop.FromFolderID ?? | ||
4140 | block.FromTaskID = UUID.Zero; // ??? | ||
4141 | block.InventorySerial = (short)sop.InventorySerial; | ||
4142 | |||
4143 | SceneObjectPart root = sop.ParentGroup.RootPart; | ||
4144 | |||
4145 | block.TouchName = Util.StringToBytes256(root.TouchName); | ||
4146 | block.TextureID = new byte[0]; // TextureID ??? | ||
4147 | block.SitName = Util.StringToBytes256(root.SitName); | ||
4148 | block.OwnerMask = root.OwnerMask; | ||
4149 | block.NextOwnerMask = root.NextOwnerMask; | ||
4150 | block.GroupMask = root.GroupMask; | ||
4151 | block.EveryoneMask = root.EveryoneMask; | ||
4152 | block.BaseMask = root.BaseMask; | ||
4153 | block.SaleType = root.ObjectSaleType; | ||
4154 | block.SalePrice = root.SalePrice; | ||
4155 | |||
4156 | return block; | ||
4077 | } | 4157 | } |
4078 | 4158 | ||
4079 | #region Estate Data Sending Methods | 4159 | #region Estate Data Sending Methods |
@@ -4217,6 +4297,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4217 | 4297 | ||
4218 | public void SendEstateCovenantInformation(UUID covenant) | 4298 | public void SendEstateCovenantInformation(UUID covenant) |
4219 | { | 4299 | { |
4300 | // m_log.DebugFormat("[LLCLIENTVIEW]: Sending estate covenant asset id of {0} to {1}", covenant, Name); | ||
4301 | |||
4220 | EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); | 4302 | EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket(); |
4221 | EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); | 4303 | EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock(); |
4222 | edata.CovenantID = covenant; | 4304 | edata.CovenantID = covenant; |
@@ -4227,8 +4309,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4227 | OutPacket(einfopack, ThrottleOutPacketType.Task); | 4309 | OutPacket(einfopack, ThrottleOutPacketType.Task); |
4228 | } | 4310 | } |
4229 | 4311 | ||
4230 | public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, string abuseEmail, UUID estateOwner) | 4312 | public void SendDetailedEstateData( |
4313 | UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, | ||
4314 | UUID covenant, string abuseEmail, UUID estateOwner) | ||
4231 | { | 4315 | { |
4316 | // m_log.DebugFormat( | ||
4317 | // "[LLCLIENTVIEW]: Sending detailed estate data to {0} with covenant asset id {1}", Name, covenant); | ||
4318 | |||
4232 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); | 4319 | EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); |
4233 | packet.MethodData.Invoice = invoice; | 4320 | packet.MethodData.Invoice = invoice; |
4234 | packet.AgentData.TransactionID = UUID.Random(); | 4321 | packet.AgentData.TransactionID = UUID.Random(); |
@@ -4407,6 +4494,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4407 | 4494 | ||
4408 | public void SendForceClientSelectObjects(List<uint> ObjectIDs) | 4495 | public void SendForceClientSelectObjects(List<uint> ObjectIDs) |
4409 | { | 4496 | { |
4497 | m_log.WarnFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count); | ||
4498 | |||
4410 | bool firstCall = true; | 4499 | bool firstCall = true; |
4411 | const int MAX_OBJECTS_PER_PACKET = 251; | 4500 | const int MAX_OBJECTS_PER_PACKET = 251; |
4412 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); | 4501 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); |
@@ -11298,7 +11387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11298 | if (logPacket) | 11387 | if (logPacket) |
11299 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); | 11388 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); |
11300 | } | 11389 | } |
11301 | 11390 | ||
11302 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); | 11391 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); |
11303 | } | 11392 | } |
11304 | 11393 | ||
@@ -11726,171 +11815,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11726 | OutPacket(pack, ThrottleOutPacketType.Task); | 11815 | OutPacket(pack, ThrottleOutPacketType.Task); |
11727 | } | 11816 | } |
11728 | 11817 | ||
11729 | #region PriorityQueue | ||
11730 | public class PriorityQueue | ||
11731 | { | ||
11732 | internal delegate bool UpdatePriorityHandler(ref double priority, uint local_id); | ||
11733 | |||
11734 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1]; | ||
11735 | private Dictionary<uint, LookupItem> m_lookupTable; | ||
11736 | private Comparison<double> m_comparison; | ||
11737 | private object m_syncRoot = new object(); | ||
11738 | |||
11739 | internal PriorityQueue() : | ||
11740 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<double>.Default) { } | ||
11741 | internal PriorityQueue(int capacity) : | ||
11742 | this(capacity, Comparer<double>.Default) { } | ||
11743 | internal PriorityQueue(IComparer<double> comparer) : | ||
11744 | this(new Comparison<double>(comparer.Compare)) { } | ||
11745 | internal PriorityQueue(Comparison<double> comparison) : | ||
11746 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { } | ||
11747 | internal PriorityQueue(int capacity, IComparer<double> comparer) : | ||
11748 | this(capacity, new Comparison<double>(comparer.Compare)) { } | ||
11749 | internal PriorityQueue(int capacity, Comparison<double> comparison) | ||
11750 | { | ||
11751 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | ||
11752 | |||
11753 | for (int i = 0; i < m_heaps.Length; ++i) | ||
11754 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
11755 | this.m_comparison = comparison; | ||
11756 | } | ||
11757 | |||
11758 | public object SyncRoot { get { return this.m_syncRoot; } } | ||
11759 | internal int Count | ||
11760 | { | ||
11761 | get | ||
11762 | { | ||
11763 | int count = 0; | ||
11764 | for (int i = 0; i < m_heaps.Length; ++i) | ||
11765 | count = m_heaps[i].Count; | ||
11766 | return count; | ||
11767 | } | ||
11768 | } | ||
11769 | |||
11770 | public bool Enqueue(double priority, EntityUpdate value, uint local_id) | ||
11771 | { | ||
11772 | LookupItem item; | ||
11773 | |||
11774 | if (m_lookupTable.TryGetValue(local_id, out item)) | ||
11775 | { | ||
11776 | // Combine flags | ||
11777 | value.Flags |= item.Heap[item.Handle].Value.Flags; | ||
11778 | |||
11779 | item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison); | ||
11780 | return false; | ||
11781 | } | ||
11782 | else | ||
11783 | { | ||
11784 | item.Heap = m_heaps[0]; | ||
11785 | item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle); | ||
11786 | m_lookupTable.Add(local_id, item); | ||
11787 | return true; | ||
11788 | } | ||
11789 | } | ||
11790 | |||
11791 | internal EntityUpdate Peek() | ||
11792 | { | ||
11793 | for (int i = 0; i < m_heaps.Length; ++i) | ||
11794 | if (m_heaps[i].Count > 0) | ||
11795 | return m_heaps[i].Min().Value; | ||
11796 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
11797 | } | ||
11798 | |||
11799 | internal bool TryDequeue(out EntityUpdate value) | ||
11800 | { | ||
11801 | for (int i = 0; i < m_heaps.Length; ++i) | ||
11802 | { | ||
11803 | if (m_heaps[i].Count > 0) | ||
11804 | { | ||
11805 | MinHeapItem item = m_heaps[i].RemoveMin(); | ||
11806 | m_lookupTable.Remove(item.LocalID); | ||
11807 | value = item.Value; | ||
11808 | return true; | ||
11809 | } | ||
11810 | } | ||
11811 | |||
11812 | value = default(EntityUpdate); | ||
11813 | return false; | ||
11814 | } | ||
11815 | |||
11816 | internal void Reprioritize(UpdatePriorityHandler handler) | ||
11817 | { | ||
11818 | MinHeapItem item; | ||
11819 | double priority; | ||
11820 | |||
11821 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | ||
11822 | { | ||
11823 | if (lookup.Heap.TryGetValue(lookup.Handle, out item)) | ||
11824 | { | ||
11825 | priority = item.Priority; | ||
11826 | if (handler(ref priority, item.LocalID)) | ||
11827 | { | ||
11828 | if (lookup.Heap.ContainsHandle(lookup.Handle)) | ||
11829 | lookup.Heap[lookup.Handle] = | ||
11830 | new MinHeapItem(priority, item.Value, item.LocalID, this.m_comparison); | ||
11831 | } | ||
11832 | else | ||
11833 | { | ||
11834 | m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update"); | ||
11835 | lookup.Heap.Remove(lookup.Handle); | ||
11836 | this.m_lookupTable.Remove(item.LocalID); | ||
11837 | } | ||
11838 | } | ||
11839 | } | ||
11840 | } | ||
11841 | |||
11842 | #region MinHeapItem | ||
11843 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
11844 | { | ||
11845 | private double priority; | ||
11846 | private EntityUpdate value; | ||
11847 | private uint local_id; | ||
11848 | private Comparison<double> comparison; | ||
11849 | |||
11850 | internal MinHeapItem(double priority, EntityUpdate value, uint local_id) : | ||
11851 | this(priority, value, local_id, Comparer<double>.Default) { } | ||
11852 | internal MinHeapItem(double priority, EntityUpdate value, uint local_id, IComparer<double> comparer) : | ||
11853 | this(priority, value, local_id, new Comparison<double>(comparer.Compare)) { } | ||
11854 | internal MinHeapItem(double priority, EntityUpdate value, uint local_id, Comparison<double> comparison) | ||
11855 | { | ||
11856 | this.priority = priority; | ||
11857 | this.value = value; | ||
11858 | this.local_id = local_id; | ||
11859 | this.comparison = comparison; | ||
11860 | } | ||
11861 | |||
11862 | internal double Priority { get { return this.priority; } } | ||
11863 | internal EntityUpdate Value { get { return this.value; } } | ||
11864 | internal uint LocalID { get { return this.local_id; } } | ||
11865 | |||
11866 | public override string ToString() | ||
11867 | { | ||
11868 | StringBuilder sb = new StringBuilder(); | ||
11869 | sb.Append("["); | ||
11870 | sb.Append(this.priority.ToString()); | ||
11871 | sb.Append(","); | ||
11872 | if (this.value != null) | ||
11873 | sb.Append(this.value.ToString()); | ||
11874 | sb.Append("]"); | ||
11875 | return sb.ToString(); | ||
11876 | } | ||
11877 | |||
11878 | public int CompareTo(MinHeapItem other) | ||
11879 | { | ||
11880 | return this.comparison(this.priority, other.priority); | ||
11881 | } | ||
11882 | } | ||
11883 | #endregion | ||
11884 | |||
11885 | #region LookupItem | ||
11886 | private struct LookupItem | ||
11887 | { | ||
11888 | internal MinHeap<MinHeapItem> Heap; | ||
11889 | internal IHandle Handle; | ||
11890 | } | ||
11891 | #endregion | ||
11892 | } | ||
11893 | |||
11894 | public struct PacketProcessor | 11818 | public struct PacketProcessor |
11895 | { | 11819 | { |
11896 | public PacketMethod method; | 11820 | public PacketMethod method; |
@@ -11911,8 +11835,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11911 | } | 11835 | } |
11912 | } | 11836 | } |
11913 | 11837 | ||
11914 | #endregion | ||
11915 | |||
11916 | public static OSD BuildEvent(string eventName, OSD eventBody) | 11838 | public static OSD BuildEvent(string eventName, OSD eventBody) |
11917 | { | 11839 | { |
11918 | OSDMap osdEvent = new OSDMap(2); | 11840 | OSDMap osdEvent = new OSDMap(2); |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 65a8fe3..7be8a0a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -135,7 +135,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
135 | private int m_nextOnQueueEmpty = 1; | 135 | private int m_nextOnQueueEmpty = 1; |
136 | 136 | ||
137 | /// <summary>Throttle bucket for this agent's connection</summary> | 137 | /// <summary>Throttle bucket for this agent's connection</summary> |
138 | private readonly TokenBucket m_throttle; | 138 | private readonly TokenBucket m_throttleClient; |
139 | /// <summary>Throttle bucket for this agent's connection</summary> | ||
140 | private readonly TokenBucket m_throttleCategory; | ||
139 | /// <summary>Throttle buckets for each packet category</summary> | 141 | /// <summary>Throttle buckets for each packet category</summary> |
140 | private readonly TokenBucket[] m_throttleCategories; | 142 | private readonly TokenBucket[] m_throttleCategories; |
141 | /// <summary>Outgoing queues for throttled packets</summary> | 143 | /// <summary>Outgoing queues for throttled packets</summary> |
@@ -149,7 +151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
149 | /// <summary>Caches packed throttle information</summary> | 151 | /// <summary>Caches packed throttle information</summary> |
150 | private byte[] m_packedThrottles; | 152 | private byte[] m_packedThrottles; |
151 | 153 | ||
152 | private int m_defaultRTO = 3000; | 154 | private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC |
153 | private int m_maxRTO = 60000; | 155 | private int m_maxRTO = 60000; |
154 | 156 | ||
155 | /// <summary> | 157 | /// <summary> |
@@ -174,7 +176,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
174 | m_maxRTO = maxRTO; | 176 | m_maxRTO = maxRTO; |
175 | 177 | ||
176 | // Create a token bucket throttle for this client that has the scene token bucket as a parent | 178 | // Create a token bucket throttle for this client that has the scene token bucket as a parent |
177 | m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total); | 179 | m_throttleClient = new TokenBucket(parentThrottle, rates.TotalLimit); |
180 | // Create a token bucket throttle for the total categary with the client bucket as a throttle | ||
181 | m_throttleCategory = new TokenBucket(m_throttleClient, rates.TotalLimit); | ||
178 | // Create an array of token buckets for this clients different throttle categories | 182 | // Create an array of token buckets for this clients different throttle categories |
179 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; | 183 | m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; |
180 | 184 | ||
@@ -185,7 +189,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
185 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | 189 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens |
186 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 190 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
187 | // Initialize the token buckets that control the throttling for each category | 191 | // Initialize the token buckets that control the throttling for each category |
188 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); | 192 | m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetLimit(type)); |
189 | } | 193 | } |
190 | 194 | ||
191 | // Default the retransmission timeout to three seconds | 195 | // Default the retransmission timeout to three seconds |
@@ -206,6 +210,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
206 | m_packetOutboxes[i].Clear(); | 210 | m_packetOutboxes[i].Clear(); |
207 | m_nextPackets[i] = null; | 211 | m_nextPackets[i] = null; |
208 | } | 212 | } |
213 | |||
214 | // pull the throttle out of the scene throttle | ||
215 | m_throttleClient.Parent.UnregisterRequest(m_throttleClient); | ||
209 | OnPacketStats = null; | 216 | OnPacketStats = null; |
210 | OnQueueEmpty = null; | 217 | OnQueueEmpty = null; |
211 | } | 218 | } |
@@ -216,6 +223,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
216 | /// <returns>Information about the client connection</returns> | 223 | /// <returns>Information about the client connection</returns> |
217 | public ClientInfo GetClientInfo() | 224 | public ClientInfo GetClientInfo() |
218 | { | 225 | { |
226 | ///<mic> | ||
227 | TokenBucket tb; | ||
228 | |||
229 | tb = m_throttleClient.Parent; | ||
230 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest,"ROOT"); | ||
231 | |||
232 | tb = m_throttleClient; | ||
233 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CLIENT"); | ||
234 | |||
235 | tb = m_throttleCategory; | ||
236 | m_log.WarnFormat("[TOKENS] {3}: Actual={0},Request={1},TotalRequest={2}",tb.DripRate,tb.RequestedDripRate,tb.TotalDripRequest," CATEGORY"); | ||
237 | |||
238 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | ||
239 | { | ||
240 | tb = m_throttleCategories[i]; | ||
241 | m_log.WarnFormat("[TOKENS] {4} <{0}:{1}>: Actual={2},Requested={3}",AgentID,i,tb.DripRate,tb.RequestedDripRate," BUCKET"); | ||
242 | } | ||
243 | |||
244 | ///</mic> | ||
245 | |||
219 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists | 246 | // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists |
220 | // of pending and needed ACKs for every client every time some method wants information about | 247 | // of pending and needed ACKs for every client every time some method wants information about |
221 | // this connection is a recipe for poor performance | 248 | // this connection is a recipe for poor performance |
@@ -223,13 +250,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
223 | info.pendingAcks = new Dictionary<uint, uint>(); | 250 | info.pendingAcks = new Dictionary<uint, uint>(); |
224 | info.needAck = new Dictionary<uint, byte[]>(); | 251 | info.needAck = new Dictionary<uint, byte[]>(); |
225 | 252 | ||
226 | info.resendThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; | 253 | info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; |
227 | info.landThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; | 254 | info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; |
228 | info.windThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; | 255 | info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; |
229 | info.cloudThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; | 256 | info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; |
230 | info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; | 257 | // info.taskThrottle = m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate + m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
231 | info.assetThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; | 258 | info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; |
232 | info.textureThrottle = m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | 259 | info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; |
260 | info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; | ||
233 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + | 261 | info.totalThrottle = info.resendThrottle + info.landThrottle + info.windThrottle + info.cloudThrottle + |
234 | info.taskThrottle + info.assetThrottle + info.textureThrottle; | 262 | info.taskThrottle + info.assetThrottle + info.textureThrottle; |
235 | 263 | ||
@@ -317,8 +345,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
317 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; | 345 | int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; |
318 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); | 346 | int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); |
319 | // State is a subcategory of task that we allocate a percentage to | 347 | // State is a subcategory of task that we allocate a percentage to |
320 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); | 348 | int state = 0; |
321 | task -= state; | 349 | // int state = (int)((float)task * STATE_TASK_PERCENTAGE); |
350 | // task -= state; | ||
322 | 351 | ||
323 | // Make sure none of the throttles are set below our packet MTU, | 352 | // Make sure none of the throttles are set below our packet MTU, |
324 | // otherwise a throttle could become permanently clogged | 353 | // otherwise a throttle could become permanently clogged |
@@ -339,40 +368,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
339 | // Update the token buckets with new throttle values | 368 | // Update the token buckets with new throttle values |
340 | TokenBucket bucket; | 369 | TokenBucket bucket; |
341 | 370 | ||
342 | bucket = m_throttle; | 371 | bucket = m_throttleCategory; |
343 | bucket.MaxBurst = total; | 372 | bucket.RequestedDripRate = total; |
344 | 373 | ||
345 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; | 374 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
346 | bucket.DripRate = resend; | 375 | bucket.RequestedDripRate = resend; |
347 | bucket.MaxBurst = resend; | ||
348 | 376 | ||
349 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | 377 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; |
350 | bucket.DripRate = land; | 378 | bucket.RequestedDripRate = land; |
351 | bucket.MaxBurst = land; | ||
352 | 379 | ||
353 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | 380 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; |
354 | bucket.DripRate = wind; | 381 | bucket.RequestedDripRate = wind; |
355 | bucket.MaxBurst = wind; | ||
356 | 382 | ||
357 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | 383 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; |
358 | bucket.DripRate = cloud; | 384 | bucket.RequestedDripRate = cloud; |
359 | bucket.MaxBurst = cloud; | ||
360 | 385 | ||
361 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | 386 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; |
362 | bucket.DripRate = asset; | 387 | bucket.RequestedDripRate = asset; |
363 | bucket.MaxBurst = asset; | ||
364 | 388 | ||
365 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | 389 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; |
366 | bucket.DripRate = task + state; | 390 | bucket.RequestedDripRate = task; |
367 | bucket.MaxBurst = task + state; | ||
368 | 391 | ||
369 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; | 392 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; |
370 | bucket.DripRate = state; | 393 | bucket.RequestedDripRate = state; |
371 | bucket.MaxBurst = state; | ||
372 | 394 | ||
373 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | 395 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; |
374 | bucket.DripRate = texture; | 396 | bucket.RequestedDripRate = texture; |
375 | bucket.MaxBurst = texture; | ||
376 | 397 | ||
377 | // Reset the packed throttles cached data | 398 | // Reset the packed throttles cached data |
378 | m_packedThrottles = null; | 399 | m_packedThrottles = null; |
@@ -387,14 +408,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
387 | data = new byte[7 * 4]; | 408 | data = new byte[7 * 4]; |
388 | int i = 0; | 409 | int i = 0; |
389 | 410 | ||
390 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate), 0, data, i, 4); i += 4; | 411 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate), 0, data, i, 4); i += 4; |
391 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate), 0, data, i, 4); i += 4; | 412 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate), 0, data, i, 4); i += 4; |
392 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate), 0, data, i, 4); i += 4; | 413 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate), 0, data, i, 4); i += 4; |
393 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate), 0, data, i, 4); i += 4; | 414 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate), 0, data, i, 4); i += 4; |
394 | Buffer.BlockCopy(Utils.FloatToBytes((float)(m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate) + | 415 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate), 0, data, i, 4); i += 4; |
395 | m_throttleCategories[(int)ThrottleOutPacketType.State].DripRate), 0, data, i, 4); i += 4; | 416 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate), 0, data, i, 4); i += 4; |
396 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate), 0, data, i, 4); i += 4; | 417 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate), 0, data, i, 4); i += 4; |
397 | Buffer.BlockCopy(Utils.FloatToBytes((float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate), 0, data, i, 4); i += 4; | ||
398 | 418 | ||
399 | m_packedThrottles = data; | 419 | m_packedThrottles = data; |
400 | } | 420 | } |
@@ -420,6 +440,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
420 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; | 440 | OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; |
421 | TokenBucket bucket = m_throttleCategories[category]; | 441 | TokenBucket bucket = m_throttleCategories[category]; |
422 | 442 | ||
443 | // Don't send this packet if there is already a packet waiting in the queue | ||
444 | // even if we have the tokens to send it, tokens should go to the already | ||
445 | // queued packets | ||
446 | if (queue.Count > 0) | ||
447 | { | ||
448 | queue.Enqueue(packet); | ||
449 | return true; | ||
450 | } | ||
451 | |||
452 | |||
423 | if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength)) | 453 | if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength)) |
424 | { | 454 | { |
425 | // Enough tokens were removed from the bucket, the packet will not be queued | 455 | // Enough tokens were removed from the bucket, the packet will not be queued |
@@ -557,7 +587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
557 | int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); | 587 | int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR)); |
558 | 588 | ||
559 | // Clamp the retransmission timeout to manageable values | 589 | // Clamp the retransmission timeout to manageable values |
560 | rto = Utils.Clamp(RTO, m_defaultRTO, m_maxRTO); | 590 | rto = Utils.Clamp(rto, m_defaultRTO, m_maxRTO); |
561 | 591 | ||
562 | RTO = rto; | 592 | RTO = rto; |
563 | 593 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 583214c..d08b25f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -228,7 +228,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
228 | } | 228 | } |
229 | #endregion BinaryStats | 229 | #endregion BinaryStats |
230 | 230 | ||
231 | m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); | 231 | m_throttle = new TokenBucket(null, sceneThrottleBps); |
232 | ThrottleRates = new ThrottleRates(configSource); | 232 | ThrottleRates = new ThrottleRates(configSource); |
233 | } | 233 | } |
234 | 234 | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs new file mode 100644 index 0000000..b62ec07 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/PriorityQueue.cs | |||
@@ -0,0 +1,245 @@ | |||
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 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Client; | ||
35 | using log4net; | ||
36 | |||
37 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
38 | { | ||
39 | public class PriorityQueue | ||
40 | { | ||
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
42 | |||
43 | internal delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); | ||
44 | |||
45 | // Heap[0] for self updates | ||
46 | // Heap[1..12] for entity updates | ||
47 | |||
48 | internal const uint m_numberOfQueues = 12; | ||
49 | |||
50 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[m_numberOfQueues]; | ||
51 | private Dictionary<uint, LookupItem> m_lookupTable; | ||
52 | private uint m_nextQueue = 0; | ||
53 | private UInt64 m_nextRequest = 0; | ||
54 | |||
55 | private object m_syncRoot = new object(); | ||
56 | public object SyncRoot { | ||
57 | get { return this.m_syncRoot; } | ||
58 | } | ||
59 | |||
60 | internal PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } | ||
61 | |||
62 | internal PriorityQueue(int capacity) | ||
63 | { | ||
64 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | ||
65 | |||
66 | for (int i = 0; i < m_heaps.Length; ++i) | ||
67 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
68 | } | ||
69 | |||
70 | internal int Count | ||
71 | { | ||
72 | get | ||
73 | { | ||
74 | int count = 0; | ||
75 | for (int i = 0; i < m_heaps.Length; ++i) | ||
76 | count += m_heaps[i].Count; | ||
77 | return count; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | public bool Enqueue(uint pqueue, IEntityUpdate value) | ||
82 | { | ||
83 | LookupItem lookup; | ||
84 | |||
85 | uint localid = value.Entity.LocalId; | ||
86 | UInt64 entry = m_nextRequest++; | ||
87 | if (m_lookupTable.TryGetValue(localid, out lookup)) | ||
88 | { | ||
89 | entry = lookup.Heap[lookup.Handle].EntryOrder; | ||
90 | value.Update(lookup.Heap[lookup.Handle].Value); | ||
91 | lookup.Heap.Remove(lookup.Handle); | ||
92 | } | ||
93 | |||
94 | pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1); | ||
95 | lookup.Heap = m_heaps[pqueue]; | ||
96 | lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle); | ||
97 | m_lookupTable[localid] = lookup; | ||
98 | |||
99 | return true; | ||
100 | } | ||
101 | |||
102 | internal bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) | ||
103 | { | ||
104 | for (int i = 0; i < m_numberOfQueues; ++i) | ||
105 | { | ||
106 | // To get the fair queing, we cycle through each of the | ||
107 | // queues when finding an element to dequeue, this code | ||
108 | // assumes that the distribution of updates in the queues | ||
109 | // is polynomial, probably quadractic (eg distance of PI * R^2) | ||
110 | uint h = (uint)((m_nextQueue + i) % m_numberOfQueues); | ||
111 | if (m_heaps[h].Count > 0) | ||
112 | { | ||
113 | m_nextQueue = (uint)((h + 1) % m_numberOfQueues); | ||
114 | |||
115 | MinHeapItem item = m_heaps[h].RemoveMin(); | ||
116 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
117 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
118 | value = item.Value; | ||
119 | |||
120 | return true; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | timeinqueue = 0; | ||
125 | value = default(IEntityUpdate); | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | internal void Reprioritize(UpdatePriorityHandler handler) | ||
130 | { | ||
131 | MinHeapItem item; | ||
132 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | ||
133 | { | ||
134 | if (lookup.Heap.TryGetValue(lookup.Handle, out item)) | ||
135 | { | ||
136 | uint pqueue = item.PriorityQueue; | ||
137 | uint localid = item.Value.Entity.LocalId; | ||
138 | |||
139 | if (handler(ref pqueue, item.Value.Entity)) | ||
140 | { | ||
141 | // unless the priority queue has changed, there is no need to modify | ||
142 | // the entry | ||
143 | pqueue = Util.Clamp<uint>(pqueue, 0, m_numberOfQueues - 1); | ||
144 | if (pqueue != item.PriorityQueue) | ||
145 | { | ||
146 | lookup.Heap.Remove(lookup.Handle); | ||
147 | |||
148 | LookupItem litem = lookup; | ||
149 | litem.Heap = m_heaps[pqueue]; | ||
150 | litem.Heap.Add(new MinHeapItem(pqueue, item), ref litem.Handle); | ||
151 | m_lookupTable[localid] = litem; | ||
152 | } | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | // m_log.WarnFormat("[PQUEUE]: UpdatePriorityHandler returned false for {0}",item.Value.Entity.UUID); | ||
157 | lookup.Heap.Remove(lookup.Handle); | ||
158 | this.m_lookupTable.Remove(localid); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | public override string ToString() | ||
165 | { | ||
166 | string s = ""; | ||
167 | for (int i = 0; i < m_numberOfQueues; i++) | ||
168 | { | ||
169 | if (s != "") s += ","; | ||
170 | s += m_heaps[i].Count.ToString(); | ||
171 | } | ||
172 | return s; | ||
173 | } | ||
174 | |||
175 | #region MinHeapItem | ||
176 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
177 | { | ||
178 | private IEntityUpdate value; | ||
179 | internal IEntityUpdate Value { | ||
180 | get { | ||
181 | return this.value; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | private uint pqueue; | ||
186 | internal uint PriorityQueue { | ||
187 | get { | ||
188 | return this.pqueue; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | private Int32 entrytime; | ||
193 | internal Int32 EntryTime { | ||
194 | get { | ||
195 | return this.entrytime; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | private UInt64 entryorder; | ||
200 | internal UInt64 EntryOrder | ||
201 | { | ||
202 | get { | ||
203 | return this.entryorder; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | internal MinHeapItem(uint pqueue, MinHeapItem other) | ||
208 | { | ||
209 | this.entrytime = other.entrytime; | ||
210 | this.entryorder = other.entryorder; | ||
211 | this.value = other.value; | ||
212 | this.pqueue = pqueue; | ||
213 | } | ||
214 | |||
215 | internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value) | ||
216 | { | ||
217 | this.entrytime = Util.EnvironmentTickCount(); | ||
218 | this.entryorder = entryorder; | ||
219 | this.value = value; | ||
220 | this.pqueue = pqueue; | ||
221 | } | ||
222 | |||
223 | public override string ToString() | ||
224 | { | ||
225 | return String.Format("[{0},{1},{2}]",pqueue,entryorder,value.Entity.LocalId); | ||
226 | } | ||
227 | |||
228 | public int CompareTo(MinHeapItem other) | ||
229 | { | ||
230 | // I'm assuming that the root part of an SOG is added to the update queue | ||
231 | // before the component parts | ||
232 | return Comparer<UInt64>.Default.Compare(this.EntryOrder, other.EntryOrder); | ||
233 | } | ||
234 | } | ||
235 | #endregion | ||
236 | |||
237 | #region LookupItem | ||
238 | private struct LookupItem | ||
239 | { | ||
240 | internal MinHeap<MinHeapItem> Heap; | ||
241 | internal IHandle Handle; | ||
242 | } | ||
243 | #endregion | ||
244 | } | ||
245 | } | ||
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs index 0a8331f..07b0a1d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs | |||
@@ -26,6 +26,10 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
29 | 33 | ||
30 | namespace OpenSim.Region.ClientStack.LindenUDP | 34 | namespace OpenSim.Region.ClientStack.LindenUDP |
31 | { | 35 | { |
@@ -35,89 +39,126 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
35 | /// </summary> | 39 | /// </summary> |
36 | public class TokenBucket | 40 | public class TokenBucket |
37 | { | 41 | { |
38 | /// <summary>Parent bucket to this bucket, or null if this is a root | 42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
39 | /// bucket</summary> | 43 | private static Int32 m_counter = 0; |
40 | TokenBucket parent; | 44 | |
41 | /// <summary>Size of the bucket in bytes. If zero, the bucket has | 45 | private Int32 m_identifier; |
42 | /// infinite capacity</summary> | 46 | |
43 | int maxBurst; | 47 | /// <summary> |
44 | /// <summary>Rate that the bucket fills, in bytes per millisecond. If | 48 | /// Number of ticks (ms) per quantum, drip rate and max burst |
45 | /// zero, the bucket always remains full</summary> | 49 | /// are defined over this interval. |
46 | int tokensPerMS; | 50 | /// </summary> |
47 | /// <summary>Number of tokens currently in the bucket</summary> | 51 | private const Int32 m_ticksPerQuantum = 1000; |
48 | int content; | 52 | |
53 | /// <summary> | ||
54 | /// This is the number of quantums worth of packets that can | ||
55 | /// be accommodated during a burst | ||
56 | /// </summary> | ||
57 | private const Double m_quantumsPerBurst = 1.5; | ||
58 | |||
59 | /// <summary> | ||
60 | /// </summary> | ||
61 | private const Int32 m_minimumDripRate = 1400; | ||
62 | |||
49 | /// <summary>Time of the last drip, in system ticks</summary> | 63 | /// <summary>Time of the last drip, in system ticks</summary> |
50 | int lastDrip; | 64 | private Int32 m_lastDrip; |
51 | 65 | ||
52 | #region Properties | 66 | /// <summary> |
67 | /// The number of bytes that can be sent at this moment. This is the | ||
68 | /// current number of tokens in the bucket | ||
69 | /// </summary> | ||
70 | private Int64 m_tokenCount; | ||
71 | |||
72 | /// <summary> | ||
73 | /// Map of children buckets and their requested maximum burst rate | ||
74 | /// </summary> | ||
75 | private Dictionary<TokenBucket,Int64> m_children = new Dictionary<TokenBucket,Int64>(); | ||
76 | |||
77 | #region Properties | ||
53 | 78 | ||
54 | /// <summary> | 79 | /// <summary> |
55 | /// The parent bucket of this bucket, or null if this bucket has no | 80 | /// The parent bucket of this bucket, or null if this bucket has no |
56 | /// parent. The parent bucket will limit the aggregate bandwidth of all | 81 | /// parent. The parent bucket will limit the aggregate bandwidth of all |
57 | /// of its children buckets | 82 | /// of its children buckets |
58 | /// </summary> | 83 | /// </summary> |
84 | private TokenBucket m_parent; | ||
59 | public TokenBucket Parent | 85 | public TokenBucket Parent |
60 | { | 86 | { |
61 | get { return parent; } | 87 | get { return m_parent; } |
88 | set { m_parent = value; } | ||
62 | } | 89 | } |
63 | 90 | ||
64 | /// <summary> | 91 | /// <summary> |
65 | /// Maximum burst rate in bytes per second. This is the maximum number | 92 | /// Maximum burst rate in bytes per second. This is the maximum number |
66 | /// of tokens that can accumulate in the bucket at any one time | 93 | /// of tokens that can accumulate in the bucket at any one time. This |
94 | /// also sets the total request for leaf nodes | ||
67 | /// </summary> | 95 | /// </summary> |
68 | public int MaxBurst | 96 | private Int64 m_burstRate; |
97 | public Int64 RequestedBurstRate | ||
69 | { | 98 | { |
70 | get { return maxBurst; } | 99 | get { return m_burstRate; } |
71 | set { maxBurst = (value >= 0 ? value : 0); } | 100 | set { m_burstRate = (value < 0 ? 0 : value); } |
72 | } | 101 | } |
73 | 102 | ||
103 | public Int64 BurstRate | ||
104 | { | ||
105 | get { | ||
106 | double rate = RequestedBurstRate * BurstRateModifier(); | ||
107 | if (rate < m_minimumDripRate * m_quantumsPerBurst) | ||
108 | rate = m_minimumDripRate * m_quantumsPerBurst; | ||
109 | |||
110 | return (Int64) rate; | ||
111 | } | ||
112 | } | ||
113 | |||
74 | /// <summary> | 114 | /// <summary> |
75 | /// The speed limit of this bucket in bytes per second. This is the | 115 | /// The speed limit of this bucket in bytes per second. This is the |
76 | /// number of tokens that are added to the bucket per second | 116 | /// number of tokens that are added to the bucket per quantum |
77 | /// </summary> | 117 | /// </summary> |
78 | /// <remarks>Tokens are added to the bucket any time | 118 | /// <remarks>Tokens are added to the bucket any time |
79 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of | 119 | /// <seealso cref="RemoveTokens"/> is called, at the granularity of |
80 | /// the system tick interval (typically around 15-22ms)</remarks> | 120 | /// the system tick interval (typically around 15-22ms)</remarks> |
81 | public int DripRate | 121 | private Int64 m_dripRate; |
122 | public Int64 RequestedDripRate | ||
82 | { | 123 | { |
83 | get { return tokensPerMS * 1000; } | 124 | get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); } |
84 | set | 125 | set { |
85 | { | 126 | m_dripRate = (value < 0 ? 0 : value); |
86 | if (value == 0) | 127 | m_burstRate = (Int64)((double)m_dripRate * m_quantumsPerBurst); |
87 | tokensPerMS = 0; | 128 | m_totalDripRequest = m_dripRate; |
88 | else | 129 | if (m_parent != null) |
89 | { | 130 | m_parent.RegisterRequest(this,m_dripRate); |
90 | int bpms = (int)((float)value / 1000.0f); | ||
91 | |||
92 | if (bpms <= 0) | ||
93 | tokensPerMS = 1; // 1 byte/ms is the minimum granularity | ||
94 | else | ||
95 | tokensPerMS = bpms; | ||
96 | } | ||
97 | } | 131 | } |
98 | } | 132 | } |
99 | 133 | ||
100 | /// <summary> | 134 | public Int64 DripRate |
101 | /// The speed limit of this bucket in bytes per millisecond | ||
102 | /// </summary> | ||
103 | public int DripPerMS | ||
104 | { | 135 | { |
105 | get { return tokensPerMS; } | 136 | get { |
137 | if (m_parent == null) | ||
138 | return Math.Min(RequestedDripRate,TotalDripRequest); | ||
139 | |||
140 | double rate = (double)RequestedDripRate * m_parent.DripRateModifier(); | ||
141 | if (rate < m_minimumDripRate) | ||
142 | rate = m_minimumDripRate; | ||
143 | |||
144 | return (Int64)rate; | ||
145 | } | ||
106 | } | 146 | } |
107 | 147 | ||
108 | /// <summary> | 148 | /// <summary> |
109 | /// The number of bytes that can be sent at this moment. This is the | 149 | /// The current total of the requested maximum burst rates of |
110 | /// current number of tokens in the bucket | 150 | /// this bucket's children buckets. |
111 | /// <remarks>If this bucket has a parent bucket that does not have | ||
112 | /// enough tokens for a request, <seealso cref="RemoveTokens"/> will | ||
113 | /// return false regardless of the content of this bucket</remarks> | ||
114 | /// </summary> | 151 | /// </summary> |
115 | public int Content | 152 | private Int64 m_totalDripRequest; |
116 | { | 153 | public Int64 TotalDripRequest |
117 | get { return content; } | 154 | { |
118 | } | 155 | get { return m_totalDripRequest; } |
156 | set { m_totalDripRequest = value; } | ||
157 | } | ||
158 | |||
159 | #endregion Properties | ||
119 | 160 | ||
120 | #endregion Properties | 161 | #region Constructor |
121 | 162 | ||
122 | /// <summary> | 163 | /// <summary> |
123 | /// Default constructor | 164 | /// Default constructor |
@@ -128,56 +169,114 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
128 | /// zero if this bucket has no maximum capacity</param> | 169 | /// zero if this bucket has no maximum capacity</param> |
129 | /// <param name="dripRate">Rate that the bucket fills, in bytes per | 170 | /// <param name="dripRate">Rate that the bucket fills, in bytes per |
130 | /// second. If zero, the bucket always remains full</param> | 171 | /// second. If zero, the bucket always remains full</param> |
131 | public TokenBucket(TokenBucket parent, int maxBurst, int dripRate) | 172 | public TokenBucket(TokenBucket parent, Int64 dripRate) |
132 | { | 173 | { |
133 | this.parent = parent; | 174 | m_identifier = m_counter++; |
134 | MaxBurst = maxBurst; | 175 | |
135 | DripRate = dripRate; | 176 | Parent = parent; |
136 | lastDrip = Environment.TickCount & Int32.MaxValue; | 177 | RequestedDripRate = dripRate; |
178 | // TotalDripRequest = dripRate; // this will be overwritten when a child node registers | ||
179 | // MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst); | ||
180 | m_lastDrip = Environment.TickCount & Int32.MaxValue; | ||
137 | } | 181 | } |
138 | 182 | ||
183 | #endregion Constructor | ||
184 | |||
139 | /// <summary> | 185 | /// <summary> |
140 | /// Remove a given number of tokens from the bucket | 186 | /// Compute a modifier for the MaxBurst rate. This is 1.0, meaning |
187 | /// no modification if the requested bandwidth is less than the | ||
188 | /// max burst bandwidth all the way to the root of the throttle | ||
189 | /// hierarchy. However, if any of the parents is over-booked, then | ||
190 | /// the modifier will be less than 1. | ||
141 | /// </summary> | 191 | /// </summary> |
142 | /// <param name="amount">Number of tokens to remove from the bucket</param> | 192 | private double DripRateModifier() |
143 | /// <returns>True if the requested number of tokens were removed from | ||
144 | /// the bucket, otherwise false</returns> | ||
145 | public bool RemoveTokens(int amount) | ||
146 | { | 193 | { |
147 | bool dummy; | 194 | Int64 driprate = DripRate; |
148 | return RemoveTokens(amount, out dummy); | 195 | return driprate >= TotalDripRequest ? 1.0 : (double)driprate / (double)TotalDripRequest; |
149 | } | 196 | } |
150 | 197 | ||
151 | /// <summary> | 198 | /// <summary> |
199 | /// </summary> | ||
200 | private double BurstRateModifier() | ||
201 | { | ||
202 | // for now... burst rate is always m_quantumsPerBurst (constant) | ||
203 | // larger than drip rate so the ratio of burst requests is the | ||
204 | // same as the drip ratio | ||
205 | return DripRateModifier(); | ||
206 | } | ||
207 | |||
208 | /// <summary> | ||
209 | /// Register drip rate requested by a child of this throttle. Pass the | ||
210 | /// changes up the hierarchy. | ||
211 | /// </summary> | ||
212 | public void RegisterRequest(TokenBucket child, Int64 request) | ||
213 | { | ||
214 | m_children[child] = request; | ||
215 | // m_totalDripRequest = m_children.Values.Sum(); | ||
216 | |||
217 | m_totalDripRequest = 0; | ||
218 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | ||
219 | m_totalDripRequest += cref.Value; | ||
220 | |||
221 | // Pass the new values up to the parent | ||
222 | if (m_parent != null) | ||
223 | m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); | ||
224 | } | ||
225 | |||
226 | /// <summary> | ||
227 | /// Remove the rate requested by a child of this throttle. Pass the | ||
228 | /// changes up the hierarchy. | ||
229 | /// </summary> | ||
230 | public void UnregisterRequest(TokenBucket child) | ||
231 | { | ||
232 | m_children.Remove(child); | ||
233 | // m_totalDripRequest = m_children.Values.Sum(); | ||
234 | |||
235 | m_totalDripRequest = 0; | ||
236 | foreach (KeyValuePair<TokenBucket, Int64> cref in m_children) | ||
237 | m_totalDripRequest += cref.Value; | ||
238 | |||
239 | // Pass the new values up to the parent | ||
240 | if (m_parent != null) | ||
241 | m_parent.RegisterRequest(this,Math.Min(RequestedDripRate, TotalDripRequest)); | ||
242 | } | ||
243 | |||
244 | /// <summary> | ||
152 | /// Remove a given number of tokens from the bucket | 245 | /// Remove a given number of tokens from the bucket |
153 | /// </summary> | 246 | /// </summary> |
154 | /// <param name="amount">Number of tokens to remove from the bucket</param> | 247 | /// <param name="amount">Number of tokens to remove from the bucket</param> |
155 | /// <param name="dripSucceeded">True if tokens were added to the bucket | ||
156 | /// during this call, otherwise false</param> | ||
157 | /// <returns>True if the requested number of tokens were removed from | 248 | /// <returns>True if the requested number of tokens were removed from |
158 | /// the bucket, otherwise false</returns> | 249 | /// the bucket, otherwise false</returns> |
159 | public bool RemoveTokens(int amount, out bool dripSucceeded) | 250 | public bool RemoveTokens(Int64 amount) |
160 | { | 251 | { |
161 | if (maxBurst == 0) | 252 | // Deposit tokens for this interval |
253 | Drip(); | ||
254 | |||
255 | // If we have enough tokens then remove them and return | ||
256 | if (m_tokenCount - amount >= 0) | ||
162 | { | 257 | { |
163 | dripSucceeded = true; | 258 | // we don't have to remove from the parent, the drip rate is already |
259 | // reflective of the drip rate limits in the parent | ||
260 | m_tokenCount -= amount; | ||
164 | return true; | 261 | return true; |
165 | } | 262 | } |
166 | 263 | ||
167 | dripSucceeded = Drip(); | 264 | return false; |
265 | } | ||
168 | 266 | ||
169 | if (content - amount >= 0) | 267 | /// <summary> |
170 | { | 268 | /// Deposit tokens into the bucket from a child bucket that did |
171 | if (parent != null && !parent.RemoveTokens(amount)) | 269 | /// not use all of its available tokens |
172 | return false; | 270 | /// </summary> |
271 | private void Deposit(Int64 count) | ||
272 | { | ||
273 | m_tokenCount += count; | ||
173 | 274 | ||
174 | content -= amount; | 275 | // Deposit the overflow in the parent bucket, this is how we share |
175 | return true; | 276 | // unused bandwidth |
176 | } | 277 | Int64 burstrate = BurstRate; |
177 | else | 278 | if (m_tokenCount > burstrate) |
178 | { | 279 | m_tokenCount = burstrate; |
179 | return false; | ||
180 | } | ||
181 | } | 280 | } |
182 | 281 | ||
183 | /// <summary> | 282 | /// <summary> |
@@ -186,37 +285,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
186 | /// call to Drip | 285 | /// call to Drip |
187 | /// </summary> | 286 | /// </summary> |
188 | /// <returns>True if tokens were added to the bucket, otherwise false</returns> | 287 | /// <returns>True if tokens were added to the bucket, otherwise false</returns> |
189 | public bool Drip() | 288 | private void Drip() |
190 | { | 289 | { |
191 | if (tokensPerMS == 0) | 290 | // This should never happen... means we are a leaf node and were created |
291 | // with no drip rate... | ||
292 | if (DripRate == 0) | ||
192 | { | 293 | { |
193 | content = maxBurst; | 294 | m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0"); |
194 | return true; | 295 | return; |
195 | } | 296 | } |
196 | else | 297 | |
197 | { | 298 | // Determine the interval over which we are adding tokens, never add |
198 | int now = Environment.TickCount & Int32.MaxValue; | 299 | // more than a single quantum of tokens |
199 | int deltaMS = now - lastDrip; | 300 | Int32 now = Environment.TickCount & Int32.MaxValue; |
301 | Int32 deltaMS = Math.Min(now - m_lastDrip, m_ticksPerQuantum); | ||
200 | 302 | ||
201 | if (deltaMS <= 0) | 303 | m_lastDrip = now; |
202 | { | ||
203 | if (deltaMS < 0) | ||
204 | lastDrip = now; | ||
205 | return false; | ||
206 | } | ||
207 | 304 | ||
208 | int dripAmount = deltaMS * tokensPerMS; | 305 | // This can be 0 in the very unusual case that the timer wrapped |
306 | // It can be 0 if we try add tokens at a sub-tick rate | ||
307 | if (deltaMS <= 0) | ||
308 | return; | ||
209 | 309 | ||
210 | content = Math.Min(content + dripAmount, maxBurst); | 310 | Deposit(deltaMS * DripRate / m_ticksPerQuantum); |
211 | lastDrip = now; | ||
212 | |||
213 | if (dripAmount < 0 || content < 0) | ||
214 | // sim has been idle for too long, integer has overflown | ||
215 | // previous calculation is meaningless, let's put it at correct max | ||
216 | content = maxBurst; | ||
217 | |||
218 | return true; | ||
219 | } | ||
220 | } | 311 | } |
221 | } | 312 | } |
222 | } | 313 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs index 878242a..fc1ddef 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Assets/GetMeshModule.cs | |||
@@ -54,6 +54,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
54 | 54 | ||
55 | private Scene m_scene; | 55 | private Scene m_scene; |
56 | private IAssetService m_assetService; | 56 | private IAssetService m_assetService; |
57 | private bool m_enabled = true; | ||
57 | 58 | ||
58 | #region IRegionModuleBase Members | 59 | #region IRegionModuleBase Members |
59 | 60 | ||
@@ -65,7 +66,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
65 | 66 | ||
66 | public void Initialise(IConfigSource source) | 67 | public void Initialise(IConfigSource source) |
67 | { | 68 | { |
68 | 69 | IConfig meshConfig = source.Configs["Mesh"]; | |
70 | if (meshConfig == null) | ||
71 | return; | ||
72 | |||
73 | m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); | ||
69 | } | 74 | } |
70 | 75 | ||
71 | public void AddRegion(Scene pScene) | 76 | public void AddRegion(Scene pScene) |
@@ -101,16 +106,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
101 | 106 | ||
102 | public void RegisterCaps(UUID agentID, Caps caps) | 107 | public void RegisterCaps(UUID agentID, Caps caps) |
103 | { | 108 | { |
109 | if(!m_enabled) | ||
110 | return; | ||
111 | |||
104 | UUID capID = UUID.Random(); | 112 | UUID capID = UUID.Random(); |
105 | 113 | ||
106 | // m_log.Info("[GETMESH]: /CAPS/" + capID); | 114 | // m_log.Info("[GETMESH]: /CAPS/" + capID); |
115 | |||
107 | caps.RegisterHandler("GetMesh", | 116 | caps.RegisterHandler("GetMesh", |
108 | new RestHTTPHandler("GET", "/CAPS/" + capID, | 117 | new RestHTTPHandler("GET", "/CAPS/" + capID, |
109 | delegate(Hashtable m_dhttpMethod) | 118 | delegate(Hashtable m_dhttpMethod) |
110 | { | 119 | { |
111 | return ProcessGetMesh(m_dhttpMethod, agentID, caps); | 120 | return ProcessGetMesh(m_dhttpMethod, agentID, caps); |
112 | })); | 121 | })); |
113 | |||
114 | } | 122 | } |
115 | 123 | ||
116 | #endregion | 124 | #endregion |
diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs index 4a42c93..3d4c7b7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Assets/NewFileAgentInventoryVariablePriceModule.cs | |||
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
56 | private Scene m_scene; | 56 | private Scene m_scene; |
57 | // private IAssetService m_assetService; | 57 | // private IAssetService m_assetService; |
58 | private bool m_dumpAssetsToFile = false; | 58 | private bool m_dumpAssetsToFile = false; |
59 | private bool m_enabled = true; | ||
59 | 60 | ||
60 | #region IRegionModuleBase Members | 61 | #region IRegionModuleBase Members |
61 | 62 | ||
@@ -67,7 +68,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
67 | 68 | ||
68 | public void Initialise(IConfigSource source) | 69 | public void Initialise(IConfigSource source) |
69 | { | 70 | { |
70 | 71 | IConfig meshConfig = source.Configs["Mesh"]; | |
72 | if (meshConfig == null) | ||
73 | return; | ||
74 | |||
75 | m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); | ||
71 | } | 76 | } |
72 | 77 | ||
73 | public void AddRegion(Scene pScene) | 78 | public void AddRegion(Scene pScene) |
@@ -103,6 +108,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Assets | |||
103 | 108 | ||
104 | public void RegisterCaps(UUID agentID, Caps caps) | 109 | public void RegisterCaps(UUID agentID, Caps caps) |
105 | { | 110 | { |
111 | if(!m_enabled) | ||
112 | return; | ||
113 | |||
106 | UUID capID = UUID.Random(); | 114 | UUID capID = UUID.Random(); |
107 | 115 | ||
108 | // m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); | 116 | // m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 4d74b2a..5baf078 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -34,13 +34,13 @@ using Nini.Config; | |||
34 | using Nwc.XmlRpc; | 34 | using Nwc.XmlRpc; |
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Framework.Communications; | 38 | using OpenSim.Framework.Communications; |
38 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
41 | using OpenSim.Services.Connectors.Friends; | 42 | using OpenSim.Services.Connectors.Friends; |
42 | using OpenSim.Server.Base; | 43 | using OpenSim.Server.Base; |
43 | using OpenSim.Framework.Servers.HttpServer; | ||
44 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; | 44 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; |
45 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; | 45 | using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; |
46 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 46 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index fdfcd10..919ea33 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -33,7 +33,6 @@ using OpenMetaverse; | |||
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Communications; | 34 | using OpenSim.Framework.Communications; |
35 | using OpenSim.Framework.Servers; | 35 | using OpenSim.Framework.Servers; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Framework.Client; | 36 | using OpenSim.Framework.Client; |
38 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 01170aa..6b24718 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -78,11 +78,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
78 | private Stream m_loadStream; | 78 | private Stream m_loadStream; |
79 | 79 | ||
80 | /// <summary> | 80 | /// <summary> |
81 | /// FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things | 81 | /// Has the control file been loaded for this archive? |
82 | /// (I thought they weren't). We will need to bump the version number and perform this check on all | ||
83 | /// subsequent IAR versions only | ||
84 | /// </summary> | 82 | /// </summary> |
85 | protected bool m_controlFileLoaded = true; | 83 | public bool ControlFileLoaded { get; private set; } |
84 | |||
85 | /// <summary> | ||
86 | /// Do we want to enforce the check. IAR versions before 0.2 and 1.1 do not guarantee this order, so we can't | ||
87 | /// enforce. | ||
88 | /// </summary> | ||
89 | public bool EnforceControlFileCheck { get; private set; } | ||
90 | |||
86 | protected bool m_assetsLoaded; | 91 | protected bool m_assetsLoaded; |
87 | protected bool m_inventoryNodesLoaded; | 92 | protected bool m_inventoryNodesLoaded; |
88 | 93 | ||
@@ -131,6 +136,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
131 | m_userInfo = userInfo; | 136 | m_userInfo = userInfo; |
132 | m_invPath = invPath; | 137 | m_invPath = invPath; |
133 | m_loadStream = loadStream; | 138 | m_loadStream = loadStream; |
139 | |||
140 | // FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things | ||
141 | // (I thought they weren't). We will need to bump the version number and perform this check on all | ||
142 | // subsequent IAR versions only | ||
143 | ControlFileLoaded = true; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | /// <summary> | 146 | /// <summary> |
@@ -471,16 +481,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
471 | if (m_creatorIdForAssetId.ContainsKey(assetId)) | 481 | if (m_creatorIdForAssetId.ContainsKey(assetId)) |
472 | { | 482 | { |
473 | string xmlData = Utils.BytesToString(data); | 483 | string xmlData = Utils.BytesToString(data); |
474 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 484 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
475 | foreach (SceneObjectPart sop in sog.Parts) | 485 | |
486 | CoalescedSceneObjects coa = null; | ||
487 | if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa)) | ||
488 | { | ||
489 | // m_log.DebugFormat( | ||
490 | // "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count); | ||
491 | |||
492 | sceneObjects.AddRange(coa.Objects); | ||
493 | } | ||
494 | else | ||
476 | { | 495 | { |
477 | if (sop.CreatorData == null || sop.CreatorData == "") | 496 | sceneObjects.Add(SceneObjectSerializer.FromOriginalXmlFormat(xmlData)); |
478 | { | ||
479 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | ||
480 | } | ||
481 | } | 497 | } |
482 | 498 | ||
483 | data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog)); | 499 | foreach (SceneObjectGroup sog in sceneObjects) |
500 | foreach (SceneObjectPart sop in sog.Parts) | ||
501 | if (sop.CreatorData == null || sop.CreatorData == "") | ||
502 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | ||
503 | |||
504 | if (coa != null) | ||
505 | data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa)); | ||
506 | else | ||
507 | data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0])); | ||
484 | } | 508 | } |
485 | } | 509 | } |
486 | 510 | ||
@@ -508,7 +532,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
508 | /// </summary> | 532 | /// </summary> |
509 | /// <param name="path"></param> | 533 | /// <param name="path"></param> |
510 | /// <param name="data"></param> | 534 | /// <param name="data"></param> |
511 | protected void LoadControlFile(string path, byte[] data) | 535 | public void LoadControlFile(string path, byte[] data) |
512 | { | 536 | { |
513 | XDocument doc = XDocument.Parse(Encoding.ASCII.GetString(data)); | 537 | XDocument doc = XDocument.Parse(Encoding.ASCII.GetString(data)); |
514 | XElement archiveElement = doc.Element("archive"); | 538 | XElement archiveElement = doc.Element("archive"); |
@@ -524,7 +548,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
524 | majorVersion, MAX_MAJOR_VERSION)); | 548 | majorVersion, MAX_MAJOR_VERSION)); |
525 | } | 549 | } |
526 | 550 | ||
527 | m_controlFileLoaded = true; | 551 | ControlFileLoaded = true; |
528 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); | 552 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); |
529 | } | 553 | } |
530 | 554 | ||
@@ -536,7 +560,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
536 | /// <param name="data"></param> | 560 | /// <param name="data"></param> |
537 | protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data) | 561 | protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data) |
538 | { | 562 | { |
539 | if (!m_controlFileLoaded) | 563 | if (!ControlFileLoaded) |
540 | throw new Exception( | 564 | throw new Exception( |
541 | string.Format( | 565 | string.Format( |
542 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", | 566 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", |
@@ -583,7 +607,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
583 | /// <param name="data"></param> | 607 | /// <param name="data"></param> |
584 | protected void LoadAssetFile(string path, byte[] data) | 608 | protected void LoadAssetFile(string path, byte[] data) |
585 | { | 609 | { |
586 | if (!m_controlFileLoaded) | 610 | if (!ControlFileLoaded) |
587 | throw new Exception( | 611 | throw new Exception( |
588 | string.Format( | 612 | string.Format( |
589 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", | 613 | "The IAR you are trying to load does not list {0} before {1}. Aborting load", |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index dc4900f..c039b5a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -394,12 +394,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
394 | if (options.ContainsKey("profile")) | 394 | if (options.ContainsKey("profile")) |
395 | { | 395 | { |
396 | majorVersion = 1; | 396 | majorVersion = 1; |
397 | minorVersion = 0; | 397 | minorVersion = 1; |
398 | } | 398 | } |
399 | else | 399 | else |
400 | { | 400 | { |
401 | majorVersion = 0; | 401 | majorVersion = 0; |
402 | minorVersion = 1; | 402 | minorVersion = 2; |
403 | } | 403 | } |
404 | 404 | ||
405 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); | 405 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index e5127a0..5ba08ee 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -68,17 +68,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
68 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"), | 68 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"), |
69 | FirstName = "Mr", | 69 | FirstName = "Mr", |
70 | LastName = "Tiddles" }; | 70 | LastName = "Tiddles" }; |
71 | |||
71 | protected UserAccount m_uaLL1 | 72 | protected UserAccount m_uaLL1 |
72 | = new UserAccount { | 73 | = new UserAccount { |
73 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"), | 74 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"), |
74 | FirstName = "Lord", | 75 | FirstName = "Lord", |
75 | LastName = "Lucan" }; | 76 | LastName = "Lucan" }; |
77 | |||
76 | protected UserAccount m_uaLL2 | 78 | protected UserAccount m_uaLL2 |
77 | = new UserAccount { | 79 | = new UserAccount { |
78 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000777"), | 80 | PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000777"), |
79 | FirstName = "Lord", | 81 | FirstName = "Lord", |
80 | LastName = "Lucan" }; | 82 | LastName = "Lucan" }; |
83 | |||
81 | protected string m_item1Name = "Ray Gun Item"; | 84 | protected string m_item1Name = "Ray Gun Item"; |
85 | protected string m_coaItemName = "Coalesced Item"; | ||
82 | 86 | ||
83 | [SetUp] | 87 | [SetUp] |
84 | public virtual void SetUp() | 88 | public virtual void SetUp() |
@@ -97,38 +101,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
97 | // log4net.Config.XmlConfigurator.Configure(); | 101 | // log4net.Config.XmlConfigurator.Configure(); |
98 | 102 | ||
99 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 103 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
100 | Scene scene = SceneSetupHelpers.SetupScene("Inventory"); | 104 | Scene scene = SceneSetupHelpers.SetupScene(); |
101 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); | 105 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); |
102 | 106 | ||
103 | UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); | 107 | UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); |
104 | 108 | ||
105 | MemoryStream archiveWriteStream = new MemoryStream(); | 109 | MemoryStream archiveWriteStream = new MemoryStream(); |
106 | 110 | ||
107 | // Create asset | 111 | // Create scene object asset |
108 | SceneObjectGroup object1; | 112 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); |
109 | SceneObjectPart part1; | 113 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50); |
110 | { | ||
111 | string partName = "Ray Gun Object"; | ||
112 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); | ||
113 | PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); | ||
114 | Vector3 groupPosition = new Vector3(10, 20, 30); | ||
115 | Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); | ||
116 | Vector3 offsetPosition = new Vector3(5, 10, 15); | ||
117 | |||
118 | part1 | ||
119 | = new SceneObjectPart( | ||
120 | ownerId, shape, groupPosition, rotationOffset, offsetPosition); | ||
121 | part1.Name = partName; | ||
122 | |||
123 | object1 = new SceneObjectGroup(part1); | ||
124 | scene.AddNewSceneObject(object1, false); | ||
125 | } | ||
126 | 114 | ||
127 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | 115 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); |
128 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | 116 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); |
129 | scene.AssetService.Store(asset1); | 117 | scene.AssetService.Store(asset1); |
130 | 118 | ||
131 | // Create item | 119 | // Create scene object item |
132 | InventoryItemBase item1 = new InventoryItemBase(); | 120 | InventoryItemBase item1 = new InventoryItemBase(); |
133 | item1.Name = m_item1Name; | 121 | item1.Name = m_item1Name; |
134 | item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020"); | 122 | item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020"); |
@@ -139,8 +127,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
139 | item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; | 127 | item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; |
140 | scene.AddInventoryItem(item1); | 128 | scene.AddInventoryItem(item1); |
141 | 129 | ||
130 | // Create coalesced objects asset | ||
131 | SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120); | ||
132 | cobj1.AbsolutePosition = new Vector3(15, 30, 45); | ||
133 | |||
134 | SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140); | ||
135 | cobj2.AbsolutePosition = new Vector3(25, 50, 75); | ||
136 | |||
137 | CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2); | ||
138 | |||
139 | AssetBase coaAsset = AssetHelpers.CreateAsset(0x160, coa); | ||
140 | scene.AssetService.Store(coaAsset); | ||
141 | |||
142 | // Create coalesced objects inventory item | ||
143 | InventoryItemBase coaItem = new InventoryItemBase(); | ||
144 | coaItem.Name = m_coaItemName; | ||
145 | coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180"); | ||
146 | coaItem.AssetID = coaAsset.FullID; | ||
147 | coaItem.GroupID = UUID.Random(); | ||
148 | coaItem.CreatorIdAsUuid = m_uaLL1.PrincipalID; | ||
149 | coaItem.Owner = m_uaLL1.PrincipalID; | ||
150 | coaItem.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; | ||
151 | scene.AddInventoryItem(coaItem); | ||
152 | |||
142 | archiverModule.ArchiveInventory( | 153 | archiverModule.ArchiveInventory( |
143 | Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, m_item1Name, "hampshire", archiveWriteStream); | 154 | Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream); |
144 | 155 | ||
145 | m_iarStreamBytes = archiveWriteStream.ToArray(); | 156 | m_iarStreamBytes = archiveWriteStream.ToArray(); |
146 | } | 157 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 7f156f8..52232a0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -62,9 +62,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
62 | SerialiserModule serialiserModule = new SerialiserModule(); | 62 | SerialiserModule serialiserModule = new SerialiserModule(); |
63 | m_archiverModule = new InventoryArchiverModule(); | 63 | m_archiverModule = new InventoryArchiverModule(); |
64 | 64 | ||
65 | m_scene = SceneSetupHelpers.SetupScene("Inventory"); | 65 | m_scene = SceneSetupHelpers.SetupScene(); |
66 | SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | 66 | SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); |
67 | } | 67 | } |
68 | |||
69 | [Test] | ||
70 | public void TestLoadCoalesecedItem() | ||
71 | { | ||
72 | TestHelper.InMethod(); | ||
73 | // log4net.Config.XmlConfigurator.Configure(); | ||
74 | |||
75 | UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "password"); | ||
76 | m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); | ||
77 | |||
78 | InventoryItemBase coaItem | ||
79 | = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName); | ||
80 | |||
81 | Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1"); | ||
82 | |||
83 | string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID); | ||
84 | |||
85 | CoalescedSceneObjects coa; | ||
86 | bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa); | ||
87 | |||
88 | Assert.That(readResult, Is.True); | ||
89 | Assert.That(coa.Count, Is.EqualTo(2)); | ||
90 | |||
91 | List<SceneObjectGroup> coaObjects = coa.Objects; | ||
92 | Assert.That(coaObjects[0].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000120"))); | ||
93 | Assert.That(coaObjects[0].AbsolutePosition, Is.EqualTo(new Vector3(15, 30, 45))); | ||
94 | |||
95 | Assert.That(coaObjects[1].UUID, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000140"))); | ||
96 | Assert.That(coaObjects[1].AbsolutePosition, Is.EqualTo(new Vector3(25, 50, 75))); | ||
97 | } | ||
98 | |||
99 | /// <summary> | ||
100 | /// Test that the IAR has the required files in the right order. | ||
101 | /// </summary> | ||
102 | /// <remarks> | ||
103 | /// At the moment, the only thing that matters is that the control file is the very first one. | ||
104 | /// </remarks> | ||
105 | [Test] | ||
106 | public void TestOrder() | ||
107 | { | ||
108 | TestHelper.InMethod(); | ||
109 | // log4net.Config.XmlConfigurator.Configure(); | ||
110 | |||
111 | MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes); | ||
112 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | ||
113 | string filePath; | ||
114 | TarArchiveReader.TarEntryType tarEntryType; | ||
115 | |||
116 | byte[] data = tar.ReadEntry(out filePath, out tarEntryType); | ||
117 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | ||
118 | |||
119 | InventoryArchiveReadRequest iarr | ||
120 | = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); | ||
121 | iarr.LoadControlFile(filePath, data); | ||
122 | |||
123 | Assert.That(iarr.ControlFileLoaded, Is.True); | ||
124 | } | ||
68 | 125 | ||
69 | /// <summary> | 126 | /// <summary> |
70 | /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive | 127 | /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive |
@@ -84,24 +141,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
84 | UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); | 141 | UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); |
85 | 142 | ||
86 | // Create asset | 143 | // Create asset |
87 | SceneObjectGroup object1; | 144 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); |
88 | SceneObjectPart part1; | 145 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50); |
89 | { | ||
90 | string partName = "My Little Dog Object"; | ||
91 | UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040"); | ||
92 | PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); | ||
93 | Vector3 groupPosition = new Vector3(10, 20, 30); | ||
94 | Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); | ||
95 | Vector3 offsetPosition = new Vector3(5, 10, 15); | ||
96 | |||
97 | part1 | ||
98 | = new SceneObjectPart( | ||
99 | ownerId, shape, groupPosition, rotationOffset, offsetPosition); | ||
100 | part1.Name = partName; | ||
101 | |||
102 | object1 = new SceneObjectGroup(part1); | ||
103 | m_scene.AddNewSceneObject(object1, false); | ||
104 | } | ||
105 | 146 | ||
106 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | 147 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); |
107 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | 148 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 0e8f647..c7dae52 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs | |||
@@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
63 | 63 | ||
64 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 64 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
65 | 65 | ||
66 | Scene scene = SceneSetupHelpers.SetupScene("Inventory"); | 66 | Scene scene = SceneSetupHelpers.SetupScene(); |
67 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); | 67 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); |
68 | 68 | ||
69 | // Create user | 69 | // Create user |
@@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
180 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 180 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
181 | 181 | ||
182 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene | 182 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene |
183 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 183 | Scene scene = SceneSetupHelpers.SetupScene(); |
184 | 184 | ||
185 | SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 185 | SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
186 | 186 | ||
@@ -223,7 +223,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
223 | 223 | ||
224 | SerialiserModule serialiserModule = new SerialiserModule(); | 224 | SerialiserModule serialiserModule = new SerialiserModule(); |
225 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 225 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
226 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 226 | Scene scene = SceneSetupHelpers.SetupScene(); |
227 | SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 227 | SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
228 | 228 | ||
229 | UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "password"); | 229 | UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "password"); |
@@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
248 | 248 | ||
249 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 249 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
250 | 250 | ||
251 | Scene scene = SceneSetupHelpers.SetupScene("Inventory"); | 251 | Scene scene = SceneSetupHelpers.SetupScene(); |
252 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); | 252 | SceneSetupHelpers.SetupSceneModules(scene, archiverModule); |
253 | 253 | ||
254 | // Create user | 254 | // Create user |
@@ -327,7 +327,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
327 | TestHelper.InMethod(); | 327 | TestHelper.InMethod(); |
328 | // log4net.Config.XmlConfigurator.Configure(); | 328 | // log4net.Config.XmlConfigurator.Configure(); |
329 | 329 | ||
330 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 330 | Scene scene = SceneSetupHelpers.SetupScene(); |
331 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); | 331 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); |
332 | 332 | ||
333 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 333 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); |
@@ -394,7 +394,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
394 | TestHelper.InMethod(); | 394 | TestHelper.InMethod(); |
395 | //log4net.Config.XmlConfigurator.Configure(); | 395 | //log4net.Config.XmlConfigurator.Configure(); |
396 | 396 | ||
397 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 397 | Scene scene = SceneSetupHelpers.SetupScene(); |
398 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); | 398 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); |
399 | 399 | ||
400 | string folder1ExistingName = "a"; | 400 | string folder1ExistingName = "a"; |
@@ -445,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
445 | TestHelper.InMethod(); | 445 | TestHelper.InMethod(); |
446 | // log4net.Config.XmlConfigurator.Configure(); | 446 | // log4net.Config.XmlConfigurator.Configure(); |
447 | 447 | ||
448 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 448 | Scene scene = SceneSetupHelpers.SetupScene(); |
449 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); | 449 | UserAccount ua1 = UserProfileTestUtils.CreateUserWithInventory(scene); |
450 | 450 | ||
451 | string folder1ExistingName = "a"; | 451 | string folder1ExistingName = "a"; |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 4565d10..52791cb 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | |||
@@ -75,6 +75,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
75 | if (name == Name) | 75 | if (name == Name) |
76 | { | 76 | { |
77 | m_Enabled = true; | 77 | m_Enabled = true; |
78 | |||
79 | InitialiseCommon(source); | ||
80 | |||
78 | m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); | 81 | m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); |
79 | 82 | ||
80 | IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; | 83 | IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; |
@@ -129,35 +132,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
129 | } | 132 | } |
130 | 133 | ||
131 | /// | 134 | /// |
132 | /// DeleteToInventory | 135 | /// Used in DeleteToInventory |
133 | /// | 136 | /// |
134 | public override UUID DeleteToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) | 137 | protected override void ExportAsset(UUID agentID, UUID assetID) |
135 | { | 138 | { |
136 | UUID ret = UUID.Zero; | ||
137 | |||
138 | // HACK: Only works for lists of length one. | ||
139 | // Intermediate version, just to make things compile | ||
140 | foreach (SceneObjectGroup g in objectGroups) | ||
141 | ret = DeleteToInventory(action, folderID, g, remoteClient); | ||
142 | |||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | // DO NOT OVERRIDE THE BASE METHOD | ||
147 | public new virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, | ||
148 | SceneObjectGroup objectGroup, IClientAPI remoteClient) | ||
149 | { | ||
150 | UUID assetID = base.DeleteToInventory(action, folderID, new List<SceneObjectGroup>() {objectGroup}, remoteClient); | ||
151 | |||
152 | if (!assetID.Equals(UUID.Zero)) | 139 | if (!assetID.Equals(UUID.Zero)) |
153 | { | 140 | UploadInventoryItem(agentID, assetID, "", 0); |
154 | if (remoteClient != null) | ||
155 | UploadInventoryItem(remoteClient.AgentId, assetID, "", 0); | ||
156 | } | ||
157 | else | 141 | else |
158 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); | 142 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); |
159 | |||
160 | return assetID; | ||
161 | } | 143 | } |
162 | 144 | ||
163 | /// | 145 | /// |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9fbfc34..6b3df9d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -64,7 +64,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
64 | return m_UserManagement; | 64 | return m_UserManagement; |
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | public bool CoalesceMultipleObjectsToInventory { get; set; } | ||
68 | 69 | ||
69 | #region INonSharedRegionModule | 70 | #region INonSharedRegionModule |
70 | 71 | ||
@@ -87,10 +88,28 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
87 | if (name == Name) | 88 | if (name == Name) |
88 | { | 89 | { |
89 | m_Enabled = true; | 90 | m_Enabled = true; |
90 | m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name); | 91 | |
92 | InitialiseCommon(source); | ||
93 | |||
94 | m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name); | ||
91 | } | 95 | } |
92 | } | 96 | } |
93 | } | 97 | } |
98 | |||
99 | /// <summary> | ||
100 | /// Common module config for both this and descendant classes. | ||
101 | /// </summary> | ||
102 | /// <param name="source"></param> | ||
103 | protected virtual void InitialiseCommon(IConfigSource source) | ||
104 | { | ||
105 | IConfig inventoryConfig = source.Configs["Inventory"]; | ||
106 | |||
107 | if (inventoryConfig != null) | ||
108 | CoalesceMultipleObjectsToInventory | ||
109 | = inventoryConfig.GetBoolean("CoalesceMultipleObjectsToInventory", true); | ||
110 | else | ||
111 | CoalesceMultipleObjectsToInventory = true; | ||
112 | } | ||
94 | 113 | ||
95 | public virtual void PostInitialise() | 114 | public virtual void PostInitialise() |
96 | { | 115 | { |
@@ -194,366 +213,386 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
194 | 213 | ||
195 | return UUID.Zero; | 214 | return UUID.Zero; |
196 | } | 215 | } |
197 | 216 | ||
198 | /// <summary> | 217 | public virtual UUID CopyToInventory(DeRezAction action, UUID folderID, |
199 | /// Delete a scene object from a scene and place in the given avatar's inventory. | ||
200 | /// Returns the UUID of the newly created asset. | ||
201 | /// </summary> | ||
202 | /// <param name="action"></param> | ||
203 | /// <param name="folderID"></param> | ||
204 | /// <param name="objectGroup"></param> | ||
205 | /// <param name="remoteClient"> </param> | ||
206 | public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, | ||
207 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) | 218 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) |
208 | { | 219 | { |
209 | UUID ret = UUID.Zero; | 220 | Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>(); |
210 | 221 | ||
211 | // The following code groups the SOG's by owner. No objects | 222 | if (CoalesceMultipleObjectsToInventory) |
212 | // belonging to different people can be coalesced, for obvious | ||
213 | // reasons. | ||
214 | Dictionary<UUID, List<SceneObjectGroup>> deletes = | ||
215 | new Dictionary<UUID, List<SceneObjectGroup>>(); | ||
216 | |||
217 | foreach (SceneObjectGroup g in objectGroups) | ||
218 | { | 223 | { |
219 | if (!deletes.ContainsKey(g.OwnerID)) | 224 | // The following code groups the SOG's by owner. No objects |
220 | deletes[g.OwnerID] = new List<SceneObjectGroup>(); | 225 | // belonging to different people can be coalesced, for obvious |
221 | 226 | // reasons. | |
222 | deletes[g.OwnerID].Add(g); | 227 | foreach (SceneObjectGroup g in objectGroups) |
228 | { | ||
229 | if (!bundlesToCopy.ContainsKey(g.OwnerID)) | ||
230 | bundlesToCopy[g.OwnerID] = new List<SceneObjectGroup>(); | ||
231 | |||
232 | bundlesToCopy[g.OwnerID].Add(g); | ||
233 | } | ||
234 | } | ||
235 | else | ||
236 | { | ||
237 | // If we don't want to coalesce then put every object in its own bundle. | ||
238 | foreach (SceneObjectGroup g in objectGroups) | ||
239 | { | ||
240 | List<SceneObjectGroup> bundle = new List<SceneObjectGroup>(); | ||
241 | bundle.Add(g); | ||
242 | bundlesToCopy[g.UUID] = bundle; | ||
243 | } | ||
223 | } | 244 | } |
224 | 245 | ||
225 | // This is pethod scoped and will be returned. It will be the | 246 | // This is method scoped and will be returned. It will be the |
226 | // last created asset id | 247 | // last created asset id |
227 | UUID assetID = UUID.Zero; | 248 | UUID assetID = UUID.Zero; |
228 | 249 | ||
229 | // Each iteration is really a separate asset being created, | 250 | // Each iteration is really a separate asset being created, |
230 | // with distinct destinations as well. | 251 | // with distinct destinations as well. |
231 | foreach (List<SceneObjectGroup> objlist in deletes.Values) | 252 | foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values) |
232 | { | 253 | assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient); |
233 | Dictionary<UUID, string> xmlStrings = | 254 | |
234 | new Dictionary<UUID, string>(); | 255 | return assetID; |
235 | 256 | } | |
236 | foreach (SceneObjectGroup objectGroup in objlist) | 257 | |
237 | { | 258 | /// <summary> |
238 | Vector3 inventoryStoredPosition = new Vector3 | 259 | /// Copy a bundle of objects to inventory. If there is only one object, then this will create an object |
239 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | 260 | /// item. If there are multiple objects then these will be saved as a single coalesced item. |
240 | ? 250 | 261 | /// </summary> |
241 | : objectGroup.AbsolutePosition.X) | 262 | /// <param name="action"></param> |
242 | , | 263 | /// <param name="folderID"></param> |
243 | (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | 264 | /// <param name="objlist"></param> |
244 | ? 250 | 265 | /// <param name="remoteClient"></param> |
245 | : objectGroup.AbsolutePosition.X, | 266 | /// <returns></returns> |
246 | objectGroup.AbsolutePosition.Z); | 267 | protected UUID CopyBundleToInventory( |
247 | 268 | DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient) | |
248 | Vector3 originalPosition = objectGroup.AbsolutePosition; | 269 | { |
249 | 270 | UUID assetID = UUID.Zero; | |
250 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 271 | |
251 | 272 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | |
252 | // Make sure all bits but the ones we want are clear | 273 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
253 | // on take. | ||
254 | // This will be applied to the current perms, so | ||
255 | // it will do what we want. | ||
256 | objectGroup.RootPart.NextOwnerMask &= | ||
257 | ((uint)PermissionMask.Copy | | ||
258 | (uint)PermissionMask.Transfer | | ||
259 | (uint)PermissionMask.Modify); | ||
260 | objectGroup.RootPart.NextOwnerMask |= | ||
261 | (uint)PermissionMask.Move; | ||
262 | |||
263 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | ||
264 | |||
265 | objectGroup.AbsolutePosition = originalPosition; | ||
266 | |||
267 | xmlStrings[objectGroup.UUID] = sceneObjectXml; | ||
268 | } | ||
269 | 274 | ||
270 | string itemXml; | 275 | foreach (SceneObjectGroup objectGroup in objlist) |
276 | { | ||
277 | Vector3 inventoryStoredPosition = new Vector3 | ||
278 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
279 | ? 250 | ||
280 | : objectGroup.AbsolutePosition.X) | ||
281 | , | ||
282 | (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize) | ||
283 | ? 250 | ||
284 | : objectGroup.AbsolutePosition.Y, | ||
285 | objectGroup.AbsolutePosition.Z); | ||
286 | |||
287 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; | ||
288 | |||
289 | objectGroup.AbsolutePosition = inventoryStoredPosition; | ||
290 | |||
291 | // Make sure all bits but the ones we want are clear | ||
292 | // on take. | ||
293 | // This will be applied to the current perms, so | ||
294 | // it will do what we want. | ||
295 | objectGroup.RootPart.NextOwnerMask &= | ||
296 | ((uint)PermissionMask.Copy | | ||
297 | (uint)PermissionMask.Transfer | | ||
298 | (uint)PermissionMask.Modify); | ||
299 | objectGroup.RootPart.NextOwnerMask |= | ||
300 | (uint)PermissionMask.Move; | ||
301 | |||
302 | coa.Add(objectGroup); | ||
303 | } | ||
271 | 304 | ||
272 | if (objlist.Count > 1) | 305 | string itemXml; |
273 | { | ||
274 | float minX, minY, minZ; | ||
275 | float maxX, maxY, maxZ; | ||
276 | 306 | ||
277 | Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist, | 307 | if (objlist.Count > 1) |
278 | out minX, out maxX, out minY, out maxY, | 308 | itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); |
279 | out minZ, out maxZ); | 309 | else |
310 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); | ||
311 | |||
312 | // Restore the position of each group now that it has been stored to inventory. | ||
313 | foreach (SceneObjectGroup objectGroup in objlist) | ||
314 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | ||
280 | 315 | ||
281 | // CreateWrapper | 316 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
282 | XmlDocument itemDoc = new XmlDocument(); | 317 | if (item == null) |
283 | XmlElement root = itemDoc.CreateElement("", "CoalescedObject", ""); | 318 | return UUID.Zero; |
284 | itemDoc.AppendChild(root); | 319 | |
320 | // Can't know creator is the same, so null it in inventory | ||
321 | if (objlist.Count > 1) | ||
322 | { | ||
323 | item.CreatorId = UUID.Zero.ToString(); | ||
324 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
325 | } | ||
326 | else | ||
327 | { | ||
328 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
329 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | ||
330 | item.SalePrice = objlist[0].RootPart.SalePrice; | ||
331 | } | ||
332 | |||
333 | AssetBase asset = CreateAsset( | ||
334 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), | ||
335 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), | ||
336 | (sbyte)AssetType.Object, | ||
337 | Utils.StringToBytes(itemXml), | ||
338 | objlist[0].OwnerID.ToString()); | ||
339 | m_Scene.AssetService.Store(asset); | ||
340 | |||
341 | item.AssetID = asset.FullID; | ||
342 | assetID = asset.FullID; | ||
285 | 343 | ||
286 | // Embed the offsets into the group XML | 344 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
287 | for ( int i = 0 ; i < objlist.Count ; i++ ) | 345 | { |
288 | { | 346 | m_Scene.InventoryService.UpdateItem(item); |
289 | XmlDocument doc = new XmlDocument(); | 347 | } |
290 | SceneObjectGroup g = objlist[i]; | 348 | else |
291 | doc.LoadXml(xmlStrings[g.UUID]); | 349 | { |
292 | XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); | 350 | AddPermissions(item, objlist[0], objlist, remoteClient); |
293 | e.SetAttribute("offsetx", offsets[i].X.ToString()); | ||
294 | e.SetAttribute("offsety", offsets[i].Y.ToString()); | ||
295 | e.SetAttribute("offsetz", offsets[i].Z.ToString()); | ||
296 | |||
297 | XmlNode objectNode = itemDoc.ImportNode(e, true); | ||
298 | root.AppendChild(objectNode); | ||
299 | } | ||
300 | 351 | ||
301 | float sizeX = maxX - minX; | 352 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
302 | float sizeY = maxY - minY; | 353 | item.Description = asset.Description; |
303 | float sizeZ = maxZ - minZ; | 354 | item.Name = asset.Name; |
355 | item.AssetType = asset.Type; | ||
304 | 356 | ||
305 | root.SetAttribute("x", sizeX.ToString()); | 357 | m_Scene.AddInventoryItem(item); |
306 | root.SetAttribute("y", sizeY.ToString()); | ||
307 | root.SetAttribute("z", sizeZ.ToString()); | ||
308 | 358 | ||
309 | itemXml = itemDoc.InnerXml; | 359 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
360 | { | ||
361 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
310 | } | 362 | } |
311 | else | 363 | else |
312 | { | 364 | { |
313 | itemXml = xmlStrings[objlist[0].UUID]; | 365 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); |
366 | if (notifyUser != null) | ||
367 | { | ||
368 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
369 | } | ||
314 | } | 370 | } |
371 | } | ||
315 | 372 | ||
316 | // Get the user info of the item destination | 373 | // This is a hook to do some per-asset post-processing for subclasses that need that |
317 | // | 374 | ExportAsset(remoteClient.AgentId, assetID); |
318 | UUID userID = UUID.Zero; | 375 | |
376 | return assetID; | ||
377 | } | ||
319 | 378 | ||
320 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | 379 | protected virtual void ExportAsset(UUID agentID, UUID assetID) |
321 | action == DeRezAction.SaveToExistingUserInventoryItem) | 380 | { |
322 | { | 381 | // nothing to do here |
323 | // Take or take copy require a taker | 382 | } |
324 | // Saving changes requires a local user | ||
325 | // | ||
326 | if (remoteClient == null) | ||
327 | return UUID.Zero; | ||
328 | 383 | ||
329 | userID = remoteClient.AgentId; | 384 | /// <summary> |
330 | } | 385 | /// Add relevant permissions for an object to the item. |
331 | else | 386 | /// </summary> |
332 | { | 387 | /// <param name="item"></param> |
333 | // All returns / deletes go to the object owner | 388 | /// <param name="so"></param> |
334 | // | 389 | /// <param name="objsForEffectivePermissions"></param> |
390 | /// <param name="remoteClient"></param> | ||
391 | /// <returns></returns> | ||
392 | protected InventoryItemBase AddPermissions( | ||
393 | InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, | ||
394 | IClientAPI remoteClient) | ||
395 | { | ||
396 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | ||
397 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) | ||
398 | effectivePerms &= grp.GetEffectivePermissions(); | ||
399 | effectivePerms |= (uint)PermissionMask.Move; | ||
335 | 400 | ||
336 | userID = objlist[0].RootPart.OwnerID; | 401 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
337 | } | 402 | { |
403 | uint perms = effectivePerms; | ||
404 | uint nextPerms = (perms & 7) << 13; | ||
405 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
406 | perms &= ~(uint)PermissionMask.Copy; | ||
407 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
408 | perms &= ~(uint)PermissionMask.Transfer; | ||
409 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
410 | perms &= ~(uint)PermissionMask.Modify; | ||
411 | |||
412 | item.BasePermissions = perms & so.RootPart.NextOwnerMask; | ||
413 | item.CurrentPermissions = item.BasePermissions; | ||
414 | item.NextPermissions = perms & so.RootPart.NextOwnerMask; | ||
415 | item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; | ||
416 | item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; | ||
417 | |||
418 | // Magic number badness. Maybe this deserves an enum. | ||
419 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
420 | // and apply next owner perms on rez | ||
421 | item.CurrentPermissions |= 16; // Slam! | ||
422 | } | ||
423 | else | ||
424 | { | ||
425 | item.BasePermissions = effectivePerms; | ||
426 | item.CurrentPermissions = effectivePerms; | ||
427 | item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms; | ||
428 | item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms; | ||
429 | item.GroupPermissions = so.RootPart.GroupMask & effectivePerms; | ||
430 | |||
431 | item.CurrentPermissions &= | ||
432 | ((uint)PermissionMask.Copy | | ||
433 | (uint)PermissionMask.Transfer | | ||
434 | (uint)PermissionMask.Modify | | ||
435 | (uint)PermissionMask.Move | | ||
436 | 7); // Preserve folded permissions | ||
437 | } | ||
438 | |||
439 | return item; | ||
440 | } | ||
441 | |||
442 | /// <summary> | ||
443 | /// Create an item using details for the given scene object. | ||
444 | /// </summary> | ||
445 | /// <param name="action"></param> | ||
446 | /// <param name="remoteClient"></param> | ||
447 | /// <param name="so"></param> | ||
448 | /// <param name="folderID"></param> | ||
449 | /// <returns></returns> | ||
450 | protected InventoryItemBase CreateItemForObject( | ||
451 | DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) | ||
452 | { | ||
453 | // Get the user info of the item destination | ||
454 | // | ||
455 | UUID userID = UUID.Zero; | ||
338 | 456 | ||
339 | if (userID == UUID.Zero) // Can't proceed | 457 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || |
340 | { | 458 | action == DeRezAction.SaveToExistingUserInventoryItem) |
341 | return UUID.Zero; | 459 | { |
342 | } | 460 | // Take or take copy require a taker |
461 | // Saving changes requires a local user | ||
462 | // | ||
463 | if (remoteClient == null) | ||
464 | return null; | ||
343 | 465 | ||
344 | // If we're returning someone's item, it goes back to the | 466 | userID = remoteClient.AgentId; |
345 | // owner's Lost And Found folder. | 467 | } |
346 | // Delete is treated like return in this case | 468 | else |
347 | // Deleting your own items makes them go to trash | 469 | { |
470 | // All returns / deletes go to the object owner | ||
348 | // | 471 | // |
472 | userID = so.RootPart.OwnerID; | ||
473 | } | ||
349 | 474 | ||
350 | InventoryFolderBase folder = null; | 475 | if (userID == UUID.Zero) // Can't proceed |
351 | InventoryItemBase item = null; | 476 | { |
477 | return null; | ||
478 | } | ||
352 | 479 | ||
353 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 480 | // If we're returning someone's item, it goes back to the |
354 | { | 481 | // owner's Lost And Found folder. |
355 | item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); | 482 | // Delete is treated like return in this case |
356 | item = m_Scene.InventoryService.GetItem(item); | 483 | // Deleting your own items makes them go to trash |
484 | // | ||
485 | |||
486 | InventoryFolderBase folder = null; | ||
487 | InventoryItemBase item = null; | ||
357 | 488 | ||
358 | //item = userInfo.RootFolder.FindItem( | 489 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
359 | // objectGroup.RootPart.FromUserInventoryItemID); | 490 | { |
491 | item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID); | ||
492 | item = m_Scene.InventoryService.GetItem(item); | ||
360 | 493 | ||
361 | if (null == item) | 494 | //item = userInfo.RootFolder.FindItem( |
362 | { | 495 | // objectGroup.RootPart.FromUserInventoryItemID); |
363 | m_log.DebugFormat( | 496 | |
364 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | 497 | if (null == item) |
365 | objlist[0].Name, objlist[0].UUID); | 498 | { |
366 | return UUID.Zero; | 499 | m_log.DebugFormat( |
367 | } | 500 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", |
501 | so.Name, so.UUID); | ||
502 | |||
503 | return null; | ||
368 | } | 504 | } |
369 | else | 505 | } |
506 | else | ||
507 | { | ||
508 | // Folder magic | ||
509 | // | ||
510 | if (action == DeRezAction.Delete) | ||
370 | { | 511 | { |
371 | // Folder magic | 512 | // Deleting someone else's item |
372 | // | 513 | // |
373 | if (action == DeRezAction.Delete) | 514 | if (remoteClient == null || |
515 | so.OwnerID != remoteClient.AgentId) | ||
374 | { | 516 | { |
375 | // Deleting someone else's item | 517 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
376 | // | ||
377 | if (remoteClient == null || | ||
378 | objlist[0].OwnerID != remoteClient.AgentId) | ||
379 | { | ||
380 | |||
381 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | ||
382 | } | ||
383 | else | ||
384 | { | ||
385 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
386 | } | ||
387 | } | 518 | } |
388 | else if (action == DeRezAction.Return) | 519 | else |
389 | { | 520 | { |
521 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
522 | } | ||
523 | } | ||
524 | else if (action == DeRezAction.Return) | ||
525 | { | ||
526 | // Dump to lost + found unconditionally | ||
527 | // | ||
528 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | ||
529 | } | ||
390 | 530 | ||
391 | // Dump to lost + found unconditionally | 531 | if (folderID == UUID.Zero && folder == null) |
532 | { | ||
533 | if (action == DeRezAction.Delete) | ||
534 | { | ||
535 | // Deletes go to trash by default | ||
392 | // | 536 | // |
393 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 537 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); |
394 | } | 538 | } |
395 | 539 | else | |
396 | if (folderID == UUID.Zero && folder == null) | ||
397 | { | 540 | { |
398 | if (action == DeRezAction.Delete) | 541 | if (remoteClient == null || so.OwnerID != remoteClient.AgentId) |
399 | { | 542 | { |
400 | // Deletes go to trash by default | 543 | // Taking copy of another person's item. Take to |
401 | // | 544 | // Objects folder. |
402 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 545 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); |
403 | } | 546 | } |
404 | else | 547 | else |
405 | { | 548 | { |
406 | if (remoteClient == null || | 549 | // Catch all. Use lost & found |
407 | objlist[0].OwnerID != remoteClient.AgentId) | 550 | // |
408 | { | ||
409 | // Taking copy of another person's item. Take to | ||
410 | // Objects folder. | ||
411 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
412 | } | ||
413 | else | ||
414 | { | ||
415 | // Catch all. Use lost & found | ||
416 | // | ||
417 | |||
418 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | |||
423 | // Override and put into where it came from, if it came | ||
424 | // from anywhere in inventory | ||
425 | // | ||
426 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) | ||
427 | { | ||
428 | if (objlist[0].RootPart.FromFolderID != UUID.Zero) | ||
429 | { | ||
430 | InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); | ||
431 | folder = m_Scene.InventoryService.GetFolder(f); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | if (folder == null) // None of the above | ||
436 | { | ||
437 | folder = new InventoryFolderBase(folderID); | ||
438 | 551 | ||
439 | if (folder == null) // Nowhere to put it | 552 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
440 | { | ||
441 | return UUID.Zero; | ||
442 | } | 553 | } |
443 | } | 554 | } |
444 | |||
445 | item = new InventoryItemBase(); | ||
446 | // Can't know creator is the same, so null it in inventory | ||
447 | if (objlist.Count > 1) | ||
448 | item.CreatorId = UUID.Zero.ToString(); | ||
449 | else | ||
450 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
451 | item.ID = UUID.Random(); | ||
452 | item.InvType = (int)InventoryType.Object; | ||
453 | item.Folder = folder.ID; | ||
454 | item.Owner = userID; | ||
455 | if (objlist.Count > 1) | ||
456 | { | ||
457 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | ||
462 | item.SalePrice = objlist[0].RootPart.SalePrice; | ||
463 | } | ||
464 | } | 555 | } |
465 | 556 | ||
466 | AssetBase asset = CreateAsset( | 557 | // Override and put into where it came from, if it came |
467 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), | 558 | // from anywhere in inventory |
468 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), | 559 | // |
469 | (sbyte)AssetType.Object, | 560 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) |
470 | Utils.StringToBytes(itemXml), | ||
471 | objlist[0].OwnerID.ToString()); | ||
472 | m_Scene.AssetService.Store(asset); | ||
473 | assetID = asset.FullID; | ||
474 | |||
475 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | ||
476 | { | ||
477 | item.AssetID = asset.FullID; | ||
478 | m_Scene.InventoryService.UpdateItem(item); | ||
479 | } | ||
480 | else | ||
481 | { | 561 | { |
482 | item.AssetID = asset.FullID; | 562 | if (so.RootPart.FromFolderID != UUID.Zero) |
483 | |||
484 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | ||
485 | foreach (SceneObjectGroup grp in objlist) | ||
486 | effectivePerms &= grp.GetEffectivePermissions(); | ||
487 | effectivePerms |= (uint)PermissionMask.Move; | ||
488 | |||
489 | if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | ||
490 | { | 563 | { |
491 | uint perms = effectivePerms; | 564 | InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); |
492 | uint nextPerms = (perms & 7) << 13; | 565 | folder = m_Scene.InventoryService.GetFolder(f); |
493 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
494 | perms &= ~(uint)PermissionMask.Copy; | ||
495 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
496 | perms &= ~(uint)PermissionMask.Transfer; | ||
497 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
498 | perms &= ~(uint)PermissionMask.Modify; | ||
499 | |||
500 | item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
501 | item.CurrentPermissions = item.BasePermissions; | ||
502 | item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
503 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask; | ||
504 | item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask; | ||
505 | |||
506 | // Magic number badness. Maybe this deserves an enum. | ||
507 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
508 | // and apply next owner perms on rez | ||
509 | item.CurrentPermissions |= 16; // Slam! | ||
510 | } | 566 | } |
511 | else | 567 | } |
512 | { | ||
513 | item.BasePermissions = effectivePerms; | ||
514 | item.CurrentPermissions = effectivePerms; | ||
515 | item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; | ||
516 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; | ||
517 | item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; | ||
518 | |||
519 | item.CurrentPermissions &= | ||
520 | ((uint)PermissionMask.Copy | | ||
521 | (uint)PermissionMask.Transfer | | ||
522 | (uint)PermissionMask.Modify | | ||
523 | (uint)PermissionMask.Move | | ||
524 | 7); // Preserve folded permissions | ||
525 | } | ||
526 | |||
527 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
528 | item.Description = asset.Description; | ||
529 | item.Name = asset.Name; | ||
530 | item.AssetType = asset.Type; | ||
531 | 568 | ||
532 | m_Scene.AddInventoryItem(item); | 569 | if (folder == null) // None of the above |
570 | { | ||
571 | folder = new InventoryFolderBase(folderID); | ||
533 | 572 | ||
534 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 573 | if (folder == null) // Nowhere to put it |
535 | { | ||
536 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
537 | } | ||
538 | else | ||
539 | { | 574 | { |
540 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | 575 | return null; |
541 | if (notifyUser != null) | ||
542 | { | ||
543 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
544 | } | ||
545 | } | 576 | } |
546 | } | 577 | } |
547 | } | ||
548 | return assetID; | ||
549 | } | ||
550 | 578 | ||
579 | item = new InventoryItemBase(); | ||
580 | item.ID = UUID.Random(); | ||
581 | item.InvType = (int)InventoryType.Object; | ||
582 | item.Folder = folder.ID; | ||
583 | item.Owner = userID; | ||
584 | } | ||
585 | |||
586 | return item; | ||
587 | } | ||
551 | 588 | ||
552 | /// <summary> | 589 | /// <summary> |
553 | /// Rez an object into the scene from the user's inventory | 590 | /// Rez an object into the scene from the user's inventory |
554 | /// </summary> | 591 | /// </summary> |
592 | /// <remarks> | ||
555 | /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing | 593 | /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing |
556 | /// things to the scene. The caller should be doing that, I think. | 594 | /// things to the scene. The caller should be doing that, I think. |
595 | /// </remarks> | ||
557 | /// <param name="remoteClient"></param> | 596 | /// <param name="remoteClient"></param> |
558 | /// <param name="itemID"></param> | 597 | /// <param name="itemID"></param> |
559 | /// <param name="RayEnd"></param> | 598 | /// <param name="RayEnd"></param> |
@@ -570,21 +609,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
570 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 609 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
571 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 610 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
572 | { | 611 | { |
573 | // Work out position details | 612 | // m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); |
574 | byte bRayEndIsIntersection = (byte)0; | 613 | |
575 | 614 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | |
576 | if (RayEndIsIntersection) | ||
577 | { | ||
578 | bRayEndIsIntersection = (byte)1; | ||
579 | } | ||
580 | else | ||
581 | { | ||
582 | bRayEndIsIntersection = (byte)0; | ||
583 | } | ||
584 | |||
585 | Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); | 615 | Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); |
586 | |||
587 | |||
588 | Vector3 pos = m_Scene.GetNewRezLocation( | 616 | Vector3 pos = m_Scene.GetNewRezLocation( |
589 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 617 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
590 | BypassRayCast, bRayEndIsIntersection, true, scale, false); | 618 | BypassRayCast, bRayEndIsIntersection, true, scale, false); |
@@ -668,9 +696,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
668 | itemId, n.OuterXml); | 696 | itemId, n.OuterXml); |
669 | objlist.Add(g); | 697 | objlist.Add(g); |
670 | XmlElement el = (XmlElement)n; | 698 | XmlElement el = (XmlElement)n; |
671 | float x = Convert.ToSingle(el.GetAttribute("offsetx")); | 699 | |
672 | float y = Convert.ToSingle(el.GetAttribute("offsety")); | 700 | string rawX = el.GetAttribute("offsetx"); |
673 | float z = Convert.ToSingle(el.GetAttribute("offsetz")); | 701 | string rawY = el.GetAttribute("offsety"); |
702 | string rawZ = el.GetAttribute("offsetz"); | ||
703 | // | ||
704 | // m_log.DebugFormat( | ||
705 | // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", | ||
706 | // g.Name, rawX, rawY, rawZ); | ||
707 | |||
708 | float x = Convert.ToSingle(rawX); | ||
709 | float y = Convert.ToSingle(rawY); | ||
710 | float z = Convert.ToSingle(rawZ); | ||
674 | veclist.Add(new Vector3(x, y, z)); | 711 | veclist.Add(new Vector3(x, y, z)); |
675 | } | 712 | } |
676 | } | 713 | } |
@@ -762,10 +799,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
762 | // affect the name stored in the serialization, transfer | 799 | // affect the name stored in the serialization, transfer |
763 | // the correct name from the inventory to the | 800 | // the correct name from the inventory to the |
764 | // object itself before we rez. | 801 | // object itself before we rez. |
765 | rootPart.Name = item.Name; | 802 | // |
766 | rootPart.Description = item.Description; | 803 | // Only do these for the first object if we are rezzing a coalescence. |
767 | rootPart.ObjectSaleType = item.SaleType; | 804 | if (i == 0) |
768 | rootPart.SalePrice = item.SalePrice; | 805 | { |
806 | rootPart.Name = item.Name; | ||
807 | rootPart.Description = item.Description; | ||
808 | rootPart.ObjectSaleType = item.SaleType; | ||
809 | rootPart.SalePrice = item.SalePrice; | ||
810 | } | ||
769 | 811 | ||
770 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); | 812 | group.SetGroup(remoteClient.ActiveGroupId, remoteClient); |
771 | if ((rootPart.OwnerID != item.Owner) || | 813 | if ((rootPart.OwnerID != item.Owner) || |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs new file mode 100644 index 0000000..8d53cf1 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | |||
@@ -0,0 +1,174 @@ | |||
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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using Nini.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Data; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Serialization; | ||
39 | using OpenSim.Framework.Serialization.External; | ||
40 | using OpenSim.Framework.Communications; | ||
41 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | ||
42 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | ||
43 | using OpenSim.Region.Framework.Scenes; | ||
44 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
45 | using OpenSim.Services.Interfaces; | ||
46 | using OpenSim.Tests.Common; | ||
47 | using OpenSim.Tests.Common.Mock; | ||
48 | using OpenSim.Tests.Common.Setup; | ||
49 | |||
50 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | ||
51 | { | ||
52 | [TestFixture] | ||
53 | public class InventoryAccessModuleTests | ||
54 | { | ||
55 | protected TestScene m_scene; | ||
56 | protected BasicInventoryAccessModule m_iam; | ||
57 | protected UUID m_userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); | ||
58 | protected TestClient m_tc; | ||
59 | |||
60 | [SetUp] | ||
61 | public void SetUp() | ||
62 | { | ||
63 | m_iam = new BasicInventoryAccessModule(); | ||
64 | |||
65 | IConfigSource config = new IniConfigSource(); | ||
66 | config.AddConfig("Modules"); | ||
67 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | ||
68 | |||
69 | m_scene = SceneSetupHelpers.SetupScene(); | ||
70 | SceneSetupHelpers.SetupSceneModules(m_scene, config, m_iam); | ||
71 | |||
72 | // Create user | ||
73 | string userFirstName = "Jock"; | ||
74 | string userLastName = "Stirrup"; | ||
75 | string userPassword = "troll"; | ||
76 | UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword); | ||
77 | |||
78 | AgentCircuitData acd = new AgentCircuitData(); | ||
79 | acd.AgentID = m_userId; | ||
80 | m_tc = new TestClient(acd, m_scene); | ||
81 | } | ||
82 | |||
83 | [Test] | ||
84 | public void TestRezCoalescedObject() | ||
85 | { | ||
86 | TestHelper.InMethod(); | ||
87 | // log4net.Config.XmlConfigurator.Configure(); | ||
88 | |||
89 | // Create asset | ||
90 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); | ||
91 | object1.AbsolutePosition = new Vector3(15, 30, 45); | ||
92 | |||
93 | SceneObjectGroup object2 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); | ||
94 | object2.AbsolutePosition = new Vector3(25, 50, 75); | ||
95 | |||
96 | CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2); | ||
97 | |||
98 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | ||
99 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, coa); | ||
100 | m_scene.AssetService.Store(asset1); | ||
101 | |||
102 | // Create item | ||
103 | UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); | ||
104 | string item1Name = "My Little Dog"; | ||
105 | InventoryItemBase item1 = new InventoryItemBase(); | ||
106 | item1.Name = item1Name; | ||
107 | item1.AssetID = asset1.FullID; | ||
108 | item1.ID = item1Id; | ||
109 | InventoryFolderBase objsFolder | ||
110 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; | ||
111 | item1.Folder = objsFolder.ID; | ||
112 | m_scene.AddInventoryItem(item1); | ||
113 | |||
114 | SceneObjectGroup so | ||
115 | = m_iam.RezObject( | ||
116 | m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false); | ||
117 | |||
118 | Assert.That(so, Is.Not.Null); | ||
119 | |||
120 | Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(2)); | ||
121 | |||
122 | SceneObjectPart retrievedObj1Part = m_scene.GetSceneObjectPart(object1.Name); | ||
123 | Assert.That(retrievedObj1Part, Is.Null); | ||
124 | |||
125 | retrievedObj1Part = m_scene.GetSceneObjectPart(item1.Name); | ||
126 | Assert.That(retrievedObj1Part, Is.Not.Null); | ||
127 | Assert.That(retrievedObj1Part.Name, Is.EqualTo(item1.Name)); | ||
128 | |||
129 | // Bottom of coalescence is placed on ground, hence we end up with 100.5 rather than 85 since the bottom | ||
130 | // object is unit square. | ||
131 | Assert.That(retrievedObj1Part.AbsolutePosition, Is.EqualTo(new Vector3(95, 90, 100.5f))); | ||
132 | |||
133 | SceneObjectPart retrievedObj2Part = m_scene.GetSceneObjectPart(object2.Name); | ||
134 | Assert.That(retrievedObj2Part, Is.Not.Null); | ||
135 | Assert.That(retrievedObj2Part.Name, Is.EqualTo(object2.Name)); | ||
136 | Assert.That(retrievedObj2Part.AbsolutePosition, Is.EqualTo(new Vector3(105, 110, 130.5f))); | ||
137 | } | ||
138 | |||
139 | [Test] | ||
140 | public void TestRezObject() | ||
141 | { | ||
142 | TestHelper.InMethod(); | ||
143 | // log4net.Config.XmlConfigurator.Configure(); | ||
144 | |||
145 | // Create asset | ||
146 | SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); | ||
147 | |||
148 | UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); | ||
149 | AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); | ||
150 | m_scene.AssetService.Store(asset1); | ||
151 | |||
152 | // Create item | ||
153 | UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); | ||
154 | string item1Name = "My Little Dog"; | ||
155 | InventoryItemBase item1 = new InventoryItemBase(); | ||
156 | item1.Name = item1Name; | ||
157 | item1.AssetID = asset1.FullID; | ||
158 | item1.ID = item1Id; | ||
159 | InventoryFolderBase objsFolder | ||
160 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; | ||
161 | item1.Folder = objsFolder.ID; | ||
162 | m_scene.AddInventoryItem(item1); | ||
163 | |||
164 | SceneObjectGroup so | ||
165 | = m_iam.RezObject( | ||
166 | m_tc, item1Id, Vector3.Zero, Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false); | ||
167 | |||
168 | Assert.That(so, Is.Not.Null); | ||
169 | |||
170 | SceneObjectPart retrievedPart = m_scene.GetSceneObjectPart(so.UUID); | ||
171 | Assert.That(retrievedPart, Is.Not.Null); | ||
172 | } | ||
173 | } | ||
174 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index d78931a..4c8424d 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -29,8 +29,10 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Net.Security; | ||
32 | using System.Text; | 33 | using System.Text; |
33 | using System.Threading; | 34 | using System.Threading; |
35 | using System.Security.Cryptography.X509Certificates; | ||
34 | using Nini.Config; | 36 | using Nini.Config; |
35 | using OpenMetaverse; | 37 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
@@ -100,8 +102,24 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
100 | 102 | ||
101 | public HttpRequestModule() | 103 | public HttpRequestModule() |
102 | { | 104 | { |
105 | ServicePointManager.ServerCertificateValidationCallback +=ValidateServerCertificate; | ||
103 | } | 106 | } |
104 | 107 | ||
108 | public static bool ValidateServerCertificate( | ||
109 | object sender, | ||
110 | X509Certificate certificate, | ||
111 | X509Chain chain, | ||
112 | SslPolicyErrors sslPolicyErrors) | ||
113 | { | ||
114 | HttpWebRequest Request = (HttpWebRequest)sender; | ||
115 | |||
116 | if (Request.Headers.Get("NoVerifyCert") != null) | ||
117 | { | ||
118 | return true; | ||
119 | } | ||
120 | |||
121 | return chain.Build(new X509Certificate2(certificate)); | ||
122 | } | ||
105 | #region IHttpRequestModule Members | 123 | #region IHttpRequestModule Members |
106 | 124 | ||
107 | public UUID MakeHttpRequest(string url, string parameters, string body) | 125 | public UUID MakeHttpRequest(string url, string parameters, string body) |
@@ -141,8 +159,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
141 | break; | 159 | break; |
142 | 160 | ||
143 | case (int)HttpRequestConstants.HTTP_VERIFY_CERT: | 161 | case (int)HttpRequestConstants.HTTP_VERIFY_CERT: |
144 | 162 | htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); | |
145 | // TODO implement me | ||
146 | break; | 163 | break; |
147 | } | 164 | } |
148 | } | 165 | } |
@@ -189,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
189 | * Not sure how important ordering is is here - the next first | 206 | * Not sure how important ordering is is here - the next first |
190 | * one completed in the list is returned, based soley on its list | 207 | * one completed in the list is returned, based soley on its list |
191 | * position, not the order in which the request was started or | 208 | * position, not the order in which the request was started or |
192 | * finsihed. I thought about setting up a queue for this, but | 209 | * finished. I thought about setting up a queue for this, but |
193 | * it will need some refactoring and this works 'enough' right now | 210 | * it will need some refactoring and this works 'enough' right now |
194 | */ | 211 | */ |
195 | 212 | ||
@@ -237,8 +254,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
237 | 254 | ||
238 | m_scene.RegisterModuleInterface<IHttpRequestModule>(this); | 255 | m_scene.RegisterModuleInterface<IHttpRequestModule>(this); |
239 | 256 | ||
240 | m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); | 257 | m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); |
241 | m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); | 258 | m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); |
242 | 259 | ||
243 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); | 260 | m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); |
244 | } | 261 | } |
@@ -282,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
282 | public string HttpMethod = "GET"; | 299 | public string HttpMethod = "GET"; |
283 | public string HttpMIMEType = "text/plain;charset=utf-8"; | 300 | public string HttpMIMEType = "text/plain;charset=utf-8"; |
284 | public int HttpTimeout; | 301 | public int HttpTimeout; |
285 | // public bool HttpVerifyCert = true; // not implemented | 302 | public bool HttpVerifyCert = true; |
286 | private Thread httpThread; | 303 | private Thread httpThread; |
287 | 304 | ||
288 | // Request info | 305 | // Request info |
@@ -344,6 +361,17 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
344 | Request.Method = HttpMethod; | 361 | Request.Method = HttpMethod; |
345 | Request.ContentType = HttpMIMEType; | 362 | Request.ContentType = HttpMIMEType; |
346 | 363 | ||
364 | if(!HttpVerifyCert) | ||
365 | { | ||
366 | // We could hijack Connection Group Name to identify | ||
367 | // a desired security exception. But at the moment we'll use a dummy header instead. | ||
368 | // Request.ConnectionGroupName = "NoVerify"; | ||
369 | Request.Headers.Add("NoVerifyCert", "true"); | ||
370 | } | ||
371 | // else | ||
372 | // { | ||
373 | // Request.ConnectionGroupName="Verify"; | ||
374 | // } | ||
347 | if (proxyurl != null && proxyurl.Length > 0) | 375 | if (proxyurl != null && proxyurl.Length > 0) |
348 | { | 376 | { |
349 | if (proxyexcepts != null && proxyexcepts.Length > 0) | 377 | if (proxyexcepts != null && proxyexcepts.Length > 0) |
@@ -436,4 +464,4 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
436 | } | 464 | } |
437 | } | 465 | } |
438 | } | 466 | } |
439 | } | 467 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs index e25700d..422f394 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs index 02acddc..2b5beba 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs index 6d975af..f29c074 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index 2f96bcb..d2343c9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs index 209cf0d..53a8ace 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs | |||
@@ -31,9 +31,8 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
38 | using OpenSim.Server.Handlers.Base; | 37 | using OpenSim.Server.Handlers.Base; |
39 | 38 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index fcc69e9..fc64203 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs index 2a9366c..f759470 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs index 35518d5..5c32632 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs index 5ee1c97..86b4926 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs | |||
@@ -31,7 +31,6 @@ using System.Collections.Generic; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Framework.Servers.HttpServer; | ||
35 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 1b3419d..51d1d59 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs | |||
@@ -195,6 +195,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
195 | 195 | ||
196 | public byte[] GetData(string id) | 196 | public byte[] GetData(string id) |
197 | { | 197 | { |
198 | // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id); | ||
199 | |||
198 | AssetBase asset = m_Cache.Get(id); | 200 | AssetBase asset = m_Cache.Get(id); |
199 | 201 | ||
200 | if (asset != null) | 202 | if (asset != null) |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index fd8f546..82bef48 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -57,6 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
57 | /// bumps here should be compatible. | 57 | /// bumps here should be compatible. |
58 | /// </summary> | 58 | /// </summary> |
59 | public static int MAX_MAJOR_VERSION = 1; | 59 | public static int MAX_MAJOR_VERSION = 1; |
60 | |||
61 | /// <summary> | ||
62 | /// Has the control file been loaded for this archive? | ||
63 | /// </summary> | ||
64 | public bool ControlFileLoaded { get; private set; } | ||
60 | 65 | ||
61 | protected Scene m_scene; | 66 | protected Scene m_scene; |
62 | protected Stream m_loadStream; | 67 | protected Stream m_loadStream; |
@@ -527,7 +532,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
527 | /// </summary> | 532 | /// </summary> |
528 | /// <param name="path"></param> | 533 | /// <param name="path"></param> |
529 | /// <param name="data"></param> | 534 | /// <param name="data"></param> |
530 | protected void LoadControlFile(string path, byte[] data) | 535 | public void LoadControlFile(string path, byte[] data) |
531 | { | 536 | { |
532 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); | 537 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); |
533 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); | 538 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); |
@@ -573,6 +578,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
573 | } | 578 | } |
574 | 579 | ||
575 | currentRegionSettings.Save(); | 580 | currentRegionSettings.Save(); |
581 | |||
582 | ControlFileLoaded = true; | ||
576 | } | 583 | } |
577 | } | 584 | } |
578 | } \ No newline at end of file | 585 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index f2d487e..597b780 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
206 | /// <returns></returns> | 206 | /// <returns></returns> |
207 | public static string CreateControlFile(Dictionary<string, object> options) | 207 | public static string CreateControlFile(Dictionary<string, object> options) |
208 | { | 208 | { |
209 | int majorVersion = MAX_MAJOR_VERSION, minorVersion = 5; | 209 | int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6; |
210 | // | 210 | // |
211 | // if (options.ContainsKey("version")) | 211 | // if (options.ContainsKey("version")) |
212 | // { | 212 | // { |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index e2760a2..2307c8e 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -171,7 +171,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
171 | MemoryStream archiveReadStream = new MemoryStream(archive); | 171 | MemoryStream archiveReadStream = new MemoryStream(archive); |
172 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); | 172 | TarArchiveReader tar = new TarArchiveReader(archiveReadStream); |
173 | 173 | ||
174 | bool gotControlFile = false; | ||
175 | bool gotNcAssetFile = false; | 174 | bool gotNcAssetFile = false; |
176 | 175 | ||
177 | string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt"); | 176 | string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt"); |
@@ -182,15 +181,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
182 | expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2)); | 181 | expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2)); |
183 | 182 | ||
184 | string filePath; | 183 | string filePath; |
185 | TarArchiveReader.TarEntryType tarEntryType; | 184 | TarArchiveReader.TarEntryType tarEntryType; |
186 | 185 | ||
186 | byte[] data = tar.ReadEntry(out filePath, out tarEntryType); | ||
187 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | ||
188 | |||
189 | ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); | ||
190 | arr.LoadControlFile(filePath, data); | ||
191 | |||
192 | Assert.That(arr.ControlFileLoaded, Is.True); | ||
193 | |||
187 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) | 194 | while (tar.ReadEntry(out filePath, out tarEntryType) != null) |
188 | { | 195 | { |
189 | if (ArchiveConstants.CONTROL_FILE_PATH == filePath) | 196 | if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) |
190 | { | ||
191 | gotControlFile = true; | ||
192 | } | ||
193 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) | ||
194 | { | 197 | { |
195 | string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); | 198 | string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); |
196 | 199 | ||
@@ -203,7 +206,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
206 | Assert.That(gotControlFile, Is.True, "No control file in archive"); | ||
207 | Assert.That(gotNcAssetFile, Is.True, "No notecard asset file in archive"); | 209 | Assert.That(gotNcAssetFile, Is.True, "No notecard asset file in archive"); |
208 | Assert.That(foundPaths, Is.EquivalentTo(expectedPaths)); | 210 | Assert.That(foundPaths, Is.EquivalentTo(expectedPaths)); |
209 | 211 | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index b6d64ac..3aed6ba 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -125,7 +125,10 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
125 | else | 125 | else |
126 | Scene.RegionInfo.RegionSettings.AllowLandResell = true; | 126 | Scene.RegionInfo.RegionSettings.AllowLandResell = true; |
127 | 127 | ||
128 | Scene.RegionInfo.RegionSettings.AgentLimit = (byte) maxAgents; | 128 | if((byte)maxAgents <= Scene.RegionInfo.AgentCapacity) |
129 | Scene.RegionInfo.RegionSettings.AgentLimit = (byte) maxAgents; | ||
130 | else | ||
131 | Scene.RegionInfo.RegionSettings.AgentLimit = Scene.RegionInfo.AgentCapacity; | ||
129 | 132 | ||
130 | Scene.RegionInfo.RegionSettings.ObjectBonus = objectBonusFactor; | 133 | Scene.RegionInfo.RegionSettings.ObjectBonus = objectBonusFactor; |
131 | 134 | ||
@@ -259,6 +262,10 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
259 | 262 | ||
260 | private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID) | 263 | private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID) |
261 | { | 264 | { |
265 | // m_log.DebugFormat( | ||
266 | // "[ESTATE MANAGEMENT MODULE]: Handling request from {0} to change estate covenant to {1}", | ||
267 | // remoteClient.Name, estateCovenantID); | ||
268 | |||
262 | Scene.RegionInfo.RegionSettings.Covenant = estateCovenantID; | 269 | Scene.RegionInfo.RegionSettings.Covenant = estateCovenantID; |
263 | Scene.RegionInfo.RegionSettings.Save(); | 270 | Scene.RegionInfo.RegionSettings.Save(); |
264 | TriggerRegionInfoChange(); | 271 | TriggerRegionInfoChange(); |
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index dafaa0c..a866fd9 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs | |||
@@ -237,7 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
237 | public void Init() | 237 | public void Init() |
238 | { | 238 | { |
239 | m_serialiserModule = new SerialiserModule(); | 239 | m_serialiserModule = new SerialiserModule(); |
240 | m_scene = SceneSetupHelpers.SetupScene(""); | 240 | m_scene = SceneSetupHelpers.SetupScene(); |
241 | SceneSetupHelpers.SetupSceneModules(m_scene, m_serialiserModule); | 241 | SceneSetupHelpers.SetupSceneModules(m_scene, m_serialiserModule); |
242 | } | 242 | } |
243 | 243 | ||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index d6fa093..21a9999 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs | |||
@@ -124,6 +124,52 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
124 | colours.Save(stream, ImageFormat.Png); | 124 | colours.Save(stream, ImageFormat.Png); |
125 | } | 125 | } |
126 | 126 | ||
127 | public virtual void SaveFile(ITerrainChannel m_channel, string filename, | ||
128 | int offsetX, int offsetY, | ||
129 | int fileWidth, int fileHeight, | ||
130 | int regionSizeX, int regionSizeY) | ||
131 | |||
132 | { | ||
133 | // We need to do this because: | ||
134 | // "Saving the image to the same file it was constructed from is not allowed and throws an exception." | ||
135 | string tempName = offsetX + "_ " + offsetY + "_" + filename; | ||
136 | |||
137 | Bitmap entireBitmap = null; | ||
138 | Bitmap thisBitmap = null; | ||
139 | if (File.Exists(filename)) | ||
140 | { | ||
141 | File.Copy(filename, tempName); | ||
142 | entireBitmap = new Bitmap(tempName); | ||
143 | if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) | ||
144 | { | ||
145 | // old file, let's overwrite it | ||
146 | entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); | ||
147 | } | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); | ||
152 | } | ||
153 | |||
154 | thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); | ||
155 | Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); | ||
156 | for (int x = 0; x < regionSizeX; x++) | ||
157 | for (int y = 0; y < regionSizeY; y++) | ||
158 | entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); | ||
159 | |||
160 | Save(entireBitmap, filename); | ||
161 | thisBitmap.Dispose(); | ||
162 | entireBitmap.Dispose(); | ||
163 | |||
164 | if (File.Exists(tempName)) | ||
165 | File.Delete(tempName); | ||
166 | } | ||
167 | |||
168 | protected virtual void Save(Bitmap bmp, string filename) | ||
169 | { | ||
170 | bmp.Save(filename, ImageFormat.Png); | ||
171 | } | ||
172 | |||
127 | #endregion | 173 | #endregion |
128 | 174 | ||
129 | public override string ToString() | 175 | public override string ToString() |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs index 8667607..1a0d8ec 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs | |||
@@ -76,6 +76,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
76 | colours.Save(stream, ImageFormat.Jpeg); | 76 | colours.Save(stream, ImageFormat.Jpeg); |
77 | } | 77 | } |
78 | 78 | ||
79 | public virtual void SaveFile(ITerrainChannel m_channel, string filename, | ||
80 | int offsetX, int offsetY, | ||
81 | int fileWidth, int fileHeight, | ||
82 | int regionSizeX, int regionSizeY) | ||
83 | { | ||
84 | throw new System.Exception("Not Implemented"); | ||
85 | } | ||
86 | |||
79 | #endregion | 87 | #endregion |
80 | 88 | ||
81 | public override string ToString() | 89 | public override string ToString() |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs index a70ef13..fad7641 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs | |||
@@ -240,6 +240,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
240 | get { return ".raw"; } | 240 | get { return ".raw"; } |
241 | } | 241 | } |
242 | 242 | ||
243 | public virtual void SaveFile(ITerrainChannel m_channel, string filename, | ||
244 | int offsetX, int offsetY, | ||
245 | int fileWidth, int fileHeight, | ||
246 | int regionSizeX, int regionSizeY) | ||
247 | { | ||
248 | throw new System.Exception("Not Implemented"); | ||
249 | } | ||
250 | |||
243 | #endregion | 251 | #endregion |
244 | 252 | ||
245 | public override string ToString() | 253 | public override string ToString() |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs index 3c76665..ba073ca 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/RAW32.cs | |||
@@ -160,6 +160,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
160 | bs.Close(); | 160 | bs.Close(); |
161 | } | 161 | } |
162 | 162 | ||
163 | public virtual void SaveFile(ITerrainChannel m_channel, string filename, | ||
164 | int offsetX, int offsetY, | ||
165 | int fileWidth, int fileHeight, | ||
166 | int regionSizeX, int regionSizeY) | ||
167 | { | ||
168 | throw new System.Exception("Not Implemented"); | ||
169 | } | ||
163 | #endregion | 170 | #endregion |
164 | 171 | ||
165 | public override string ToString() | 172 | public override string ToString() |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 2919897..2f37d9d 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | |||
@@ -308,6 +308,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
308 | get { return ".ter"; } | 308 | get { return ".ter"; } |
309 | } | 309 | } |
310 | 310 | ||
311 | public virtual void SaveFile(ITerrainChannel m_channel, string filename, | ||
312 | int offsetX, int offsetY, | ||
313 | int fileWidth, int fileHeight, | ||
314 | int regionSizeX, int regionSizeY) | ||
315 | { | ||
316 | throw new System.Exception("Not Implemented"); | ||
317 | } | ||
318 | |||
311 | #endregion | 319 | #endregion |
312 | 320 | ||
313 | public override string ToString() | 321 | public override string ToString() |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs index 7403281..7237f90 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs | |||
@@ -38,5 +38,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
38 | ITerrainChannel LoadStream(Stream stream); | 38 | ITerrainChannel LoadStream(Stream stream); |
39 | void SaveFile(string filename, ITerrainChannel map); | 39 | void SaveFile(string filename, ITerrainChannel map); |
40 | void SaveStream(Stream stream, ITerrainChannel map); | 40 | void SaveStream(Stream stream, ITerrainChannel map); |
41 | void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); | ||
41 | } | 42 | } |
42 | } \ No newline at end of file | 43 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 8a79d78..9c7b2fa 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -541,6 +541,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
541 | } | 541 | } |
542 | 542 | ||
543 | /// <summary> | 543 | /// <summary> |
544 | /// Saves the terrain to a larger terrain file. | ||
545 | /// </summary> | ||
546 | /// <param name="filename">The terrain file to save</param> | ||
547 | /// <param name="fileWidth">The width of the file in units</param> | ||
548 | /// <param name="fileHeight">The height of the file in units</param> | ||
549 | /// <param name="fileStartX">Where to begin our slice</param> | ||
550 | /// <param name="fileStartY">Where to begin our slice</param> | ||
551 | public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | ||
552 | { | ||
553 | int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; | ||
554 | int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; | ||
555 | |||
556 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) | ||
557 | { | ||
558 | // this region is included in the tile request | ||
559 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | ||
560 | { | ||
561 | if (filename.EndsWith(loader.Key)) | ||
562 | { | ||
563 | lock (m_scene) | ||
564 | { | ||
565 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, | ||
566 | fileWidth, fileHeight, | ||
567 | (int)Constants.RegionSize, | ||
568 | (int)Constants.RegionSize); | ||
569 | } | ||
570 | return; | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /// <summary> | ||
544 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections | 577 | /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections |
545 | /// </summary> | 578 | /// </summary> |
546 | private void EventManager_OnTerrainTick() | 579 | private void EventManager_OnTerrainTick() |
@@ -860,6 +893,15 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
860 | SaveToFile((string) args[0]); | 893 | SaveToFile((string) args[0]); |
861 | } | 894 | } |
862 | 895 | ||
896 | private void InterfaceSaveTileFile(Object[] args) | ||
897 | { | ||
898 | SaveToFile((string)args[0], | ||
899 | (int)args[1], | ||
900 | (int)args[2], | ||
901 | (int)args[3], | ||
902 | (int)args[4]); | ||
903 | } | ||
904 | |||
863 | private void InterfaceBakeTerrain(Object[] args) | 905 | private void InterfaceBakeTerrain(Object[] args) |
864 | { | 906 | { |
865 | UpdateRevertMap(); | 907 | UpdateRevertMap(); |
@@ -1115,6 +1157,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1115 | loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", | 1157 | loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", |
1116 | "Integer"); | 1158 | "Integer"); |
1117 | 1159 | ||
1160 | Command saveToTileCommand = | ||
1161 | new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file."); | ||
1162 | saveToTileCommand.AddArgument("filename", | ||
1163 | "The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " + | ||
1164 | supportedFileExtensions, "String"); | ||
1165 | saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); | ||
1166 | saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); | ||
1167 | saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", | ||
1168 | "Integer"); | ||
1169 | saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", | ||
1170 | "Integer"); | ||
1118 | // Terrain adjustments | 1171 | // Terrain adjustments |
1119 | Command fillRegionCommand = | 1172 | Command fillRegionCommand = |
1120 | new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); | 1173 | new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); |
@@ -1166,6 +1219,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1166 | m_commander.RegisterCommand("load", loadFromFileCommand); | 1219 | m_commander.RegisterCommand("load", loadFromFileCommand); |
1167 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); | 1220 | m_commander.RegisterCommand("load-tile", loadFromTileCommand); |
1168 | m_commander.RegisterCommand("save", saveToFileCommand); | 1221 | m_commander.RegisterCommand("save", saveToFileCommand); |
1222 | m_commander.RegisterCommand("save-tile", saveToTileCommand); | ||
1169 | m_commander.RegisterCommand("fill", fillRegionCommand); | 1223 | m_commander.RegisterCommand("fill", fillRegionCommand); |
1170 | m_commander.RegisterCommand("elevate", elevateCommand); | 1224 | m_commander.RegisterCommand("elevate", elevateCommand); |
1171 | m_commander.RegisterCommand("lower", lowerCommand); | 1225 | m_commander.RegisterCommand("lower", lowerCommand); |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d939329..89e9e20 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -702,18 +702,12 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
702 | { | 702 | { |
703 | } | 703 | } |
704 | 704 | ||
705 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, | 705 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
706 | uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, | ||
707 | uint NextOwnerMask, int OwnershipCost, byte SaleType,int SalePrice, uint Category, | ||
708 | UUID LastOwnerID, string ObjectName, string Description) | ||
709 | { | 706 | { |
707 | |||
710 | } | 708 | } |
711 | 709 | ||
712 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, | 710 | public void SendObjectPropertiesReply(ISceneEntity entity) |
713 | UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, | ||
714 | UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, | ||
715 | string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, | ||
716 | uint BaseMask, byte saleType, int salePrice) | ||
717 | { | 711 | { |
718 | } | 712 | } |
719 | 713 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 05fc2ad..305975e 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs | |||
@@ -38,7 +38,23 @@ namespace OpenSim.Region.Framework.Interfaces | |||
38 | public interface IInventoryAccessModule | 38 | public interface IInventoryAccessModule |
39 | { | 39 | { |
40 | UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data); | 40 | UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data); |
41 | UUID DeleteToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient); | 41 | |
42 | /// <summary> | ||
43 | /// Copy objects to a user's inventory. | ||
44 | /// </summary> | ||
45 | /// <remarks> | ||
46 | /// Is it left to the caller to delete them from the scene if required. | ||
47 | /// </remarks> | ||
48 | /// <param name="action"></param> | ||
49 | /// <param name="folderID"></param> | ||
50 | /// <param name="objectGroups"></param> | ||
51 | /// <param name="remoteClient"></param> | ||
52 | /// <returns> | ||
53 | /// Returns the UUID of the newly created item asset (not the item itself). | ||
54 | /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. | ||
55 | /// </returns> | ||
56 | UUID CopyToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient); | ||
57 | |||
42 | SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, | 58 | SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, |
43 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 59 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
44 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); | 60 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); |
diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs index 23be9c2..14ecd44 100644 --- a/OpenSim/Region/Framework/ModuleLoader.cs +++ b/OpenSim/Region/Framework/ModuleLoader.cs | |||
@@ -223,7 +223,8 @@ namespace OpenSim.Region.Framework | |||
223 | catch (Exception e) | 223 | catch (Exception e) |
224 | { | 224 | { |
225 | m_log.ErrorFormat( | 225 | m_log.ErrorFormat( |
226 | "[MODULES]: Could not load types for [{0}]. Exception {1}", pluginAssembly.FullName, e); | 226 | "[MODULES]: Could not load types for plugin DLL {0}. Exception {1} {2}", |
227 | pluginAssembly.FullName, e.Message, e.StackTrace); | ||
227 | 228 | ||
228 | // justincc: Right now this is fatal to really get the user's attention | 229 | // justincc: Right now this is fatal to really get the user's attention |
229 | throw e; | 230 | throw e; |
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 8feb022..3423542 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs | |||
@@ -143,7 +143,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
143 | { | 143 | { |
144 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | 144 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); |
145 | if (invAccess != null) | 145 | if (invAccess != null) |
146 | invAccess.DeleteToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); | 146 | invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); |
147 | |||
147 | if (x.permissionToDelete) | 148 | if (x.permissionToDelete) |
148 | { | 149 | { |
149 | foreach (SceneObjectGroup g in x.objectGroups) | 150 | foreach (SceneObjectGroup g in x.objectGroups) |
diff --git a/OpenSim/Region/Framework/Scenes/CoalescedSceneObjects.cs b/OpenSim/Region/Framework/Scenes/CoalescedSceneObjects.cs new file mode 100644 index 0000000..af8ccda --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/CoalescedSceneObjects.cs | |||
@@ -0,0 +1,154 @@ | |||
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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.Framework.Scenes | ||
34 | { | ||
35 | /// <summary> | ||
36 | /// Represents a coalescene of scene objects. A coalescence occurs when objects that are not in the same linkset | ||
37 | /// are grouped together. | ||
38 | /// </summary> | ||
39 | public class CoalescedSceneObjects | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// The creator of this coalesence, though not necessarily the objects within it. | ||
43 | /// </summary> | ||
44 | public UUID CreatorId { get; set; } | ||
45 | |||
46 | /// <summary> | ||
47 | /// The number of objects in this coalesence | ||
48 | /// </summary> | ||
49 | public int Count | ||
50 | { | ||
51 | get | ||
52 | { | ||
53 | lock (m_memberObjects) | ||
54 | return m_memberObjects.Count; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | /// <summary> | ||
59 | /// Does this coalesence have any member objects? | ||
60 | /// </summary> | ||
61 | public bool HasObjects { get { return Count > 0; } } | ||
62 | |||
63 | /// <summary> | ||
64 | /// Get the objects currently in this coalescence | ||
65 | /// </summary> | ||
66 | public List<SceneObjectGroup> Objects | ||
67 | { | ||
68 | get | ||
69 | { | ||
70 | lock (m_memberObjects) | ||
71 | return new List<SceneObjectGroup>(m_memberObjects); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | /// <summary> | ||
76 | /// Get the scene that contains the objects in this coalescence. If there are no objects then null is returned. | ||
77 | /// </summary> | ||
78 | public Scene Scene | ||
79 | { | ||
80 | get | ||
81 | { | ||
82 | if (!HasObjects) | ||
83 | return null; | ||
84 | else | ||
85 | return Objects[0].Scene; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /// <summary> | ||
90 | /// At this point, we need to preserve the order of objects added to the coalescence, since the first | ||
91 | /// one will end up matching the item name when rerezzed. | ||
92 | /// </summary> | ||
93 | protected List<SceneObjectGroup> m_memberObjects = new List<SceneObjectGroup>(); | ||
94 | |||
95 | public CoalescedSceneObjects(UUID creatorId) | ||
96 | { | ||
97 | CreatorId = creatorId; | ||
98 | } | ||
99 | |||
100 | public CoalescedSceneObjects(UUID creatorId, params SceneObjectGroup[] objs) : this(creatorId) | ||
101 | { | ||
102 | foreach (SceneObjectGroup obj in objs) | ||
103 | Add(obj); | ||
104 | } | ||
105 | |||
106 | /// <summary> | ||
107 | /// Add an object to the coalescence. | ||
108 | /// </summary> | ||
109 | /// <param name="obj"></param> | ||
110 | /// <param name="offset">The offset of the object within the group</param> | ||
111 | public void Add(SceneObjectGroup obj) | ||
112 | { | ||
113 | lock (m_memberObjects) | ||
114 | m_memberObjects.Add(obj); | ||
115 | } | ||
116 | |||
117 | /// <summary> | ||
118 | /// Removes a scene object from the coalescene | ||
119 | /// </summary> | ||
120 | /// <param name="sceneObjectId"></param> | ||
121 | /// <returns>true if the object was there to be removed, false if not.</returns> | ||
122 | public bool Remove(SceneObjectGroup obj) | ||
123 | { | ||
124 | lock (m_memberObjects) | ||
125 | return m_memberObjects.Remove(obj); | ||
126 | } | ||
127 | |||
128 | /// <summary> | ||
129 | /// Get the total size of the coalescence (the size required to cover all the objects within it) and the | ||
130 | /// offsets of each of those objects. | ||
131 | /// </summary> | ||
132 | /// <param name="size"></param> | ||
133 | /// <returns> | ||
134 | /// An array of offsets. The order of objects is the same as returned from the Objects property | ||
135 | /// </returns> | ||
136 | public Vector3[] GetSizeAndOffsets(out Vector3 size) | ||
137 | { | ||
138 | float minX, minY, minZ; | ||
139 | float maxX, maxY, maxZ; | ||
140 | |||
141 | Vector3[] offsets | ||
142 | = Scene.GetCombinedBoundingBox( | ||
143 | Objects, out minX, out maxX, out minY, out maxY, out minZ, out maxZ); | ||
144 | |||
145 | float sizeX = maxX - minX; | ||
146 | float sizeY = maxY - minY; | ||
147 | float sizeZ = maxZ - minZ; | ||
148 | |||
149 | size = new Vector3(sizeX, sizeY, sizeZ); | ||
150 | |||
151 | return offsets; | ||
152 | } | ||
153 | } | ||
154 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index f9599f5..e3ed905 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -58,17 +58,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
58 | 58 | ||
59 | public class Prioritizer | 59 | public class Prioritizer |
60 | { | 60 | { |
61 | // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 61 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
62 | 62 | ||
63 | /// <summary> | ||
64 | /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the | ||
65 | /// viewer before child prim updates. | ||
66 | /// The adjustment is added to child prims and subtracted from root prims, so the gap ends up | ||
67 | /// being double. We do it both ways so that there is a still a priority delta even if the priority is already | ||
68 | /// double.MinValue or double.MaxValue. | ||
69 | /// </summary> | ||
70 | private double m_childPrimAdjustmentFactor = 0.05; | ||
71 | |||
72 | private Scene m_scene; | 63 | private Scene m_scene; |
73 | 64 | ||
74 | public Prioritizer(Scene scene) | 65 | public Prioritizer(Scene scene) |
@@ -76,17 +67,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
76 | m_scene = scene; | 67 | m_scene = scene; |
77 | } | 68 | } |
78 | 69 | ||
79 | public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) | 70 | /// <summary> |
71 | /// Returns the priority queue into which the update should be placed. Updates within a | ||
72 | /// queue will be processed in arrival order. There are currently 12 priority queues | ||
73 | /// implemented in PriorityQueue class in LLClientView. Queue 0 is generally retained | ||
74 | /// for avatar updates. The fair queuing discipline for processing the priority queues | ||
75 | /// assumes that the number of entities in each priority queues increases exponentially. | ||
76 | /// So for example... if queue 1 contains all updates within 10m of the avatar or camera | ||
77 | /// then queue 2 at 20m is about 3X bigger in space & about 3X bigger in total number | ||
78 | /// of updates. | ||
79 | /// </summary> | ||
80 | public uint GetUpdatePriority(IClientAPI client, ISceneEntity entity) | ||
80 | { | 81 | { |
81 | double priority = 0; | 82 | // If entity is null we have a serious problem |
82 | |||
83 | if (entity == null) | 83 | if (entity == null) |
84 | return 100000; | 84 | { |
85 | m_log.WarnFormat("[PRIORITIZER] attempt to prioritize null entity"); | ||
86 | throw new InvalidOperationException("Prioritization entity not defined"); | ||
87 | } | ||
88 | |||
89 | // If this is an update for our own avatar give it the highest priority | ||
90 | if (client.AgentId == entity.UUID) | ||
91 | return 0; | ||
92 | |||
93 | uint priority; | ||
85 | 94 | ||
86 | switch (m_scene.UpdatePrioritizationScheme) | 95 | switch (m_scene.UpdatePrioritizationScheme) |
87 | { | 96 | { |
88 | case UpdatePrioritizationSchemes.Time: | 97 | case UpdatePrioritizationSchemes.Time: |
89 | priority = GetPriorityByTime(); | 98 | priority = GetPriorityByTime(client, entity); |
90 | break; | 99 | break; |
91 | case UpdatePrioritizationSchemes.Distance: | 100 | case UpdatePrioritizationSchemes.Distance: |
92 | priority = GetPriorityByDistance(client, entity); | 101 | priority = GetPriorityByDistance(client, entity); |
@@ -104,180 +113,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | 113 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); |
105 | } | 114 | } |
106 | 115 | ||
107 | // Adjust priority so that root prims are sent to the viewer first. This is especially important for | ||
108 | // attachments acting as huds, since current viewers fail to display hud child prims if their updates | ||
109 | // arrive before the root one. | ||
110 | if (entity is SceneObjectPart) | ||
111 | { | ||
112 | SceneObjectPart sop = ((SceneObjectPart)entity); | ||
113 | |||
114 | if (sop.IsRoot) | ||
115 | { | ||
116 | if (priority >= double.MinValue + m_childPrimAdjustmentFactor) | ||
117 | priority -= m_childPrimAdjustmentFactor; | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | if (priority <= double.MaxValue - m_childPrimAdjustmentFactor) | ||
122 | priority += m_childPrimAdjustmentFactor; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | return priority; | 116 | return priority; |
127 | } | 117 | } |
128 | 118 | ||
129 | private double GetPriorityByTime() | 119 | |
120 | private uint GetPriorityByTime(IClientAPI client, ISceneEntity entity) | ||
130 | { | 121 | { |
131 | return DateTime.UtcNow.ToOADate(); | 122 | return 1; |
132 | } | 123 | } |
133 | 124 | ||
134 | private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity) | 125 | private uint GetPriorityByDistance(IClientAPI client, ISceneEntity entity) |
135 | { | 126 | { |
136 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); | 127 | return ComputeDistancePriority(client,entity,false); |
137 | if (presence != null) | 128 | } |
138 | { | 129 | |
139 | // If this is an update for our own avatar give it the highest priority | 130 | private uint GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) |
140 | if (presence == entity) | 131 | { |
141 | return 0.0; | 132 | return ComputeDistancePriority(client,entity,true); |
142 | |||
143 | // Use the camera position for local agents and avatar position for remote agents | ||
144 | Vector3 presencePos = (presence.IsChildAgent) ? | ||
145 | presence.AbsolutePosition : | ||
146 | presence.CameraPosition; | ||
147 | |||
148 | // Use group position for child prims | ||
149 | Vector3 entityPos; | ||
150 | if (entity is SceneObjectPart) | ||
151 | { | ||
152 | // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene | ||
153 | // before its scheduled update was triggered | ||
154 | //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | ||
155 | entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition; | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | entityPos = entity.AbsolutePosition; | ||
160 | } | ||
161 | |||
162 | return Vector3.DistanceSquared(presencePos, entityPos); | ||
163 | } | ||
164 | |||
165 | return double.NaN; | ||
166 | } | 133 | } |
167 | 134 | ||
168 | private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) | 135 | private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) |
169 | { | 136 | { |
137 | uint pqueue = ComputeDistancePriority(client,entity,true); | ||
138 | |||
170 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); | 139 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); |
171 | if (presence != null) | 140 | if (presence != null) |
172 | { | 141 | { |
173 | // If this is an update for our own avatar give it the highest priority | ||
174 | if (presence == entity) | ||
175 | return 0.0; | ||
176 | |||
177 | // Use group position for child prims | ||
178 | Vector3 entityPos = entity.AbsolutePosition; | ||
179 | if (entity is SceneObjectPart) | ||
180 | { | ||
181 | // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene | ||
182 | // before its scheduled update was triggered | ||
183 | //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | ||
184 | entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition; | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | entityPos = entity.AbsolutePosition; | ||
189 | } | ||
190 | |||
191 | if (!presence.IsChildAgent) | 142 | if (!presence.IsChildAgent) |
192 | { | 143 | { |
193 | // Root agent. Use distance from camera and a priority decrease for objects behind us | 144 | if (entity is SceneObjectPart) |
194 | Vector3 camPosition = presence.CameraPosition; | 145 | { |
195 | Vector3 camAtAxis = presence.CameraAtAxis; | 146 | // Non physical prims are lower priority than physical prims |
196 | 147 | PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; | |
197 | // Distance | 148 | if (physActor == null || !physActor.IsPhysical) |
198 | double priority = Vector3.DistanceSquared(camPosition, entityPos); | 149 | pqueue++; |
199 | |||
200 | // Plane equation | ||
201 | float d = -Vector3.Dot(camPosition, camAtAxis); | ||
202 | float p = Vector3.Dot(camAtAxis, entityPos) + d; | ||
203 | if (p < 0.0f) priority *= 2.0; | ||
204 | |||
205 | return priority; | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | // Child agent. Use the normal distance method | ||
210 | Vector3 presencePos = presence.AbsolutePosition; | ||
211 | 150 | ||
212 | return Vector3.DistanceSquared(presencePos, entityPos); | 151 | // Attachments are high priority, |
152 | // MIC: shouldn't these already be in the highest priority queue already | ||
153 | // since their root position is same as the avatars? | ||
154 | if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) | ||
155 | pqueue = 1; | ||
156 | } | ||
213 | } | 157 | } |
214 | } | 158 | } |
215 | 159 | ||
216 | return double.NaN; | 160 | return pqueue; |
217 | } | 161 | } |
218 | 162 | ||
219 | private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) | 163 | private uint ComputeDistancePriority(IClientAPI client, ISceneEntity entity, bool useFrontBack) |
220 | { | 164 | { |
221 | // If this is an update for our own avatar give it the highest priority | 165 | // Get this agent's position |
222 | if (client.AgentId == entity.UUID) | 166 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); |
223 | return 0.0; | 167 | if (presence == null) |
224 | if (entity == null) | 168 | { |
225 | return double.NaN; | 169 | // this shouldn't happen, it basically means that we are prioritizing |
170 | // updates to send to a client that doesn't have a presence in the scene | ||
171 | // seems like there's race condition here... | ||
226 | 172 | ||
227 | // Use group position for child prims | 173 | // m_log.WarnFormat("[PRIORITIZER] attempt to use agent {0} not in the scene",client.AgentId); |
174 | // throw new InvalidOperationException("Prioritization agent not defined"); | ||
175 | return Int32.MaxValue; | ||
176 | } | ||
177 | |||
178 | // Use group position for child prims, since we are putting child prims in | ||
179 | // the same queue with the root of the group, the root prim (which goes into | ||
180 | // the queue first) should always be sent first, no need to adjust child prim | ||
181 | // priorities | ||
228 | Vector3 entityPos = entity.AbsolutePosition; | 182 | Vector3 entityPos = entity.AbsolutePosition; |
229 | if (entity is SceneObjectPart) | 183 | if (entity is SceneObjectPart) |
230 | { | 184 | { |
231 | SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; | 185 | SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; |
232 | if (group != null) | 186 | if (group != null) |
233 | entityPos = group.AbsolutePosition; | 187 | entityPos = group.AbsolutePosition; |
234 | else | ||
235 | entityPos = entity.AbsolutePosition; | ||
236 | } | 188 | } |
237 | else | ||
238 | entityPos = entity.AbsolutePosition; | ||
239 | 189 | ||
240 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); | 190 | // Use the camera position for local agents and avatar position for remote agents |
241 | if (presence != null) | 191 | Vector3 presencePos = (presence.IsChildAgent) ? |
242 | { | 192 | presence.AbsolutePosition : |
243 | if (!presence.IsChildAgent) | 193 | presence.CameraPosition; |
244 | { | ||
245 | if (entity is ScenePresence) | ||
246 | return 1.0; | ||
247 | |||
248 | // Root agent. Use distance from camera and a priority decrease for objects behind us | ||
249 | Vector3 camPosition = presence.CameraPosition; | ||
250 | Vector3 camAtAxis = presence.CameraAtAxis; | ||
251 | 194 | ||
252 | // Distance | 195 | // Compute the distance... |
253 | double priority = Vector3.DistanceSquared(camPosition, entityPos); | 196 | double distance = Vector3.Distance(presencePos, entityPos); |
254 | 197 | ||
255 | // Plane equation | 198 | // And convert the distance to a priority queue, this computation gives queues |
256 | float d = -Vector3.Dot(camPosition, camAtAxis); | 199 | // at 10, 20, 40, 80, 160, 320, 640, and 1280m |
257 | float p = Vector3.Dot(camAtAxis, entityPos) + d; | 200 | uint pqueue = 1; |
258 | if (p < 0.0f) priority *= 2.0; | 201 | for (int i = 0; i < 8; i++) |
259 | 202 | { | |
260 | if (entity is SceneObjectPart) | 203 | if (distance < 10 * Math.Pow(2.0,i)) |
261 | { | 204 | break; |
262 | PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; | 205 | pqueue++; |
263 | if (physActor == null || !physActor.IsPhysical) | 206 | } |
264 | priority += 100; | 207 | |
265 | 208 | // If this is a root agent, then determine front & back | |
266 | if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) | 209 | // Bump up the priority queue (drop the priority) for any objects behind the avatar |
267 | priority = 1.0; | 210 | if (useFrontBack && ! presence.IsChildAgent) |
268 | } | 211 | { |
269 | return priority; | 212 | // Root agent, decrease priority for objects behind us |
270 | } | 213 | Vector3 camPosition = presence.CameraPosition; |
271 | else | 214 | Vector3 camAtAxis = presence.CameraAtAxis; |
272 | { | 215 | |
273 | // Child agent. Use the normal distance method | 216 | // Plane equation |
274 | Vector3 presencePos = presence.AbsolutePosition; | 217 | float d = -Vector3.Dot(camPosition, camAtAxis); |
275 | 218 | float p = Vector3.Dot(camAtAxis, entityPos) + d; | |
276 | return Vector3.DistanceSquared(presencePos, entityPos); | 219 | if (p < 0.0f) |
277 | } | 220 | pqueue++; |
278 | } | 221 | } |
279 | 222 | ||
280 | return double.NaN; | 223 | return pqueue; |
281 | } | 224 | } |
225 | |||
282 | } | 226 | } |
283 | } | 227 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 73dd531..0f85925 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1955,11 +1955,49 @@ namespace OpenSim.Region.Framework.Scenes | |||
1955 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 1955 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
1956 | bool RezSelected, bool RemoveItem, UUID fromTaskID) | 1956 | bool RezSelected, bool RemoveItem, UUID fromTaskID) |
1957 | { | 1957 | { |
1958 | IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); | 1958 | // m_log.DebugFormat( |
1959 | if (invAccess != null) | 1959 | // "[PRIM INVENTORY]: RezObject from {0} for item {1} from task id {2}", |
1960 | invAccess.RezObject( | 1960 | // remoteClient.Name, itemID, fromTaskID); |
1961 | remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | 1961 | |
1962 | RezSelected, RemoveItem, fromTaskID, false); | 1962 | if (fromTaskID == UUID.Zero) |
1963 | { | ||
1964 | IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); | ||
1965 | if (invAccess != null) | ||
1966 | invAccess.RezObject( | ||
1967 | remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | ||
1968 | RezSelected, RemoveItem, fromTaskID, false); | ||
1969 | } | ||
1970 | else | ||
1971 | { | ||
1972 | SceneObjectPart part = GetSceneObjectPart(fromTaskID); | ||
1973 | if (part == null) | ||
1974 | { | ||
1975 | m_log.ErrorFormat( | ||
1976 | "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such scene object", | ||
1977 | remoteClient.Name, itemID, fromTaskID); | ||
1978 | |||
1979 | return; | ||
1980 | } | ||
1981 | |||
1982 | TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); | ||
1983 | if (item == null) | ||
1984 | { | ||
1985 | m_log.ErrorFormat( | ||
1986 | "[TASK INVENTORY]: {0} tried to rez item id {1} from object id {2} but there is no such item", | ||
1987 | remoteClient.Name, itemID, fromTaskID); | ||
1988 | |||
1989 | return; | ||
1990 | } | ||
1991 | |||
1992 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | ||
1993 | Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); | ||
1994 | Vector3 pos | ||
1995 | = GetNewRezLocation( | ||
1996 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | ||
1997 | BypassRayCast, bRayEndIsIntersection, true, scale, false); | ||
1998 | |||
1999 | RezObject(part, item, pos, null, Vector3.Zero, 0); | ||
2000 | } | ||
1963 | } | 2001 | } |
1964 | 2002 | ||
1965 | /// <summary> | 2003 | /// <summary> |
@@ -1967,14 +2005,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1967 | /// </summary> | 2005 | /// </summary> |
1968 | /// <param name="sourcePart"></param> | 2006 | /// <param name="sourcePart"></param> |
1969 | /// <param name="item"></param> | 2007 | /// <param name="item"></param> |
1970 | /// <param name="pos"></param> | 2008 | /// <param name="pos">The position of the rezzed object.</param> |
1971 | /// <param name="rot"></param> | 2009 | /// <param name="rot">The rotation of the rezzed object. If null, then the rotation stored with the object |
1972 | /// <param name="vel"></param> | 2010 | /// will be used if it exists.</param> |
2011 | /// <param name="vel">The velocity of the rezzed object.</param> | ||
1973 | /// <param name="param"></param> | 2012 | /// <param name="param"></param> |
1974 | /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns> | 2013 | /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns> |
1975 | public virtual SceneObjectGroup RezObject( | 2014 | public virtual SceneObjectGroup RezObject( |
1976 | SceneObjectPart sourcePart, TaskInventoryItem item, | 2015 | SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) |
1977 | Vector3 pos, Quaternion rot, Vector3 vel, int param) | ||
1978 | { | 2016 | { |
1979 | if (null == item) | 2017 | if (null == item) |
1980 | return null; | 2018 | return null; |
@@ -1992,8 +2030,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1992 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 2030 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) |
1993 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); | 2031 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); |
1994 | } | 2032 | } |
1995 | 2033 | ||
1996 | AddNewSceneObject(group, true, pos, rot, vel); | 2034 | AddNewSceneObject(group, true); |
2035 | |||
2036 | group.AbsolutePosition = pos; | ||
2037 | group.Velocity = vel; | ||
2038 | |||
2039 | if (rot != null) | ||
2040 | group.UpdateGroupRotationR((Quaternion)rot); | ||
1997 | 2041 | ||
1998 | // We can only call this after adding the scene object, since the scene object references the scene | 2042 | // We can only call this after adding the scene object, since the scene object references the scene |
1999 | // to find out if scripts should be activated at all. | 2043 | // to find out if scripts should be activated at all. |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f0acc38..01de824 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -3665,6 +3665,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3665 | return false; | 3665 | return false; |
3666 | } | 3666 | } |
3667 | 3667 | ||
3668 | int num = m_sceneGraph.GetNumberOfScenePresences(); | ||
3669 | |||
3670 | if (num >= RegionInfo.RegionSettings.AgentLimit) | ||
3671 | { | ||
3672 | if (!Permissions.IsAdministrator(cAgentData.AgentID)) | ||
3673 | return false; | ||
3674 | } | ||
3675 | |||
3676 | |||
3668 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); | 3677 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); |
3669 | 3678 | ||
3670 | if (childAgentUpdate != null) | 3679 | if (childAgentUpdate != null) |
@@ -4839,7 +4848,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
4839 | } | 4848 | } |
4840 | } | 4849 | } |
4841 | 4850 | ||
4842 | public Vector3[] GetCombinedBoundingBox(List<SceneObjectGroup> objects, out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) | 4851 | /// <summary> |
4852 | /// Get the volume of space that will encompass all the given objects. | ||
4853 | /// </summary> | ||
4854 | /// <param name="objects"></param> | ||
4855 | /// <param name="minX"></param> | ||
4856 | /// <param name="maxX"></param> | ||
4857 | /// <param name="minY"></param> | ||
4858 | /// <param name="maxY"></param> | ||
4859 | /// <param name="minZ"></param> | ||
4860 | /// <param name="maxZ"></param> | ||
4861 | /// <returns></returns> | ||
4862 | public static Vector3[] GetCombinedBoundingBox( | ||
4863 | List<SceneObjectGroup> objects, | ||
4864 | out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) | ||
4843 | { | 4865 | { |
4844 | minX = 256; | 4866 | minX = 256; |
4845 | maxX = -256; | 4867 | maxX = -256; |
@@ -4857,6 +4879,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
4857 | Vector3 vec = g.AbsolutePosition; | 4879 | Vector3 vec = g.AbsolutePosition; |
4858 | 4880 | ||
4859 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); | 4881 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); |
4882 | |||
4883 | // m_log.DebugFormat( | ||
4884 | // "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}", | ||
4885 | // g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ)); | ||
4860 | 4886 | ||
4861 | ominX += vec.X; | 4887 | ominX += vec.X; |
4862 | omaxX += vec.X; | 4888 | omaxX += vec.X; |
@@ -4949,6 +4975,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
4949 | // child agent creation, thereby emulating the SL behavior. | 4975 | // child agent creation, thereby emulating the SL behavior. |
4950 | public bool QueryAccess(UUID agentID, Vector3 position, out string reason) | 4976 | public bool QueryAccess(UUID agentID, Vector3 position, out string reason) |
4951 | { | 4977 | { |
4978 | int num = m_sceneGraph.GetNumberOfScenePresences(); | ||
4979 | |||
4980 | if (num >= RegionInfo.RegionSettings.AgentLimit) | ||
4981 | { | ||
4982 | if (!Permissions.IsAdministrator(agentID)) | ||
4983 | { | ||
4984 | reason = "The region is full"; | ||
4985 | return false; | ||
4986 | } | ||
4987 | } | ||
4988 | |||
4952 | reason = String.Empty; | 4989 | reason = String.Empty; |
4953 | return true; | 4990 | return true; |
4954 | } | 4991 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 97af0a0..fc31b65 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -800,6 +800,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
800 | return m_scenePresenceArray; | 800 | return m_scenePresenceArray; |
801 | } | 801 | } |
802 | 802 | ||
803 | public int GetNumberOfScenePresences() | ||
804 | { | ||
805 | return m_scenePresenceArray.Count; | ||
806 | } | ||
807 | |||
803 | /// <summary> | 808 | /// <summary> |
804 | /// Request a scene presence by UUID. Fast, indexed lookup. | 809 | /// Request a scene presence by UUID. Fast, indexed lookup. |
805 | /// </summary> | 810 | /// </summary> |
@@ -997,6 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
997 | { | 1002 | { |
998 | foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts) | 1003 | foreach (SceneObjectPart p in ((SceneObjectGroup)entity).Parts) |
999 | { | 1004 | { |
1005 | // m_log.DebugFormat("[SCENE GRAPH]: Part {0} has name {1}", p.UUID, p.Name); | ||
1006 | |||
1000 | if (p.Name == name) | 1007 | if (p.Name == name) |
1001 | { | 1008 | { |
1002 | sop = p; | 1009 | sop = p; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index e8095c0..4bca3d0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -81,16 +81,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
81 | } | 81 | } |
82 | 82 | ||
83 | /// <summary> | 83 | /// <summary> |
84 | /// Add an inventory item to a prim in this group. | 84 | /// Add an inventory item from a user's inventory to a prim in this scene object. |
85 | /// </summary> | 85 | /// </summary> |
86 | /// <param name="remoteClient"></param> | 86 | /// <param name="remoteClient">The client adding the item.</param> |
87 | /// <param name="localID"></param> | 87 | /// <param name="localID">The local ID of the part receiving the add.</param> |
88 | /// <param name="item"></param> | 88 | /// <param name="item">The user inventory item being added.</param> |
89 | /// <param name="copyItemID">The item UUID that should be used by the new item.</param> | 89 | /// <param name="copyItemID">The item UUID that should be used by the new item.</param> |
90 | /// <returns></returns> | 90 | /// <returns></returns> |
91 | public bool AddInventoryItem(IClientAPI remoteClient, uint localID, | 91 | public bool AddInventoryItem(IClientAPI remoteClient, uint localID, |
92 | InventoryItemBase item, UUID copyItemID) | 92 | InventoryItemBase item, UUID copyItemID) |
93 | { | 93 | { |
94 | // m_log.DebugFormat( | ||
95 | // "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}", | ||
96 | // item.Name, remoteClient.Name, localID); | ||
97 | |||
94 | UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; | 98 | UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; |
95 | 99 | ||
96 | SceneObjectPart part = GetChildPart(localID); | 100 | SceneObjectPart part = GetChildPart(localID); |
@@ -132,15 +136,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
132 | taskItem.GroupPermissions = item.GroupPermissions; | 136 | taskItem.GroupPermissions = item.GroupPermissions; |
133 | taskItem.NextPermissions = item.NextPermissions; | 137 | taskItem.NextPermissions = item.NextPermissions; |
134 | } | 138 | } |
135 | 139 | ||
136 | taskItem.Flags = item.Flags; | 140 | taskItem.Flags = item.Flags; |
141 | |||
142 | // m_log.DebugFormat( | ||
143 | // "[PRIM INVENTORY]: Flags are 0x{0:X} for item {1} added to part {2} by {3}", | ||
144 | // taskItem.Flags, taskItem.Name, localID, remoteClient.Name); | ||
145 | |||
137 | // TODO: These are pending addition of those fields to TaskInventoryItem | 146 | // TODO: These are pending addition of those fields to TaskInventoryItem |
138 | // taskItem.SalePrice = item.SalePrice; | 147 | // taskItem.SalePrice = item.SalePrice; |
139 | // taskItem.SaleType = item.SaleType; | 148 | // taskItem.SaleType = item.SaleType; |
140 | taskItem.CreationDate = (uint)item.CreationDate; | 149 | taskItem.CreationDate = (uint)item.CreationDate; |
141 | 150 | ||
142 | bool addFromAllowedDrop = false; | 151 | bool addFromAllowedDrop = false; |
143 | if (remoteClient!=null) | 152 | if (remoteClient != null) |
144 | { | 153 | { |
145 | addFromAllowedDrop = remoteClient.AgentId != part.OwnerID; | 154 | addFromAllowedDrop = remoteClient.AgentId != part.OwnerID; |
146 | } | 155 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ca7d9d9..19a9506 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -296,11 +296,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
296 | { | 296 | { |
297 | Vector3 val = value; | 297 | Vector3 val = value; |
298 | 298 | ||
299 | if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) | 299 | if (Scene != null) |
300 | || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) | ||
301 | && !IsAttachmentCheckFull() && (!m_scene.LoadingPrims)) | ||
302 | { | 300 | { |
303 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 301 | if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) |
302 | || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) | ||
303 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) | ||
304 | { | ||
305 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | ||
306 | } | ||
304 | } | 307 | } |
305 | 308 | ||
306 | if (RootPart.GetStatusSandbox()) | 309 | if (RootPart.GetStatusSandbox()) |
@@ -308,8 +311,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
308 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) | 311 | if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) |
309 | { | 312 | { |
310 | RootPart.ScriptSetPhysicsStatus(false); | 313 | RootPart.ScriptSetPhysicsStatus(false); |
311 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | 314 | |
312 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | 315 | if (Scene != null) |
316 | Scene.SimChat(Utils.StringToBytes("Hit Sandbox Limit"), | ||
317 | ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); | ||
318 | |||
313 | return; | 319 | return; |
314 | } | 320 | } |
315 | } | 321 | } |
@@ -326,7 +332,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
326 | //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | 332 | //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); |
327 | //} | 333 | //} |
328 | 334 | ||
329 | m_scene.EventManager.TriggerParcelPrimCountTainted(); | 335 | if (Scene != null) |
336 | Scene.EventManager.TriggerParcelPrimCountTainted(); | ||
330 | } | 337 | } |
331 | } | 338 | } |
332 | 339 | ||
@@ -1765,10 +1772,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1765 | /// <param name="part"></param> | 1772 | /// <param name="part"></param> |
1766 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) | 1773 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) |
1767 | { | 1774 | { |
1768 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, | 1775 | remoteClient.SendObjectPropertiesFamilyData(RootPart, RequestFlags); |
1769 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, | 1776 | |
1770 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | 1777 | // remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, |
1771 | RootPart.CreatorID, RootPart.Name, RootPart.Description); | 1778 | // RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, |
1779 | // RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | ||
1780 | // RootPart.CreatorID, RootPart.Name, RootPart.Description); | ||
1772 | } | 1781 | } |
1773 | 1782 | ||
1774 | public void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID) | 1783 | public void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4d5eedf..8a8a699 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -2055,15 +2055,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2055 | 2055 | ||
2056 | public void GetProperties(IClientAPI client) | 2056 | public void GetProperties(IClientAPI client) |
2057 | { | 2057 | { |
2058 | //Viewer wants date in microseconds so multiply it by 1,000,000. | 2058 | client.SendObjectPropertiesReply(this); |
2059 | client.SendObjectPropertiesReply( | ||
2060 | m_fromUserInventoryItemID, (ulong)_creationDate*(ulong)1e6, _creatorID, UUID.Zero, UUID.Zero, | ||
2061 | _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID, | ||
2062 | ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, | ||
2063 | ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask, | ||
2064 | ParentGroup.RootPart._baseMask, | ||
2065 | ParentGroup.RootPart.ObjectSaleType, | ||
2066 | ParentGroup.RootPart.SalePrice); | ||
2067 | } | 2059 | } |
2068 | 2060 | ||
2069 | public UUID GetRootPartUUID() | 2061 | public UUID GetRootPartUUID() |
@@ -2088,7 +2080,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
2088 | 2080 | ||
2089 | axPos *= parentRot; | 2081 | axPos *= parentRot; |
2090 | Vector3 translationOffsetPosition = axPos; | 2082 | Vector3 translationOffsetPosition = axPos; |
2091 | return GroupPosition + translationOffsetPosition; | 2083 | |
2084 | // m_log.DebugFormat("[SCENE OBJECT PART]: Found group pos {0} for part {1}", GroupPosition, Name); | ||
2085 | |||
2086 | Vector3 worldPos = GroupPosition + translationOffsetPosition; | ||
2087 | |||
2088 | // m_log.DebugFormat("[SCENE OBJECT PART]: Found world pos {0} for part {1}", worldPos, Name); | ||
2089 | |||
2090 | return worldPos; | ||
2092 | } | 2091 | } |
2093 | 2092 | ||
2094 | /// <summary> | 2093 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs new file mode 100644 index 0000000..55455cc --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs | |||
@@ -0,0 +1,160 @@ | |||
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 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Drawing; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using System.Xml; | ||
34 | using log4net; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | |||
40 | namespace OpenSim.Region.Framework.Scenes.Serialization | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Serialize and deserialize coalesced scene objects. | ||
44 | /// </summary> | ||
45 | /// <remarks> | ||
46 | /// Deserialization not yet here. | ||
47 | /// </remarks> | ||
48 | public class CoalescedSceneObjectsSerializer | ||
49 | { | ||
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | |||
52 | /// <summary> | ||
53 | /// Serialize coalesced objects to Xml | ||
54 | /// </summary> | ||
55 | /// <param name="coa"></param> | ||
56 | /// <returns></returns> | ||
57 | public static string ToXml(CoalescedSceneObjects coa) | ||
58 | { | ||
59 | using (StringWriter sw = new StringWriter()) | ||
60 | { | ||
61 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | ||
62 | { | ||
63 | Vector3 size; | ||
64 | |||
65 | List<SceneObjectGroup> coaObjects = coa.Objects; | ||
66 | |||
67 | // m_log.DebugFormat( | ||
68 | // "[COALESCED SCENE OBJECTS SERIALIZER]: Writing {0} objects for coalesced object", | ||
69 | // coaObjects.Count); | ||
70 | |||
71 | // This is weak - we're relying on the set of coalesced objects still being identical | ||
72 | Vector3[] offsets = coa.GetSizeAndOffsets(out size); | ||
73 | |||
74 | writer.WriteStartElement("CoalescedObject"); | ||
75 | |||
76 | writer.WriteAttributeString("x", size.X.ToString()); | ||
77 | writer.WriteAttributeString("y", size.Y.ToString()); | ||
78 | writer.WriteAttributeString("z", size.Z.ToString()); | ||
79 | |||
80 | // Embed the offsets into the group XML | ||
81 | for (int i = 0; i < coaObjects.Count; i++) | ||
82 | { | ||
83 | SceneObjectGroup obj = coaObjects[i]; | ||
84 | |||
85 | // m_log.DebugFormat( | ||
86 | // "[COALESCED SCENE OBJECTS SERIALIZER]: Writing offset for object {0}, {1}", | ||
87 | // i, obj.Name); | ||
88 | |||
89 | writer.WriteStartElement("SceneObjectGroup"); | ||
90 | writer.WriteAttributeString("offsetx", offsets[i].X.ToString()); | ||
91 | writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); | ||
92 | writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); | ||
93 | |||
94 | SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, true); | ||
95 | |||
96 | writer.WriteEndElement(); // SceneObjectGroup | ||
97 | } | ||
98 | |||
99 | writer.WriteEndElement(); // CoalescedObject | ||
100 | } | ||
101 | |||
102 | string output = sw.ToString(); | ||
103 | |||
104 | // Console.WriteLine(output); | ||
105 | |||
106 | return output; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | public static bool TryFromXml(string xml, out CoalescedSceneObjects coa) | ||
111 | { | ||
112 | // m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml); | ||
113 | |||
114 | coa = null; | ||
115 | |||
116 | using (StringReader sr = new StringReader(xml)) | ||
117 | { | ||
118 | using (XmlTextReader reader = new XmlTextReader(sr)) | ||
119 | { | ||
120 | try | ||
121 | { | ||
122 | reader.Read(); | ||
123 | if (reader.Name != "CoalescedObject") | ||
124 | { | ||
125 | // m_log.DebugFormat( | ||
126 | // "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false", | ||
127 | // reader.Name); | ||
128 | |||
129 | return false; | ||
130 | } | ||
131 | |||
132 | coa = new CoalescedSceneObjects(UUID.Zero); | ||
133 | reader.Read(); | ||
134 | |||
135 | while (reader.NodeType != XmlNodeType.EndElement && reader.Name != "CoalescedObject") | ||
136 | { | ||
137 | if (reader.Name == "SceneObjectGroup") | ||
138 | { | ||
139 | string soXml = reader.ReadOuterXml(); | ||
140 | coa.Add(SceneObjectSerializer.FromOriginalXmlFormat(soXml)); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | reader.ReadEndElement(); // CoalescedObject | ||
145 | } | ||
146 | catch (Exception e) | ||
147 | { | ||
148 | m_log.ErrorFormat( | ||
149 | "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed with {0} {1}", | ||
150 | e.Message, e.StackTrace); | ||
151 | |||
152 | return false; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | return true; | ||
158 | } | ||
159 | } | ||
160 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 57ae4fd..bb8a83a 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | |||
@@ -139,6 +139,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
139 | return sw.ToString(); | 139 | return sw.ToString(); |
140 | } | 140 | } |
141 | } | 141 | } |
142 | |||
142 | 143 | ||
143 | /// <summary> | 144 | /// <summary> |
144 | /// Serialize a scene object to the original xml format | 145 | /// Serialize a scene object to the original xml format |
@@ -147,10 +148,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
147 | /// <returns></returns> | 148 | /// <returns></returns> |
148 | public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) | 149 | public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) |
149 | { | 150 | { |
151 | ToOriginalXmlFormat(sceneObject, writer, false); | ||
152 | } | ||
153 | |||
154 | /// <summary> | ||
155 | /// Serialize a scene object to the original xml format | ||
156 | /// </summary> | ||
157 | /// <param name="sceneObject"></param> | ||
158 | /// <param name="writer"></param> | ||
159 | /// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param> | ||
160 | /// <returns></returns> | ||
161 | public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool noRootElement) | ||
162 | { | ||
150 | //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); | 163 | //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); |
151 | //int time = System.Environment.TickCount; | 164 | //int time = System.Environment.TickCount; |
152 | 165 | ||
153 | writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); | 166 | if (!noRootElement) |
167 | writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); | ||
168 | |||
154 | writer.WriteStartElement(String.Empty, "RootPart", String.Empty); | 169 | writer.WriteStartElement(String.Empty, "RootPart", String.Empty); |
155 | ToXmlFormat(sceneObject.RootPart, writer); | 170 | ToXmlFormat(sceneObject.RootPart, writer); |
156 | writer.WriteEndElement(); | 171 | writer.WriteEndElement(); |
@@ -170,10 +185,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
170 | 185 | ||
171 | writer.WriteEndElement(); // OtherParts | 186 | writer.WriteEndElement(); // OtherParts |
172 | sceneObject.SaveScriptedState(writer); | 187 | sceneObject.SaveScriptedState(writer); |
173 | writer.WriteEndElement(); // SceneObjectGroup | 188 | |
189 | if (!noRootElement) | ||
190 | writer.WriteEndElement(); // SceneObjectGroup | ||
174 | 191 | ||
175 | //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); | 192 | //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); |
176 | } | 193 | } |
177 | 194 | ||
178 | protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) | 195 | protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) |
179 | { | 196 | { |
@@ -1318,7 +1335,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization | |||
1318 | writer.WriteStartElement("SculptData"); | 1335 | writer.WriteStartElement("SculptData"); |
1319 | byte[] sd; | 1336 | byte[] sd; |
1320 | if (shp.SculptData != null) | 1337 | if (shp.SculptData != null) |
1321 | sd = shp.ExtraParams; | 1338 | sd = shp.SculptData; |
1322 | else | 1339 | else |
1323 | sd = Utils.EmptyBytes; | 1340 | sd = Utils.EmptyBytes; |
1324 | writer.WriteBase64(sd, 0, sd.Length); | 1341 | writer.WriteBase64(sd, 0, sd.Length); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs index 8588f7f..dd28416 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs | |||
@@ -117,11 +117,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
117 | ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); | 117 | ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); |
118 | 118 | ||
119 | 119 | ||
120 | Scene sceneB = SceneSetupHelpers.SetupScene("sceneB", sceneBId, 1010, 1010, "grid"); | 120 | Scene sceneB = SceneSetupHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); |
121 | SceneSetupHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); | 121 | SceneSetupHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); |
122 | sceneB.RegisterRegionWithGrid(); | 122 | sceneB.RegisterRegionWithGrid(); |
123 | 123 | ||
124 | Scene sceneA = SceneSetupHelpers.SetupScene("sceneA", sceneAId, 1000, 1000, "grid"); | 124 | Scene sceneA = SceneSetupHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); |
125 | SceneSetupHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); | 125 | SceneSetupHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); |
126 | sceneA.RegisterRegionWithGrid(); | 126 | sceneA.RegisterRegionWithGrid(); |
127 | 127 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index 8138bcc..2aef4b0 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | |||
@@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Tests | |||
101 | TestHelper.InMethod(); | 101 | TestHelper.InMethod(); |
102 | // log4net.Config.XmlConfigurator.Configure(); | 102 | // log4net.Config.XmlConfigurator.Configure(); |
103 | 103 | ||
104 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 104 | Scene scene = SceneSetupHelpers.SetupScene(); |
105 | UserAccount user1 = CreateUser(scene); | 105 | UserAccount user1 = CreateUser(scene); |
106 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); | 106 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); |
107 | SceneObjectPart sop1 = sog1.RootPart; | 107 | SceneObjectPart sop1 = sog1.RootPart; |
@@ -127,7 +127,7 @@ namespace OpenSim.Region.Framework.Tests | |||
127 | TestHelper.InMethod(); | 127 | TestHelper.InMethod(); |
128 | // log4net.Config.XmlConfigurator.Configure(); | 128 | // log4net.Config.XmlConfigurator.Configure(); |
129 | 129 | ||
130 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | 130 | Scene scene = SceneSetupHelpers.SetupScene(); |
131 | UserAccount user1 = CreateUser(scene); | 131 | UserAccount user1 = CreateUser(scene); |
132 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); | 132 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); |
133 | SceneObjectPart sop1 = sog1.RootPart; | 133 | SceneObjectPart sop1 = sog1.RootPart; |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index 6b70865..dbf9e0f 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs | |||
@@ -47,7 +47,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
47 | [SetUp] | 47 | [SetUp] |
48 | public void Init() | 48 | public void Init() |
49 | { | 49 | { |
50 | m_assetService = new MockAssetService(); | 50 | // FIXME: We don't need a full scene here - it would be enough to set up the asset service. |
51 | Scene scene = SceneSetupHelpers.SetupScene(); | ||
52 | m_assetService = scene.AssetService; | ||
51 | m_uuidGatherer = new UuidGatherer(m_assetService); | 53 | m_uuidGatherer = new UuidGatherer(m_assetService); |
52 | } | 54 | } |
53 | 55 | ||
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 83906d7..77b1535 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -298,10 +298,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
298 | if (null != objectAsset) | 298 | if (null != objectAsset) |
299 | { | 299 | { |
300 | string xml = Utils.BytesToString(objectAsset.Data); | 300 | string xml = Utils.BytesToString(objectAsset.Data); |
301 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | 301 | |
302 | 302 | CoalescedSceneObjects coa; | |
303 | if (null != sog) | 303 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) |
304 | GatherAssetUuids(sog, assetUuids); | 304 | { |
305 | foreach (SceneObjectGroup sog in coa.Objects) | ||
306 | GatherAssetUuids(sog, assetUuids); | ||
307 | } | ||
308 | else | ||
309 | { | ||
310 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | ||
311 | |||
312 | if (null != sog) | ||
313 | GatherAssetUuids(sog, assetUuids); | ||
314 | } | ||
305 | } | 315 | } |
306 | } | 316 | } |
307 | 317 | ||
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 821cd4b..4b6e52e 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1332,14 +1332,13 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1332 | 1332 | ||
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description) | 1335 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
1336 | { | 1336 | { |
1337 | 1337 | ||
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) | 1340 | public void SendObjectPropertiesReply(ISceneEntity entity) |
1341 | { | 1341 | { |
1342 | |||
1343 | } | 1342 | } |
1344 | 1343 | ||
1345 | public void SendAgentOffline(UUID[] agentIDs) | 1344 | public void SendAgentOffline(UUID[] agentIDs) |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 7909d8a..42efd67 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | |||
@@ -118,7 +118,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
118 | 118 | ||
119 | if (serviceDll == String.Empty) | 119 | if (serviceDll == String.Empty) |
120 | { | 120 | { |
121 | m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice"); | 121 | m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice. Not starting."); |
122 | return; | 122 | return; |
123 | } | 123 | } |
124 | 124 | ||
@@ -143,8 +143,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
143 | if (String.IsNullOrEmpty(m_freeSwitchRealm) || | 143 | if (String.IsNullOrEmpty(m_freeSwitchRealm) || |
144 | String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) | 144 | String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) |
145 | { | 145 | { |
146 | m_log.Error("[FreeSwitchVoice] plugin mis-configured"); | 146 | m_log.Error("[FreeSwitchVoice]: Freeswitch service mis-configured. Not starting."); |
147 | m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration"); | ||
148 | return; | 147 | return; |
149 | } | 148 | } |
150 | 149 | ||
@@ -164,24 +163,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
164 | // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); | 163 | // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); |
165 | // MainServer.Instance.AddStreamHandler(h); | 164 | // MainServer.Instance.AddStreamHandler(h); |
166 | 165 | ||
167 | |||
168 | |||
169 | MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), | 166 | MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), |
170 | FreeSwitchSLVoiceSigninHTTPHandler); | 167 | FreeSwitchSLVoiceSigninHTTPHandler); |
171 | 168 | ||
172 | MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), | 169 | MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), |
173 | FreeSwitchSLVoiceBuddyHTTPHandler); | 170 | FreeSwitchSLVoiceBuddyHTTPHandler); |
171 | |||
172 | MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_watcher.php", m_freeSwitchAPIPrefix), | ||
173 | FreeSwitchSLVoiceWatcherHTTPHandler); | ||
174 | 174 | ||
175 | m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); | 175 | m_log.InfoFormat("[FreeSwitchVoice]: using FreeSwitch server {0}", m_freeSwitchRealm); |
176 | 176 | ||
177 | m_Enabled = true; | 177 | m_Enabled = true; |
178 | 178 | ||
179 | m_log.Info("[FreeSwitchVoice] plugin enabled"); | 179 | m_log.Info("[FreeSwitchVoice]: plugin enabled"); |
180 | } | 180 | } |
181 | catch (Exception e) | 181 | catch (Exception e) |
182 | { | 182 | { |
183 | m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); | 183 | m_log.ErrorFormat("[FreeSwitchVoice]: plugin initialization failed: {0} {1}", e.Message, e.StackTrace); |
184 | m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); | ||
185 | return; | 184 | return; |
186 | } | 185 | } |
187 | 186 | ||
@@ -240,7 +239,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
240 | { | 239 | { |
241 | if (m_Enabled) | 240 | if (m_Enabled) |
242 | { | 241 | { |
243 | m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); | 242 | m_log.Info("[FreeSwitchVoice]: registering IVoiceModule with the scene"); |
244 | 243 | ||
245 | // register the voice interface for this module, so the script engine can call us | 244 | // register the voice interface for this module, so the script engine can call us |
246 | scene.RegisterModuleInterface<IVoiceModule>(this); | 245 | scene.RegisterModuleInterface<IVoiceModule>(this); |
@@ -302,7 +301,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
302 | // </summary> | 301 | // </summary> |
303 | public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) | 302 | public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) |
304 | { | 303 | { |
305 | m_log.DebugFormat("[FreeSwitchVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 304 | m_log.DebugFormat( |
305 | "[FreeSwitchVoice]: OnRegisterCaps() called with agentID {0} caps {1} in scene {2}", | ||
306 | agentID, caps, scene.RegionInfo.RegionName); | ||
306 | 307 | ||
307 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 308 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
308 | caps.RegisterHandler("ProvisionVoiceAccountRequest", | 309 | caps.RegisterHandler("ProvisionVoiceAccountRequest", |
@@ -344,6 +345,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
344 | public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, | 345 | public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param, |
345 | UUID agentID, Caps caps) | 346 | UUID agentID, Caps caps) |
346 | { | 347 | { |
348 | m_log.DebugFormat( | ||
349 | "[FreeSwitchVoice][PROVISIONVOICE]: ProvisionVoiceAccountRequest() request: {0}, path: {1}, param: {2}", request, path, param); | ||
350 | |||
347 | ScenePresence avatar = scene.GetScenePresence(agentID); | 351 | ScenePresence avatar = scene.GetScenePresence(agentID); |
348 | if (avatar == null) | 352 | if (avatar == null) |
349 | { | 353 | { |
@@ -357,9 +361,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
357 | 361 | ||
358 | try | 362 | try |
359 | { | 363 | { |
360 | //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | ||
361 | // request, path, param); | ||
362 | |||
363 | //XmlElement resp; | 364 | //XmlElement resp; |
364 | string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); | 365 | string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); |
365 | string password = "1234";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); | 366 | string password = "1234";//temp hack//new UUID(Guid.NewGuid()).ToString().Replace('-','Z').Substring(0,16); |
@@ -390,7 +391,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
390 | 391 | ||
391 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); | 392 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |
392 | 393 | ||
393 | m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); | 394 | // m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); |
394 | 395 | ||
395 | return r; | 396 | return r; |
396 | } | 397 | } |
@@ -416,6 +417,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
416 | public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, | 417 | public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param, |
417 | UUID agentID, Caps caps) | 418 | UUID agentID, Caps caps) |
418 | { | 419 | { |
420 | // m_log.DebugFormat( | ||
421 | // "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}", | ||
422 | // scene.RegionInfo.RegionName, agentID); | ||
423 | |||
419 | ScenePresence avatar = scene.GetScenePresence(agentID); | 424 | ScenePresence avatar = scene.GetScenePresence(agentID); |
420 | string avatarName = avatar.Name; | 425 | string avatarName = avatar.Name; |
421 | 426 | ||
@@ -453,8 +458,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
453 | 458 | ||
454 | if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) | 459 | if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) |
455 | { | 460 | { |
456 | m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", | 461 | // m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", |
457 | scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); | 462 | // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); |
458 | channelUri = String.Empty; | 463 | channelUri = String.Empty; |
459 | } | 464 | } |
460 | else | 465 | else |
@@ -469,8 +474,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
469 | parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); | 474 | parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); |
470 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); | 475 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); |
471 | 476 | ||
472 | m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", | 477 | // m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", |
473 | scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); | 478 | // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); |
474 | return r; | 479 | return r; |
475 | } | 480 | } |
476 | catch (Exception e) | 481 | catch (Exception e) |
@@ -502,6 +507,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
502 | 507 | ||
503 | m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", | 508 | m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", |
504 | avatarName, request, path, param); | 509 | avatarName, request, path, param); |
510 | |||
505 | return "<llsd>true</llsd>"; | 511 | return "<llsd>true</llsd>"; |
506 | } | 512 | } |
507 | 513 | ||
@@ -555,10 +561,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
555 | return response; | 561 | return response; |
556 | } | 562 | } |
557 | 563 | ||
558 | |||
559 | public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) | 564 | public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) |
560 | { | 565 | { |
561 | m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called"); | 566 | m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceGetPreloginHTTPHandler called"); |
562 | 567 | ||
563 | Hashtable response = new Hashtable(); | 568 | Hashtable response = new Hashtable(); |
564 | response["content_type"] = "text/xml"; | 569 | response["content_type"] = "text/xml"; |
@@ -592,6 +597,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
592 | 597 | ||
593 | public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) | 598 | public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) |
594 | { | 599 | { |
600 | m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceBuddyHTTPHandler called"); | ||
601 | |||
595 | Hashtable response = new Hashtable(); | 602 | Hashtable response = new Hashtable(); |
596 | response["int_response_code"] = 200; | 603 | response["int_response_code"] = 200; |
597 | response["str_response_string"] = string.Empty; | 604 | response["str_response_string"] = string.Empty; |
@@ -650,21 +657,64 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
650 | <bdy_status>A</bdy_status> | 657 | <bdy_status>A</bdy_status> |
651 | <modified_ts>{3}</modified_ts> | 658 | <modified_ts>{3}</modified_ts> |
652 | <b2g_group_id></b2g_group_id> | 659 | <b2g_group_id></b2g_group_id> |
653 | </level3>", ids[i],i,m_freeSwitchRealm,dt)); | 660 | </level3>", ids[i], i ,m_freeSwitchRealm, dt)); |
654 | } | 661 | } |
655 | 662 | ||
656 | resp.Append("</buddies><groups></groups></body></level0></response>"); | 663 | resp.Append("</buddies><groups></groups></body></level0></response>"); |
657 | 664 | ||
658 | response["str_response_string"] = resp.ToString(); | 665 | response["str_response_string"] = resp.ToString(); |
659 | // Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); | 666 | // Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); |
660 | 667 | // | |
661 | //m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); | 668 | // m_log.DebugFormat( |
669 | // "[FREESWITCH]: FreeSwitchSLVoiceBuddyHTTPHandler() response {0}", | ||
670 | // normalizeEndLines.Replace((string)response["str_response_string"],"")); | ||
671 | |||
662 | return response; | 672 | return response; |
663 | } | 673 | } |
664 | 674 | ||
675 | public Hashtable FreeSwitchSLVoiceWatcherHTTPHandler(Hashtable request) | ||
676 | { | ||
677 | m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceWatcherHTTPHandler called"); | ||
678 | |||
679 | Hashtable response = new Hashtable(); | ||
680 | response["int_response_code"] = 200; | ||
681 | response["content-type"] = "text/xml"; | ||
682 | |||
683 | Hashtable requestBody = ParseRequestBody((string)request["body"]); | ||
684 | |||
685 | string auth_token = (string)requestBody["auth_token"]; | ||
686 | //string[] auth_tokenvals = auth_token.Split(':'); | ||
687 | //string username = auth_tokenvals[0]; | ||
688 | |||
689 | StringBuilder resp = new StringBuilder(); | ||
690 | resp.Append("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?><response xmlns=\"http://www.vivox.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation= \"/xsd/buddy_list.xsd\">"); | ||
691 | |||
692 | // FIXME: This is enough of a response to stop viewer 2 complaining about a login failure and get voice to work. If we don't | ||
693 | // give an OK response, then viewer 2 engages in an continuous viv_signin.php, viv_buddy.php, viv_watcher.php loop | ||
694 | // Viewer 1 appeared happy to ignore the lack of reply and still works with this reply. | ||
695 | // | ||
696 | // However, really we need to fill in whatever watcher data should be here (whatever that is). | ||
697 | resp.Append(string.Format(@"<level0> | ||
698 | <status>OK</status> | ||
699 | <cookie_name>lib_session</cookie_name> | ||
700 | <cookie>{0}</cookie> | ||
701 | <auth_token>{0}</auth_token> | ||
702 | <body/></level0></response>", auth_token)); | ||
703 | |||
704 | response["str_response_string"] = resp.ToString(); | ||
705 | |||
706 | // Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); | ||
707 | // | ||
708 | // m_log.DebugFormat( | ||
709 | // "[FREESWITCH]: FreeSwitchSLVoiceWatcherHTTPHandler() response {0}", | ||
710 | // normalizeEndLines.Replace((string)response["str_response_string"],"")); | ||
711 | |||
712 | return response; | ||
713 | } | ||
714 | |||
665 | public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) | 715 | public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) |
666 | { | 716 | { |
667 | m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); | 717 | m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceSigninHTTPHandler called"); |
668 | // string requestbody = (string)request["body"]; | 718 | // string requestbody = (string)request["body"]; |
669 | // string uri = (string)request["uri"]; | 719 | // string uri = (string)request["uri"]; |
670 | // string contenttype = (string)request["content-type"]; | 720 | // string contenttype = (string)request["content-type"]; |
@@ -709,7 +759,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
709 | </level0> | 759 | </level0> |
710 | </response>", userid, pos, avatarName); | 760 | </response>", userid, pos, avatarName); |
711 | 761 | ||
712 | response["int_response_code"] = 200; | 762 | response["int_response_code"] = 200; |
763 | |||
764 | // m_log.DebugFormat("[FreeSwitchVoice]: Sending FreeSwitchSLVoiceSigninHTTPHandler response"); | ||
765 | |||
713 | return response; | 766 | return response; |
714 | } | 767 | } |
715 | 768 | ||
@@ -795,16 +848,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
795 | response["keepalive"] = false; | 848 | response["keepalive"] = false; |
796 | response["int_response_code"] = 500; | 849 | response["int_response_code"] = 500; |
797 | 850 | ||
798 | Hashtable requestBody = ParseRequestBody((string) request["body"]); | 851 | Hashtable requestBody = ParseRequestBody((string)request["body"]); |
799 | 852 | ||
800 | string section = (string) requestBody["section"]; | 853 | string section = (string) requestBody["section"]; |
801 | 854 | ||
802 | if (section == "directory") | 855 | if (section == "directory") |
856 | { | ||
857 | string eventCallingFunction = (string)requestBody["Event-Calling-Function"]; | ||
858 | m_log.DebugFormat( | ||
859 | "[FreeSwitchVoice]: Received request for config section directory, event calling function '{0}'", | ||
860 | eventCallingFunction); | ||
861 | |||
803 | response = m_FreeswitchService.HandleDirectoryRequest(requestBody); | 862 | response = m_FreeswitchService.HandleDirectoryRequest(requestBody); |
863 | } | ||
804 | else if (section == "dialplan") | 864 | else if (section == "dialplan") |
865 | { | ||
866 | m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section dialplan"); | ||
867 | |||
805 | response = m_FreeswitchService.HandleDialplanRequest(requestBody); | 868 | response = m_FreeswitchService.HandleDialplanRequest(requestBody); |
869 | } | ||
806 | else | 870 | else |
807 | m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); | 871 | m_log.WarnFormat("[FreeSwitchVoice]: Unknown section {0} was requested from config.", section); |
808 | 872 | ||
809 | return response; | 873 | return response; |
810 | } | 874 | } |
@@ -821,4 +885,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
821 | 885 | ||
822 | #endregion | 886 | #endregion |
823 | } | 887 | } |
824 | } | 888 | } \ No newline at end of file |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 96760a2..2504e30 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -786,18 +786,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
786 | { | 786 | { |
787 | } | 787 | } |
788 | 788 | ||
789 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, | 789 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
790 | uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, | ||
791 | uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, | ||
792 | UUID LastOwnerID, string ObjectName, string Description) | ||
793 | { | 790 | { |
791 | |||
794 | } | 792 | } |
795 | 793 | ||
796 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, | 794 | public void SendObjectPropertiesReply(ISceneEntity entity) |
797 | UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, | ||
798 | UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, | ||
799 | string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, | ||
800 | uint BaseMask, byte saleType, int salePrice) | ||
801 | { | 795 | { |
802 | } | 796 | } |
803 | 797 | ||
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs index 85e34c1..6df213d 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs | |||
@@ -648,6 +648,9 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin | |||
648 | if (pbs.ProfileHollow != 0) | 648 | if (pbs.ProfileHollow != 0) |
649 | iPropertiesNotSupportedDefault++; | 649 | iPropertiesNotSupportedDefault++; |
650 | 650 | ||
651 | if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) | ||
652 | iPropertiesNotSupportedDefault++; | ||
653 | |||
651 | if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) | 654 | if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) |
652 | iPropertiesNotSupportedDefault++; | 655 | iPropertiesNotSupportedDefault++; |
653 | 656 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 211a0a7..64774d8 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -84,10 +84,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
84 | public Meshmerizer(IConfigSource config) | 84 | public Meshmerizer(IConfigSource config) |
85 | { | 85 | { |
86 | IConfig start_config = config.Configs["Startup"]; | 86 | IConfig start_config = config.Configs["Startup"]; |
87 | IConfig mesh_config = config.Configs["Mesh"]; | ||
87 | 88 | ||
88 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); | 89 | decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); |
89 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); | 90 | cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); |
90 | useMeshiesPhysicsMesh = start_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); | 91 | useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); |
91 | 92 | ||
92 | try | 93 | try |
93 | { | 94 | { |
diff --git a/OpenSim/Region/Physics/Meshing/SculptMap.cs b/OpenSim/Region/Physics/Meshing/SculptMap.cs index d2d71de..740424e 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMap.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMap.cs | |||
@@ -62,6 +62,8 @@ namespace PrimMesher | |||
62 | 62 | ||
63 | bool needsScaling = false; | 63 | bool needsScaling = false; |
64 | 64 | ||
65 | bool smallMap = bmW * bmH <= lod * lod; | ||
66 | |||
65 | width = bmW; | 67 | width = bmW; |
66 | height = bmH; | 68 | height = bmH; |
67 | while (width * height > numLodPixels) | 69 | while (width * height > numLodPixels) |
@@ -104,9 +106,14 @@ namespace PrimMesher | |||
104 | { | 106 | { |
105 | for (int x = 0; x <= width; x++) | 107 | for (int x = 0; x <= width; x++) |
106 | { | 108 | { |
107 | int bmY = y < height ? y * 2 : y * 2 - 1; | 109 | Color c; |
108 | int bmX = x < width ? x * 2 : x * 2 - 1; | 110 | |
109 | Color c = bm.GetPixel(bmX, bmY); | 111 | if (smallMap) |
112 | c = bm.GetPixel(x < width ? x : x - 1, | ||
113 | y < height ? y : y - 1); | ||
114 | else | ||
115 | c = bm.GetPixel(x < width ? x * 2 : x * 2 - 1, | ||
116 | y < height ? y * 2 : y * 2 - 1); | ||
110 | 117 | ||
111 | redBytes[byteNdx] = c.R; | 118 | redBytes[byteNdx] = c.R; |
112 | greenBytes[byteNdx] = c.G; | 119 | greenBytes[byteNdx] = c.G; |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index eb97f41..a0101af 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -2528,6 +2528,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2528 | if (pbs.ProfileHollow != 0) | 2528 | if (pbs.ProfileHollow != 0) |
2529 | iPropertiesNotSupportedDefault++; | 2529 | iPropertiesNotSupportedDefault++; |
2530 | 2530 | ||
2531 | if ((pbs.PathBegin != 0) || pbs.PathEnd != 0) | ||
2532 | iPropertiesNotSupportedDefault++; | ||
2533 | |||
2531 | if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) | 2534 | if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) |
2532 | iPropertiesNotSupportedDefault++; | 2535 | iPropertiesNotSupportedDefault++; |
2533 | 2536 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c16a985..aa28fa0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -10289,12 +10289,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10289 | { | 10289 | { |
10290 | UUID rq = UUID.Random(); | 10290 | UUID rq = UUID.Random(); |
10291 | 10291 | ||
10292 | UUID tid = AsyncCommands. | 10292 | AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); |
10293 | DataserverPlugin.RegisterRequest(m_localID, | ||
10294 | m_itemID, rq.ToString()); | ||
10295 | 10293 | ||
10296 | AsyncCommands. | 10294 | AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); |
10297 | DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); | ||
10298 | 10295 | ||
10299 | return rq.ToString(); | 10296 | return rq.ToString(); |
10300 | } | 10297 | } |
@@ -10308,12 +10305,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10308 | { | 10305 | { |
10309 | UUID rq = UUID.Random(); | 10306 | UUID rq = UUID.Random(); |
10310 | 10307 | ||
10311 | UUID tid = AsyncCommands. | 10308 | AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); |
10312 | DataserverPlugin.RegisterRequest(m_localID, | ||
10313 | m_itemID, rq.ToString()); | ||
10314 | 10309 | ||
10315 | AsyncCommands. | 10310 | AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); |
10316 | DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); | ||
10317 | 10311 | ||
10318 | return rq.ToString(); | 10312 | return rq.ToString(); |
10319 | } | 10313 | } |
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index a81af43..e1f90b6 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs | |||
@@ -89,6 +89,8 @@ namespace OpenSim.Services.AssetService | |||
89 | 89 | ||
90 | public virtual AssetBase Get(string id) | 90 | public virtual AssetBase Get(string id) |
91 | { | 91 | { |
92 | // m_log.DebugFormat("[ASSET SERVICE]: Get asset for {0}", id); | ||
93 | |||
92 | UUID assetID; | 94 | UUID assetID; |
93 | 95 | ||
94 | if (!UUID.TryParse(id, out assetID)) | 96 | if (!UUID.TryParse(id, out assetID)) |
@@ -107,6 +109,8 @@ namespace OpenSim.Services.AssetService | |||
107 | 109 | ||
108 | public virtual AssetMetadata GetMetadata(string id) | 110 | public virtual AssetMetadata GetMetadata(string id) |
109 | { | 111 | { |
112 | // m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id); | ||
113 | |||
110 | UUID assetID; | 114 | UUID assetID; |
111 | 115 | ||
112 | if (!UUID.TryParse(id, out assetID)) | 116 | if (!UUID.TryParse(id, out assetID)) |
@@ -121,6 +125,8 @@ namespace OpenSim.Services.AssetService | |||
121 | 125 | ||
122 | public virtual byte[] GetData(string id) | 126 | public virtual byte[] GetData(string id) |
123 | { | 127 | { |
128 | // m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id); | ||
129 | |||
124 | UUID assetID; | 130 | UUID assetID; |
125 | 131 | ||
126 | if (!UUID.TryParse(id, out assetID)) | 132 | if (!UUID.TryParse(id, out assetID)) |
@@ -150,7 +156,9 @@ namespace OpenSim.Services.AssetService | |||
150 | 156 | ||
151 | public virtual string Store(AssetBase asset) | 157 | public virtual string Store(AssetBase asset) |
152 | { | 158 | { |
153 | //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); | 159 | // m_log.DebugFormat( |
160 | // "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.ID, asset.Data.Length); | ||
161 | |||
154 | m_Database.StoreAsset(asset); | 162 | m_Database.StoreAsset(asset); |
155 | 163 | ||
156 | return asset.ID; | 164 | return asset.ID; |
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index 65b3537..f1da4fa 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | |||
@@ -34,7 +34,6 @@ using Nini.Config; | |||
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Console; | 35 | using OpenSim.Framework.Console; |
36 | using OpenSim.Framework.Communications; | 36 | using OpenSim.Framework.Communications; |
37 | using OpenSim.Framework.Servers.HttpServer; | ||
38 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
39 | using OpenMetaverse; | 38 | using OpenMetaverse; |
40 | 39 | ||
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs index 6f77a2d..c04e7a4 100644 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using OpenSim.Server.Base; | 37 | using OpenSim.Server.Base; |
39 | using OpenMetaverse; | 38 | using OpenMetaverse; |
diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs index 4eb4bd2..35b7109 100644 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using OpenMetaverse; | 37 | using OpenMetaverse; |
39 | 38 | ||
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs index 1cd6bf8..1a93ae7 100644 --- a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 37 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
39 | using IAvatarService = OpenSim.Services.Interfaces.IAvatarService; | 38 | using IAvatarService = OpenSim.Services.Interfaces.IAvatarService; |
diff --git a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs index c9bba0b..d688299 100644 --- a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs +++ b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using OpenSim.Server.Base; | 37 | using OpenSim.Server.Base; |
39 | using OpenMetaverse; | 38 | using OpenMetaverse; |
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index 36b5083..861c475 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; | 37 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; |
39 | using OpenSim.Server.Base; | 38 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs index 0a7b277..4ffa68c 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs | |||
@@ -32,7 +32,7 @@ using System.Reflection; | |||
32 | using OpenSim.Services.Interfaces; | 32 | using OpenSim.Services.Interfaces; |
33 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 33 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
34 | using OpenSim.Server.Base; | 34 | using OpenSim.Server.Base; |
35 | using OpenSim.Framework.Servers.HttpServer; | 35 | using OpenSim.Framework; |
36 | 36 | ||
37 | using OpenMetaverse; | 37 | using OpenMetaverse; |
38 | using log4net; | 38 | using log4net; |
diff --git a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs index 5092d74..e57f28b 100644 --- a/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 37 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
39 | using OpenSim.Server.Base; | 38 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs index b3ea865..738cc06 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 37 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
39 | using OpenSim.Server.Base; | 38 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index b3bfcc2..cd9f2bf 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs | |||
@@ -34,7 +34,6 @@ using Nini.Config; | |||
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Console; | 35 | using OpenSim.Framework.Console; |
36 | using OpenSim.Framework.Communications; | 36 | using OpenSim.Framework.Communications; |
37 | using OpenSim.Framework.Servers.HttpServer; | ||
38 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
39 | using OpenSim.Server.Base; | 38 | using OpenSim.Server.Base; |
40 | using OpenMetaverse; | 39 | using OpenMetaverse; |
diff --git a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs index 252f7a1..30a73a4 100644 --- a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs +++ b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs | |||
@@ -34,7 +34,6 @@ using System.Reflection; | |||
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Communications; | 36 | using OpenSim.Framework.Communications; |
37 | using OpenSim.Framework.Servers.HttpServer; | ||
38 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
39 | using OpenMetaverse; | 38 | using OpenMetaverse; |
40 | using Nwc.XmlRpc; | 39 | using Nwc.XmlRpc; |
diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs index 9e444c4..2cae02d 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs | |||
@@ -36,7 +36,6 @@ using System.Text; | |||
36 | using Nini.Config; | 36 | using Nini.Config; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Communications; | 38 | using OpenSim.Framework.Communications; |
39 | using OpenSim.Framework.Servers.HttpServer; | ||
40 | using OpenSim.Services.Interfaces; | 39 | using OpenSim.Services.Interfaces; |
41 | using OpenMetaverse; | 40 | using OpenMetaverse; |
42 | using OpenMetaverse.StructuredData; | 41 | using OpenMetaverse.StructuredData; |
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs index 41ebeaf..7238afc 100644 --- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | 37 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; |
39 | using OpenSim.Server.Base; | 38 | using OpenSim.Server.Base; |
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs index 2a5df83..f6835b9 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs | |||
@@ -33,7 +33,6 @@ using System.Reflection; | |||
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications; | 35 | using OpenSim.Framework.Communications; |
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Server.Base; | 36 | using OpenSim.Server.Base; |
38 | using OpenSim.Services.Interfaces; | 37 | using OpenSim.Services.Interfaces; |
39 | using OpenMetaverse; | 38 | using OpenMetaverse; |
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs index fe6f5cd..c3f1056 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs | |||
@@ -50,13 +50,13 @@ namespace OpenSim.Services.FreeswitchService | |||
50 | 50 | ||
51 | public Hashtable HandleDialplanRequest(Hashtable request) | 51 | public Hashtable HandleDialplanRequest(Hashtable request) |
52 | { | 52 | { |
53 | m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); | 53 | m_log.DebugFormat("[FreeSwitchVoice]: HandleDialplanRequest called with {0}",request.ToString()); |
54 | 54 | ||
55 | Hashtable response = new Hashtable(); | 55 | Hashtable response = new Hashtable(); |
56 | 56 | ||
57 | foreach (DictionaryEntry item in request) | 57 | foreach (DictionaryEntry item in request) |
58 | { | 58 | { |
59 | m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); | 59 | // m_log.InfoFormat("[FreeSwitchDirectory]: requestBody item {0} {1}",item.Key, item.Value); |
60 | } | 60 | } |
61 | 61 | ||
62 | string requestcontext = (string) request["Hunt-Context"]; | 62 | string requestcontext = (string) request["Hunt-Context"]; |
@@ -66,7 +66,7 @@ namespace OpenSim.Services.FreeswitchService | |||
66 | 66 | ||
67 | if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext) | 67 | if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext) |
68 | { | 68 | { |
69 | m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); | 69 | m_log.Debug("[FreeSwitchDirectory]: returning empty as it's for another context"); |
70 | response["str_response_string"] = ""; | 70 | response["str_response_string"] = ""; |
71 | } | 71 | } |
72 | else | 72 | else |
@@ -116,13 +116,16 @@ namespace OpenSim.Services.FreeswitchService | |||
116 | { | 116 | { |
117 | Hashtable response = new Hashtable(); | 117 | Hashtable response = new Hashtable(); |
118 | string domain = (string) request["domain"]; | 118 | string domain = (string) request["domain"]; |
119 | if (domain != m_freeSwitchRealm) { | 119 | if (domain != m_freeSwitchRealm) |
120 | { | ||
120 | response["content_type"] = "text/xml"; | 121 | response["content_type"] = "text/xml"; |
121 | response["keepalive"] = false; | 122 | response["keepalive"] = false; |
122 | response["int_response_code"] = 200; | 123 | response["int_response_code"] = 200; |
123 | response["str_response_string"] = ""; | 124 | response["str_response_string"] = ""; |
124 | } else { | 125 | } |
125 | m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); | 126 | else |
127 | { | ||
128 | // m_log.DebugFormat("[FreeSwitchDirectory]: HandleDirectoryRequest called with {0}",request.ToString()); | ||
126 | 129 | ||
127 | // information in the request we might be interested in | 130 | // information in the request we might be interested in |
128 | 131 | ||
@@ -143,10 +146,8 @@ namespace OpenSim.Services.FreeswitchService | |||
143 | //domain=9.20.151.43 | 146 | //domain=9.20.151.43 |
144 | //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup | 147 | //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup |
145 | 148 | ||
146 | foreach (DictionaryEntry item in request) | 149 | // foreach (DictionaryEntry item in request) |
147 | { | 150 | // m_log.DebugFormat("[FreeSwitchDirectory]: requestBody item {0} {1}", item.Key, item.Value); |
148 | m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); | ||
149 | } | ||
150 | 151 | ||
151 | string eventCallingFunction = (string) request["Event-Calling-Function"]; | 152 | string eventCallingFunction = (string) request["Event-Calling-Function"]; |
152 | if (eventCallingFunction == null) | 153 | if (eventCallingFunction == null) |
@@ -173,7 +174,7 @@ namespace OpenSim.Services.FreeswitchService | |||
173 | } | 174 | } |
174 | else | 175 | else |
175 | { | 176 | { |
176 | m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); | 177 | m_log.ErrorFormat("[FreeSwitchVoice]: HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); |
177 | response["int_response_code"] = 404; | 178 | response["int_response_code"] = 404; |
178 | response["content_type"] = "text/xml"; | 179 | response["content_type"] = "text/xml"; |
179 | response["str_response_string"] = ""; | 180 | response["str_response_string"] = ""; |
@@ -205,7 +206,7 @@ namespace OpenSim.Services.FreeswitchService | |||
205 | } | 206 | } |
206 | else | 207 | else |
207 | { | 208 | { |
208 | m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); | 209 | m_log.ErrorFormat("[FreeSwitchVoice]: HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); |
209 | response["int_response_code"] = 404; | 210 | response["int_response_code"] = 404; |
210 | response["keepalive"] = false; | 211 | response["keepalive"] = false; |
211 | response["content_type"] = "text/xml"; | 212 | response["content_type"] = "text/xml"; |
@@ -217,7 +218,7 @@ namespace OpenSim.Services.FreeswitchService | |||
217 | 218 | ||
218 | private Hashtable HandleRegister(string Context, string Realm, Hashtable request) | 219 | private Hashtable HandleRegister(string Context, string Realm, Hashtable request) |
219 | { | 220 | { |
220 | m_log.Info("[FreeSwitchDirectory] HandleRegister called"); | 221 | m_log.Info("[FreeSwitchDirectory]: HandleRegister called"); |
221 | 222 | ||
222 | // TODO the password we return needs to match that sent in the request, this is hard coded for now | 223 | // TODO the password we return needs to match that sent in the request, this is hard coded for now |
223 | string password = "1234"; | 224 | string password = "1234"; |
@@ -254,7 +255,7 @@ namespace OpenSim.Services.FreeswitchService | |||
254 | 255 | ||
255 | private Hashtable HandleInvite(string Context, string Realm, Hashtable request) | 256 | private Hashtable HandleInvite(string Context, string Realm, Hashtable request) |
256 | { | 257 | { |
257 | m_log.Info("[FreeSwitchDirectory] HandleInvite called"); | 258 | m_log.Info("[FreeSwitchDirectory]: HandleInvite called"); |
258 | 259 | ||
259 | // TODO the password we return needs to match that sent in the request, this is hard coded for now | 260 | // TODO the password we return needs to match that sent in the request, this is hard coded for now |
260 | string password = "1234"; | 261 | string password = "1234"; |
@@ -301,7 +302,7 @@ namespace OpenSim.Services.FreeswitchService | |||
301 | 302 | ||
302 | private Hashtable HandleLocateUser(String Realm, Hashtable request) | 303 | private Hashtable HandleLocateUser(String Realm, Hashtable request) |
303 | { | 304 | { |
304 | m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); | 305 | m_log.Info("[FreeSwitchDirectory]: HandleLocateUser called"); |
305 | 306 | ||
306 | // TODO the password we return needs to match that sent in the request, this is hard coded for now | 307 | // TODO the password we return needs to match that sent in the request, this is hard coded for now |
307 | string domain = (string) request["domain"]; | 308 | string domain = (string) request["domain"]; |
@@ -335,7 +336,7 @@ namespace OpenSim.Services.FreeswitchService | |||
335 | 336 | ||
336 | private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) | 337 | private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) |
337 | { | 338 | { |
338 | m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); | 339 | m_log.Info("[FreeSwitchDirectory]: HandleConfigSofia called."); |
339 | 340 | ||
340 | // TODO the password we return needs to match that sent in the request, this is hard coded for now | 341 | // TODO the password we return needs to match that sent in the request, this is hard coded for now |
341 | string domain = (string) request["domain"]; | 342 | string domain = (string) request["domain"]; |
diff --git a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs index ebbb1b0..25c18b6 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs | |||
@@ -64,7 +64,7 @@ namespace OpenSim.Services.FreeswitchService | |||
64 | m_freeSwitchDefaultWellKnownIP = freeswitchConfig.GetString("ServerAddress", String.Empty); | 64 | m_freeSwitchDefaultWellKnownIP = freeswitchConfig.GetString("ServerAddress", String.Empty); |
65 | if (m_freeSwitchDefaultWellKnownIP == String.Empty) | 65 | if (m_freeSwitchDefaultWellKnownIP == String.Empty) |
66 | { | 66 | { |
67 | m_log.Error("[FREESWITCH]: No FreeswitchServerAddress given, can't continue"); | 67 | m_log.Error("[FREESWITCH]: No ServerAddress given, cannot start service."); |
68 | return; | 68 | return; |
69 | } | 69 | } |
70 | 70 | ||
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs index 3be6815..1ac1cec 100644 --- a/OpenSim/Services/Interfaces/IAssetService.cs +++ b/OpenSim/Services/Interfaces/IAssetService.cs | |||
@@ -48,6 +48,11 @@ namespace OpenSim.Services.Interfaces | |||
48 | /// <returns></returns> | 48 | /// <returns></returns> |
49 | AssetMetadata GetMetadata(string id); | 49 | AssetMetadata GetMetadata(string id); |
50 | 50 | ||
51 | /// <summary> | ||
52 | /// Get an asset's data, ignoring the metadata. | ||
53 | /// </summary> | ||
54 | /// <param name="id"></param> | ||
55 | /// <returns>null if there is no such asset</returns> | ||
51 | byte[] GetData(string id); | 56 | byte[] GetData(string id); |
52 | 57 | ||
53 | /// <summary> | 58 | /// <summary> |
diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs index d19faed..a8bfe47 100644 --- a/OpenSim/Services/Interfaces/IInventoryService.cs +++ b/OpenSim/Services/Interfaces/IInventoryService.cs | |||
@@ -169,7 +169,7 @@ namespace OpenSim.Services.Interfaces | |||
169 | /// Get an item, given by its UUID | 169 | /// Get an item, given by its UUID |
170 | /// </summary> | 170 | /// </summary> |
171 | /// <param name="item"></param> | 171 | /// <param name="item"></param> |
172 | /// <returns></returns> | 172 | /// <returns>null if no item was found, otherwise the found item</returns> |
173 | InventoryItemBase GetItem(InventoryItemBase item); | 173 | InventoryItemBase GetItem(InventoryItemBase item); |
174 | 174 | ||
175 | /// <summary> | 175 | /// <summary> |
diff --git a/OpenSim/Tests/Common/Mock/MockAssetService.cs b/OpenSim/Tests/Common/Mock/MockAssetService.cs deleted file mode 100644 index 4118308..0000000 --- a/OpenSim/Tests/Common/Mock/MockAssetService.cs +++ /dev/null | |||
@@ -1,109 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Data; | ||
35 | using OpenSim.Services.Interfaces; | ||
36 | using Nini.Config; | ||
37 | |||
38 | namespace OpenSim.Tests.Common.Mock | ||
39 | { | ||
40 | public class MockAssetService : IAssetService | ||
41 | { | ||
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
43 | |||
44 | private readonly Dictionary<string, AssetBase> Assets = new Dictionary<string, AssetBase>(); | ||
45 | |||
46 | public MockAssetService() {} | ||
47 | |||
48 | /// <summary> | ||
49 | /// This constructor is required if the asset service is being created reflectively (which is the case in some | ||
50 | /// tests). | ||
51 | /// </summary> | ||
52 | /// <param name="config"></param> | ||
53 | public MockAssetService(IConfigSource config) {} | ||
54 | |||
55 | public AssetBase Get(string id) | ||
56 | { | ||
57 | m_log.DebugFormat("[MOCK ASSET SERVICE]: Getting asset with id {0}", id); | ||
58 | |||
59 | AssetBase asset; | ||
60 | if (Assets.ContainsKey(id)) | ||
61 | asset = Assets[id]; | ||
62 | else | ||
63 | asset = null; | ||
64 | |||
65 | return asset; | ||
66 | } | ||
67 | |||
68 | public AssetBase GetCached(string id) | ||
69 | { | ||
70 | return Get(id); | ||
71 | } | ||
72 | |||
73 | public AssetMetadata GetMetadata(string id) | ||
74 | { | ||
75 | throw new System.NotImplementedException(); | ||
76 | } | ||
77 | |||
78 | public byte[] GetData(string id) | ||
79 | { | ||
80 | throw new System.NotImplementedException(); | ||
81 | } | ||
82 | |||
83 | public bool Get(string id, object sender, AssetRetrieved handler) | ||
84 | { | ||
85 | handler(id, sender, Get(id)); | ||
86 | |||
87 | return true; | ||
88 | } | ||
89 | |||
90 | public string Store(AssetBase asset) | ||
91 | { | ||
92 | m_log.DebugFormat("[MOCK ASSET SERVICE]: Storing asset {0}", asset.ID); | ||
93 | |||
94 | Assets[asset.ID] = asset; | ||
95 | |||
96 | return asset.ID; | ||
97 | } | ||
98 | |||
99 | public bool UpdateContent(string id, byte[] data) | ||
100 | { | ||
101 | throw new System.NotImplementedException(); | ||
102 | } | ||
103 | |||
104 | public bool Delete(string id) | ||
105 | { | ||
106 | throw new System.NotImplementedException(); | ||
107 | } | ||
108 | } | ||
109 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tests/Common/Mock/MockInventoryService.cs b/OpenSim/Tests/Common/Mock/MockInventoryService.cs deleted file mode 100644 index 4ac1078..0000000 --- a/OpenSim/Tests/Common/Mock/MockInventoryService.cs +++ /dev/null | |||
@@ -1,186 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Services.Interfaces; | ||
34 | using Nini.Config; | ||
35 | |||
36 | namespace OpenSim.Tests.Common.Mock | ||
37 | { | ||
38 | public class MockInventoryService : IInventoryService | ||
39 | { | ||
40 | public MockInventoryService() {} | ||
41 | |||
42 | public MockInventoryService(IConfigSource config) {} | ||
43 | |||
44 | /// <summary> | ||
45 | /// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/> | ||
46 | /// </summary> | ||
47 | /// <param name="userId"></param> | ||
48 | /// <returns></returns> | ||
49 | public bool CreateUserInventory(UUID userId) | ||
50 | { | ||
51 | return false; | ||
52 | } | ||
53 | |||
54 | /// <summary> | ||
55 | /// <see cref="OpenSim.Framework.Communications.IInterServiceInventoryServices"/> | ||
56 | /// </summary> | ||
57 | /// <param name="userId"></param> | ||
58 | /// <returns></returns> | ||
59 | public List<InventoryFolderBase> GetInventorySkeleton(UUID userId) | ||
60 | { | ||
61 | List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); | ||
62 | InventoryFolderBase folder = new InventoryFolderBase(); | ||
63 | folder.ID = UUID.Random(); | ||
64 | folder.Owner = userId; | ||
65 | folders.Add(folder); | ||
66 | return folders; | ||
67 | } | ||
68 | |||
69 | public InventoryFolderBase GetRootFolder(UUID userID) | ||
70 | { | ||
71 | return new InventoryFolderBase(); | ||
72 | } | ||
73 | |||
74 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) | ||
75 | { | ||
76 | return null; | ||
77 | } | ||
78 | |||
79 | public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) | ||
80 | { | ||
81 | return null; | ||
82 | } | ||
83 | |||
84 | /// <summary> | ||
85 | /// Returns a list of all the active gestures in a user's inventory. | ||
86 | /// </summary> | ||
87 | /// <param name="userId"> | ||
88 | /// The <see cref="UUID"/> of the user | ||
89 | /// </param> | ||
90 | /// <returns> | ||
91 | /// A flat list of the gesture items. | ||
92 | /// </returns> | ||
93 | public List<InventoryItemBase> GetActiveGestures(UUID userId) | ||
94 | { | ||
95 | return null; | ||
96 | } | ||
97 | |||
98 | public InventoryCollection GetUserInventory(UUID userID) | ||
99 | { | ||
100 | return null; | ||
101 | } | ||
102 | |||
103 | public void GetUserInventory(UUID userID, OpenSim.Services.Interfaces.InventoryReceiptCallback callback) | ||
104 | { | ||
105 | } | ||
106 | |||
107 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | ||
108 | { | ||
109 | return null; | ||
110 | } | ||
111 | |||
112 | public bool AddFolder(InventoryFolderBase folder) | ||
113 | { | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | public bool UpdateFolder(InventoryFolderBase folder) | ||
118 | { | ||
119 | return false; | ||
120 | } | ||
121 | |||
122 | public bool MoveFolder(InventoryFolderBase folder) | ||
123 | { | ||
124 | return false; | ||
125 | } | ||
126 | |||
127 | public bool DeleteFolders(UUID ownerID, List<UUID> ids) | ||
128 | { | ||
129 | return false; | ||
130 | } | ||
131 | |||
132 | public bool PurgeFolder(InventoryFolderBase folder) | ||
133 | { | ||
134 | return false; | ||
135 | } | ||
136 | |||
137 | public bool AddItem(InventoryItemBase item) | ||
138 | { | ||
139 | return true; | ||
140 | } | ||
141 | |||
142 | public bool UpdateItem(InventoryItemBase item) | ||
143 | { | ||
144 | return false; | ||
145 | } | ||
146 | |||
147 | public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) | ||
148 | { | ||
149 | return false; | ||
150 | } | ||
151 | |||
152 | public bool DeleteItems(UUID ownerID, List<UUID> itemIDs) | ||
153 | { | ||
154 | return false; | ||
155 | } | ||
156 | |||
157 | public InventoryItemBase GetItem(InventoryItemBase item) | ||
158 | { | ||
159 | return null; | ||
160 | } | ||
161 | |||
162 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | ||
163 | { | ||
164 | return null; | ||
165 | } | ||
166 | |||
167 | public bool HasInventoryForUser(UUID userID) | ||
168 | { | ||
169 | return false; | ||
170 | } | ||
171 | |||
172 | public InventoryFolderBase RequestRootFolder(UUID userID) | ||
173 | { | ||
174 | InventoryFolderBase root = new InventoryFolderBase(); | ||
175 | root.ID = UUID.Random(); | ||
176 | root.Owner = userID; | ||
177 | root.ParentID = UUID.Zero; | ||
178 | return root; | ||
179 | } | ||
180 | |||
181 | public int GetAssetPermissions(UUID userID, UUID assetID) | ||
182 | { | ||
183 | return 1; | ||
184 | } | ||
185 | } | ||
186 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index d1dc17f..dca5626 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs | |||
@@ -816,18 +816,11 @@ namespace OpenSim.Tests.Common.Mock | |||
816 | { | 816 | { |
817 | } | 817 | } |
818 | 818 | ||
819 | public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, | 819 | public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) |
820 | uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, | ||
821 | uint NextOwnerMask, int OwnershipCost, byte SaleType,int SalePrice, uint Category, | ||
822 | UUID LastOwnerID, string ObjectName, string Description) | ||
823 | { | 820 | { |
824 | } | 821 | } |
825 | 822 | ||
826 | public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, | 823 | public void SendObjectPropertiesReply(ISceneEntity entity) |
827 | UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, | ||
828 | UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, | ||
829 | string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, | ||
830 | uint BaseMask, byte saleType, int salePrice) | ||
831 | { | 824 | { |
832 | } | 825 | } |
833 | 826 | ||
diff --git a/OpenSim/Tests/Common/Setup/AssetHelpers.cs b/OpenSim/Tests/Common/Setup/AssetHelpers.cs index ff4423f..d572249 100644 --- a/OpenSim/Tests/Common/Setup/AssetHelpers.cs +++ b/OpenSim/Tests/Common/Setup/AssetHelpers.cs | |||
@@ -30,6 +30,7 @@ using OpenMetaverse; | |||
30 | using OpenSim.Framework; | 30 | using OpenSim.Framework; |
31 | using OpenSim.Region.Framework.Scenes; | 31 | using OpenSim.Region.Framework.Scenes; |
32 | using OpenSim.Region.Framework.Scenes.Serialization; | 32 | using OpenSim.Region.Framework.Scenes.Serialization; |
33 | using OpenSim.Services.Interfaces; | ||
33 | 34 | ||
34 | namespace OpenSim.Tests.Common | 35 | namespace OpenSim.Tests.Common |
35 | { | 36 | { |
@@ -55,7 +56,7 @@ namespace OpenSim.Tests.Common | |||
55 | AssetBase asset = CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); | 56 | AssetBase asset = CreateAsset(UUID.Random(), AssetType.Notecard, "hello", creatorId); |
56 | scene.AssetService.Store(asset); | 57 | scene.AssetService.Store(asset); |
57 | return asset; | 58 | return asset; |
58 | } | 59 | } |
59 | 60 | ||
60 | /// <summary> | 61 | /// <summary> |
61 | /// Create an asset from the given scene object. | 62 | /// Create an asset from the given scene object. |
@@ -71,6 +72,35 @@ namespace OpenSim.Tests.Common | |||
71 | Encoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog)), | 72 | Encoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog)), |
72 | sog.OwnerID); | 73 | sog.OwnerID); |
73 | } | 74 | } |
75 | |||
76 | /// <summary> | ||
77 | /// Create an asset from the given scene object. | ||
78 | /// </summary> | ||
79 | /// <param name="assetUuidTailZ"> | ||
80 | /// The hexadecimal last part of the UUID for the asset created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}" | ||
81 | /// will be used. | ||
82 | /// </param> | ||
83 | /// <param name="coa"></param> | ||
84 | /// <returns></returns> | ||
85 | public static AssetBase CreateAsset(int assetUuidTail, CoalescedSceneObjects coa) | ||
86 | { | ||
87 | return CreateAsset(new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", assetUuidTail)), coa); | ||
88 | } | ||
89 | |||
90 | /// <summary> | ||
91 | /// Create an asset from the given scene object. | ||
92 | /// </summary> | ||
93 | /// <param name="assetUuid"></param> | ||
94 | /// <param name="coa"></param> | ||
95 | /// <returns></returns> | ||
96 | public static AssetBase CreateAsset(UUID assetUuid, CoalescedSceneObjects coa) | ||
97 | { | ||
98 | return CreateAsset( | ||
99 | assetUuid, | ||
100 | AssetType.Object, | ||
101 | Encoding.ASCII.GetBytes(CoalescedSceneObjectsSerializer.ToXml(coa)), | ||
102 | coa.CreatorId); | ||
103 | } | ||
74 | 104 | ||
75 | /// <summary> | 105 | /// <summary> |
76 | /// Create an asset from the given data. | 106 | /// Create an asset from the given data. |
@@ -89,5 +119,11 @@ namespace OpenSim.Tests.Common | |||
89 | asset.Data = data; | 119 | asset.Data = data; |
90 | return asset; | 120 | return asset; |
91 | } | 121 | } |
122 | |||
123 | public static string ReadAssetAsString(IAssetService assetService, UUID uuid) | ||
124 | { | ||
125 | byte[] assetData = assetService.GetData(uuid.ToString()); | ||
126 | return Encoding.ASCII.GetString(assetData); | ||
127 | } | ||
92 | } | 128 | } |
93 | } | 129 | } |
diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index 709dd78..99517d2 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | |||
@@ -66,32 +66,7 @@ namespace OpenSim.Tests.Common.Setup | |||
66 | /// <returns></returns> | 66 | /// <returns></returns> |
67 | public static TestScene SetupScene() | 67 | public static TestScene SetupScene() |
68 | { | 68 | { |
69 | return SetupScene(""); | 69 | return SetupScene("Unit test region", UUID.Random(), 1000, 1000); |
70 | } | ||
71 | |||
72 | /// <summary> | ||
73 | /// Set up a test scene | ||
74 | /// </summary> | ||
75 | /// | ||
76 | /// <param name="realServices">Starts real inventory and asset services, as opposed to mock ones, if true</param> | ||
77 | /// <returns></returns> | ||
78 | public static TestScene SetupScene(String realServices) | ||
79 | { | ||
80 | return SetupScene("Unit test region", UUID.Random(), 1000, 1000, realServices); | ||
81 | } | ||
82 | |||
83 | /// <summary> | ||
84 | /// Set up a test scene | ||
85 | /// </summary> | ||
86 | /// <param name="name">Name of the region</param> | ||
87 | /// <param name="id">ID of the region</param> | ||
88 | /// <param name="x">X co-ordinate of the region</param> | ||
89 | /// <param name="y">Y co-ordinate of the region</param> | ||
90 | /// <param name="cm">This should be the same if simulating two scenes within a standalone</param> | ||
91 | /// <returns></returns> | ||
92 | public static TestScene SetupScene(string name, UUID id, uint x, uint y) | ||
93 | { | ||
94 | return SetupScene(name, id, x, y, ""); | ||
95 | } | 70 | } |
96 | 71 | ||
97 | /// <summary> | 72 | /// <summary> |
@@ -103,10 +78,8 @@ namespace OpenSim.Tests.Common.Setup | |||
103 | /// <param name="x">X co-ordinate of the region</param> | 78 | /// <param name="x">X co-ordinate of the region</param> |
104 | /// <param name="y">Y co-ordinate of the region</param> | 79 | /// <param name="y">Y co-ordinate of the region</param> |
105 | /// <param name="cm">This should be the same if simulating two scenes within a standalone</param> | 80 | /// <param name="cm">This should be the same if simulating two scenes within a standalone</param> |
106 | /// <param name="realServices">Starts real inventory and asset services, as opposed to mock ones, if true</param> | ||
107 | /// <returns></returns> | 81 | /// <returns></returns> |
108 | public static TestScene SetupScene( | 82 | public static TestScene SetupScene(string name, UUID id, uint x, uint y) |
109 | string name, UUID id, uint x, uint y, String realServices) | ||
110 | { | 83 | { |
111 | Console.WriteLine("Setting up test scene {0}", name); | 84 | Console.WriteLine("Setting up test scene {0}", name); |
112 | 85 | ||
@@ -130,15 +103,11 @@ namespace OpenSim.Tests.Common.Setup | |||
130 | IRegionModule godsModule = new GodsModule(); | 103 | IRegionModule godsModule = new GodsModule(); |
131 | godsModule.Initialise(testScene, new IniConfigSource()); | 104 | godsModule.Initialise(testScene, new IniConfigSource()); |
132 | testScene.AddModule(godsModule.Name, godsModule); | 105 | testScene.AddModule(godsModule.Name, godsModule); |
133 | realServices = realServices.ToLower(); | ||
134 | |||
135 | LocalAssetServicesConnector assetService = StartAssetService(testScene, realServices.Contains("asset")); | ||
136 | |||
137 | // For now, always started a 'real' authentication service | ||
138 | StartAuthenticationService(testScene, true); | ||
139 | 106 | ||
140 | LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene, realServices.Contains("inventory")); | 107 | LocalAssetServicesConnector assetService = StartAssetService(testScene); |
141 | StartGridService(testScene, true); | 108 | StartAuthenticationService(testScene); |
109 | LocalInventoryServicesConnector inventoryService = StartInventoryService(testScene); | ||
110 | StartGridService(testScene); | ||
142 | LocalUserAccountServicesConnector userAccountService = StartUserAccountService(testScene); | 111 | LocalUserAccountServicesConnector userAccountService = StartUserAccountService(testScene); |
143 | LocalPresenceServicesConnector presenceService = StartPresenceService(testScene); | 112 | LocalPresenceServicesConnector presenceService = StartPresenceService(testScene); |
144 | 113 | ||
@@ -164,18 +133,17 @@ namespace OpenSim.Tests.Common.Setup | |||
164 | return testScene; | 133 | return testScene; |
165 | } | 134 | } |
166 | 135 | ||
167 | private static LocalAssetServicesConnector StartAssetService(Scene testScene, bool real) | 136 | private static LocalAssetServicesConnector StartAssetService(Scene testScene) |
168 | { | 137 | { |
169 | LocalAssetServicesConnector assetService = new LocalAssetServicesConnector(); | 138 | LocalAssetServicesConnector assetService = new LocalAssetServicesConnector(); |
170 | IConfigSource config = new IniConfigSource(); | 139 | IConfigSource config = new IniConfigSource(); |
171 | config.AddConfig("Modules"); | 140 | |
141 | config.AddConfig("Modules"); | ||
142 | config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector"); | ||
172 | config.AddConfig("AssetService"); | 143 | config.AddConfig("AssetService"); |
173 | config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector"); | 144 | config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); |
174 | if (real) | ||
175 | config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); | ||
176 | else | ||
177 | config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockAssetService"); | ||
178 | config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); | 145 | config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); |
146 | |||
179 | assetService.Initialise(config); | 147 | assetService.Initialise(config); |
180 | assetService.AddRegion(testScene); | 148 | assetService.AddRegion(testScene); |
181 | assetService.RegionLoaded(testScene); | 149 | assetService.RegionLoaded(testScene); |
@@ -184,20 +152,18 @@ namespace OpenSim.Tests.Common.Setup | |||
184 | return assetService; | 152 | return assetService; |
185 | } | 153 | } |
186 | 154 | ||
187 | private static void StartAuthenticationService(Scene testScene, bool real) | 155 | private static void StartAuthenticationService(Scene testScene) |
188 | { | 156 | { |
189 | ISharedRegionModule service = new LocalAuthenticationServicesConnector(); | 157 | ISharedRegionModule service = new LocalAuthenticationServicesConnector(); |
190 | IConfigSource config = new IniConfigSource(); | 158 | IConfigSource config = new IniConfigSource(); |
159 | |||
191 | config.AddConfig("Modules"); | 160 | config.AddConfig("Modules"); |
192 | config.AddConfig("AuthenticationService"); | 161 | config.AddConfig("AuthenticationService"); |
193 | config.Configs["Modules"].Set("AuthenticationServices", "LocalAuthenticationServicesConnector"); | 162 | config.Configs["Modules"].Set("AuthenticationServices", "LocalAuthenticationServicesConnector"); |
194 | if (real) | 163 | config.Configs["AuthenticationService"].Set( |
195 | config.Configs["AuthenticationService"].Set( | 164 | "LocalServiceModule", "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"); |
196 | "LocalServiceModule", "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"); | ||
197 | else | ||
198 | config.Configs["AuthenticationService"].Set( | ||
199 | "LocalServiceModule", "OpenSim.Tests.Common.dll:MockAuthenticationService"); | ||
200 | config.Configs["AuthenticationService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); | 165 | config.Configs["AuthenticationService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); |
166 | |||
201 | service.Initialise(config); | 167 | service.Initialise(config); |
202 | service.AddRegion(testScene); | 168 | service.AddRegion(testScene); |
203 | service.RegionLoaded(testScene); | 169 | service.RegionLoaded(testScene); |
@@ -205,24 +171,17 @@ namespace OpenSim.Tests.Common.Setup | |||
205 | //m_authenticationService = service; | 171 | //m_authenticationService = service; |
206 | } | 172 | } |
207 | 173 | ||
208 | private static LocalInventoryServicesConnector StartInventoryService(Scene testScene, bool real) | 174 | private static LocalInventoryServicesConnector StartInventoryService(Scene testScene) |
209 | { | 175 | { |
210 | LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); | 176 | LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); |
211 | IConfigSource config = new IniConfigSource(); | 177 | |
178 | IConfigSource config = new IniConfigSource(); | ||
212 | config.AddConfig("Modules"); | 179 | config.AddConfig("Modules"); |
213 | config.AddConfig("InventoryService"); | 180 | config.AddConfig("InventoryService"); |
214 | config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); | 181 | config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); |
215 | 182 | config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); | |
216 | if (real) | ||
217 | { | ||
218 | config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); | ||
219 | } | ||
220 | else | ||
221 | { | ||
222 | config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockInventoryService"); | ||
223 | } | ||
224 | |||
225 | config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); | 183 | config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); |
184 | |||
226 | inventoryService.Initialise(config); | 185 | inventoryService.Initialise(config); |
227 | inventoryService.AddRegion(testScene); | 186 | inventoryService.AddRegion(testScene); |
228 | inventoryService.RegionLoaded(testScene); | 187 | inventoryService.RegionLoaded(testScene); |
@@ -231,24 +190,19 @@ namespace OpenSim.Tests.Common.Setup | |||
231 | return inventoryService; | 190 | return inventoryService; |
232 | } | 191 | } |
233 | 192 | ||
234 | private static LocalGridServicesConnector StartGridService(Scene testScene, bool real) | 193 | private static LocalGridServicesConnector StartGridService(Scene testScene) |
235 | { | 194 | { |
236 | IConfigSource config = new IniConfigSource(); | 195 | IConfigSource config = new IniConfigSource(); |
237 | config.AddConfig("Modules"); | 196 | config.AddConfig("Modules"); |
238 | config.AddConfig("GridService"); | 197 | config.AddConfig("GridService"); |
239 | config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector"); | 198 | config.Configs["Modules"].Set("GridServices", "LocalGridServicesConnector"); |
240 | config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll:NullRegionData"); | 199 | config.Configs["GridService"].Set("StorageProvider", "OpenSim.Data.Null.dll:NullRegionData"); |
241 | if (real) | 200 | config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService"); |
242 | config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Services.GridService.dll:GridService"); | ||
243 | 201 | ||
244 | LocalGridServicesConnector gridService = new LocalGridServicesConnector(); | 202 | LocalGridServicesConnector gridService = new LocalGridServicesConnector(); |
245 | gridService.Initialise(config); | 203 | gridService.Initialise(config); |
246 | |||
247 | //else | ||
248 | // config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestGridService"); | ||
249 | gridService.AddRegion(testScene); | 204 | gridService.AddRegion(testScene); |
250 | gridService.RegionLoaded(testScene); | 205 | gridService.RegionLoaded(testScene); |
251 | //testScene.AddRegionModule(m_gridService.Name, m_gridService); | ||
252 | 206 | ||
253 | return gridService; | 207 | return gridService; |
254 | } | 208 | } |
@@ -472,10 +426,10 @@ namespace OpenSim.Tests.Common.Setup | |||
472 | /// <param name="ownerId"></param> | 426 | /// <param name="ownerId"></param> |
473 | /// <returns></returns> | 427 | /// <returns></returns> |
474 | public static SceneObjectPart CreateSceneObjectPart(string name, UUID id, UUID ownerId) | 428 | public static SceneObjectPart CreateSceneObjectPart(string name, UUID id, UUID ownerId) |
475 | { | 429 | { |
476 | return new SceneObjectPart( | 430 | return new SceneObjectPart( |
477 | ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) | 431 | ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) |
478 | { Name = name, UUID = id }; | 432 | { Name = name, UUID = id, Scale = new Vector3(1, 1, 1) }; |
479 | } | 433 | } |
480 | 434 | ||
481 | /// <summary> | 435 | /// <summary> |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 5bac56e..fbaa590 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -1,4 +1,22 @@ | |||
1 | ;; A note on the format of this file | 1 | ;; This is the main configuration file for OpenSimulator. If it's named OpenSim.ini |
2 | ;; then it will be loaded by OpenSimulator. If it's named OpenSim.ini.example then | ||
3 | ;; you will need to copy it to OpenSim.ini first (if that file does not already exist) | ||
4 | ;; | ||
5 | ;; If you are copying, then once you have copied OpenSim.ini.example to OpenSim.ini you will | ||
6 | ;; need to pick an architecture in the [Architecture] section at the end of this file. | ||
7 | ;; | ||
8 | ;; The settings in this file are in the form "<key> = <value>". For example, save_crashes = false | ||
9 | ;; in the [Startup] section below. | ||
10 | ;; | ||
11 | ;; All settings are initially commented out and the default value used, as found in | ||
12 | ;; OpenSimDefaults.ini. To change a setting, first uncomment it by deleting the initial semicolon (;) | ||
13 | ;; and then change the value. This will override the value in OpenSimDefaults.ini | ||
14 | ;; | ||
15 | ;; If you want to find out what configuration OpenSimulator has finished with once all the configuration | ||
16 | ;; files are loaded then type "config show" on the region console command line. | ||
17 | ;; | ||
18 | ;; | ||
19 | ;; NOTES FOR DEVELOPERS REGARDING THE FORMAT OF THIS FILE | ||
2 | ;; | 20 | ;; |
3 | ;; All leading white space is ignored, but preserved. | 21 | ;; All leading white space is ignored, but preserved. |
4 | ;; | 22 | ;; |
@@ -8,15 +26,14 @@ | |||
8 | ;; formatted as: | 26 | ;; formatted as: |
9 | ;; {option} {depends on} {question to ask} {choices} default value | 27 | ;; {option} {depends on} {question to ask} {choices} default value |
10 | ;; Any text comments following the declaration, up to the next blank line. | 28 | ;; Any text comments following the declaration, up to the next blank line. |
11 | ;; will be copied to the generated file. | 29 | ;; will be copied to the generated file (NOTE: generation is not yet implemented) |
12 | ;; A * in the choices list will allow an empty entry.\ | 30 | ;; A * in the choices list will allow an empty entry. |
13 | ;; An empty question will set the default if the dependencies are | 31 | ;; An empty question will set the default if the dependencies are |
14 | ;; satisfied. | 32 | ;; satisfied. |
15 | ;; | 33 | ;; |
16 | ;; ; denotes a commented out option. Uncomment it to actvate it | 34 | ;; ; denotes a commented out option. |
17 | ;; and change it to the desired value | 35 | ;; Any options added to OpenSim.ini.example should be initially commented out. |
18 | ;; Any options added to OpenSim.ini.exmaple must be commented out, | 36 | |
19 | ;; and their value must represent the default. | ||
20 | 37 | ||
21 | [Startup] | 38 | [Startup] |
22 | ;# {save_crashes} {} {Save crashes to disk?} {true false} false | 39 | ;# {save_crashes} {} {Save crashes to disk?} {true false} false |
@@ -35,7 +52,7 @@ | |||
35 | 52 | ||
36 | ;; Determine where OpenSimulator looks for the files which tell it | 53 | ;; Determine where OpenSimulator looks for the files which tell it |
37 | ;; which regions to server | 54 | ;; which regions to server |
38 | ;; Defaults to "filesystem" if this setting isn't present | 55 | ;; Default is "filesystem" |
39 | ; region_info_source = "filesystem" | 56 | ; region_info_source = "filesystem" |
40 | ; region_info_source = "web" | 57 | ; region_info_source = "web" |
41 | 58 | ||
@@ -131,6 +148,7 @@ | |||
131 | ;; ZeroMesher is faster but leaves the physics engine to model the mesh | 148 | ;; ZeroMesher is faster but leaves the physics engine to model the mesh |
132 | ;; using the basic shapes that it supports. | 149 | ;; using the basic shapes that it supports. |
133 | ;; Usually this is only a box. | 150 | ;; Usually this is only a box. |
151 | ;; Default is Meshmerizer | ||
134 | ; meshing = Meshmerizer | 152 | ; meshing = Meshmerizer |
135 | ; meshing = ZeroMesher | 153 | ; meshing = ZeroMesher |
136 | 154 | ||
@@ -138,6 +156,7 @@ | |||
138 | ;; OpenDynamicsEngine is by some distance the most developed physics engine | 156 | ;; OpenDynamicsEngine is by some distance the most developed physics engine |
139 | ;; basicphysics effectively does not model physics at all, making all | 157 | ;; basicphysics effectively does not model physics at all, making all |
140 | ;; objects phantom | 158 | ;; objects phantom |
159 | ;; Default is OpenDynamicsEngine | ||
141 | ; physics = OpenDynamicsEngine | 160 | ; physics = OpenDynamicsEngine |
142 | ; physics = basicphysics | 161 | ; physics = basicphysics |
143 | ; physics = POS | 162 | ; physics = POS |
@@ -154,7 +173,6 @@ | |||
154 | ;; permission checks (allowing anybody to copy | 173 | ;; permission checks (allowing anybody to copy |
155 | ;; any item, etc. This may not yet be implemented uniformally. | 174 | ;; any item, etc. This may not yet be implemented uniformally. |
156 | ;; If set to true, then all permissions checks are carried out | 175 | ;; If set to true, then all permissions checks are carried out |
157 | ;; Default is false | ||
158 | ; serverside_object_permissions = false | 176 | ; serverside_object_permissions = false |
159 | 177 | ||
160 | ;; This allows users with a UserLevel of 200 or more to assume god | 178 | ;; This allows users with a UserLevel of 200 or more to assume god |
@@ -183,11 +201,20 @@ | |||
183 | ;; If not generating maptiles, use this static texture asset ID | 201 | ;; If not generating maptiles, use this static texture asset ID |
184 | ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" | 202 | ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" |
185 | 203 | ||
204 | ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required | ||
205 | ; HttpProxy = "http://proxy.com:8080" | ||
206 | |||
207 | ;; If you're using HttpProxy, then you can set HttpProxyExceptions to a list of regular expressions for URLs that you don't want to go through the proxy | ||
208 | ;; For example, servers inside your firewall. | ||
209 | ;; Separate patterns with a ';' | ||
210 | ; HttpProxyExceptions = ".mydomain.com;localhost" | ||
211 | |||
186 | ;# {emailmodule} {} {Provide llEmail and llGetNextEmail functionality? (requires SMTP server)} {true false} false | 212 | ;# {emailmodule} {} {Provide llEmail and llGetNextEmail functionality? (requires SMTP server)} {true false} false |
187 | ;; The email module requires some configuration. It needs an SMTP | 213 | ;; The email module requires some configuration. It needs an SMTP |
188 | ;; server to send mail through. | 214 | ;; server to send mail through. |
189 | ; emailmodule = DefaultEmailModule | 215 | ; emailmodule = DefaultEmailModule |
190 | 216 | ||
217 | |||
191 | [SMTP] | 218 | [SMTP] |
192 | ;; The SMTP server enabled the email module to send email to external | 219 | ;; The SMTP server enabled the email module to send email to external |
193 | ;; destinations. | 220 | ;; destinations. |
@@ -214,6 +241,7 @@ | |||
214 | ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {} | 241 | ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {} |
215 | ; SMTP_SERVER_PASSWORD = "" | 242 | ; SMTP_SERVER_PASSWORD = "" |
216 | 243 | ||
244 | |||
217 | [Network] | 245 | [Network] |
218 | ;; Configure the remote console user here. This will not actually be used | 246 | ;; Configure the remote console user here. This will not actually be used |
219 | ;; unless you use -console=rest at startup. | 247 | ;; unless you use -console=rest at startup. |
@@ -247,6 +275,7 @@ | |||
247 | ;; " (Mozilla Compatible)" to the text where there are problems with a web server | 275 | ;; " (Mozilla Compatible)" to the text where there are problems with a web server |
248 | ; user_agent = "OpenSim LSL (Mozilla Compatible)" | 276 | ; user_agent = "OpenSim LSL (Mozilla Compatible)" |
249 | 277 | ||
278 | |||
250 | [ClientStack.LindenUDP] | 279 | [ClientStack.LindenUDP] |
251 | ;; See OpensSimDefaults.ini for the throttle options. You can copy the | 280 | ;; See OpensSimDefaults.ini for the throttle options. You can copy the |
252 | ;; relevant sections and override them here. | 281 | ;; relevant sections and override them here. |
@@ -263,17 +292,18 @@ | |||
263 | ;; building's lights to possibly not be rendered. | 292 | ;; building's lights to possibly not be rendered. |
264 | ; DisableFacelights = "false" | 293 | ; DisableFacelights = "false" |
265 | 294 | ||
295 | |||
266 | [Chat] | 296 | [Chat] |
267 | ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 | 297 | ;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10 |
268 | ;; Distance in meters that whispers should travel. Default is 10m | 298 | ;; Distance in meters that whispers should travel. |
269 | ; whisper_distance = 10 | 299 | ; whisper_distance = 10 |
270 | 300 | ||
271 | ;# {say_distance} {} {Distance at which normal chat is heard, in meters? (SL uses 20 here)} {} 30 | 301 | ;# {say_distance} {} {Distance at which normal chat is heard, in meters? (SL uses 20 here)} {} 30 |
272 | ;; Distance in meters that ordinary chat should travel. Default is 30m | 302 | ;; Distance in meters that ordinary chat should travel. |
273 | ; say_distance = 30 | 303 | ; say_distance = 30 |
274 | 304 | ||
275 | ;# {shout_distance} {Distance at which a shout is heard, in meters?} {} 100 | 305 | ;# {shout_distance} {Distance at which a shout is heard, in meters?} {} 100 |
276 | ;; Distance in meters that shouts should travel. Default is 100m | 306 | ;; Distance in meters that shouts should travel. |
277 | ; shout_distance = 100 | 307 | ; shout_distance = 100 |
278 | 308 | ||
279 | 309 | ||
@@ -337,13 +367,13 @@ | |||
337 | ;# {create_region_enable_voice} {enabled:true} {Enable voice for newly created regions?} {true false} false | 367 | ;# {create_region_enable_voice} {enabled:true} {Enable voice for newly created regions?} {true false} false |
338 | ;; set this variable to true if you want the create_region XmlRpc | 368 | ;; set this variable to true if you want the create_region XmlRpc |
339 | ;; call to unconditionally enable voice on all parcels for a newly | 369 | ;; call to unconditionally enable voice on all parcels for a newly |
340 | ;; created region [default: false] | 370 | ;; created region |
341 | ; create_region_enable_voice = false | 371 | ; create_region_enable_voice = false |
342 | 372 | ||
343 | ;# {create_region_public} {enabled:true} {Make newly created regions public?} {true false} false | 373 | ;# {create_region_public} {enabled:true} {Make newly created regions public?} {true false} false |
344 | ;; set this variable to false if you want the create_region XmlRpc | 374 | ;; set this variable to false if you want the create_region XmlRpc |
345 | ;; call to create all regions as private per default (can be | 375 | ;; call to create all regions as private per default (can be |
346 | ;; overridden in the XmlRpc call) [default: true] | 376 | ;; overridden in the XmlRpc call) |
347 | ; create_region_public = false | 377 | ; create_region_public = false |
348 | 378 | ||
349 | ;# {enabled_methods} {enabled:true} {List of methods to allow, separated by |} {} all | 379 | ;# {enabled_methods} {enabled:true} {List of methods to allow, separated by |} {} all |
@@ -372,15 +402,16 @@ | |||
372 | ;; default avatars | 402 | ;; default avatars |
373 | ; default_appearance = default_appearance.xml | 403 | ; default_appearance = default_appearance.xml |
374 | 404 | ||
405 | |||
375 | [Wind] | 406 | [Wind] |
376 | ;# {enabled} {} {Enable wind module?} {true false} true | 407 | ;# {enabled} {} {Enable wind module?} {true false} true |
377 | ;; Enables the wind module. Default is true | 408 | ;; Enables the wind module. |
378 | ;enabled = true | 409 | ; enabled = true |
379 | 410 | ||
380 | ;# {wind_update_rate} {enabled:true} {Wind update rate in frames?} {} 150 | 411 | ;# {wind_update_rate} {enabled:true} {Wind update rate in frames?} {} 150 |
381 | ;; How often should wind be updated, as a function of world frames. | 412 | ;; How often should wind be updated, as a function of world frames. |
382 | ;; Approximately 50 frames a second | 413 | ;; Approximately 50 frames a second |
383 | wind_update_rate = 150 | 414 | ; wind_update_rate = 150 |
384 | 415 | ||
385 | ;; The Default Wind Plugin to load | 416 | ;; The Default Wind Plugin to load |
386 | ; wind_plugin = SimpleRandomWind | 417 | ; wind_plugin = SimpleRandomWind |
@@ -396,9 +427,10 @@ | |||
396 | 427 | ||
397 | ;# {strength} {enabled:true wind_plugin:SimpleRandomWind} {Wind strength?} {} 1.0 | 428 | ;# {strength} {enabled:true wind_plugin:SimpleRandomWind} {Wind strength?} {} 1.0 |
398 | ;; This setting is specific to the SimpleRandomWind plugin | 429 | ;; This setting is specific to the SimpleRandomWind plugin |
399 | ;; Adjusts wind strength. 0.0 = no wind, 1.0 = normal wind. Default is 1.0 | 430 | ;; Adjusts wind strength. 0.0 = no wind, 1.0 = normal wind. |
400 | ; strength = 1.0 | 431 | ; strength = 1.0 |
401 | 432 | ||
433 | |||
402 | [LightShare] | 434 | [LightShare] |
403 | ;# {enable_windlight} {} {Enable LightShare technology?} {true false} false | 435 | ;# {enable_windlight} {} {Enable LightShare technology?} {true false} false |
404 | ;; This enables the transmission of Windlight scenes to supporting clients, | 436 | ;; This enables the transmission of Windlight scenes to supporting clients, |
@@ -406,7 +438,8 @@ | |||
406 | ;; It has no ill effect on viewers which do not support server-side | 438 | ;; It has no ill effect on viewers which do not support server-side |
407 | ;; windlight settings. | 439 | ;; windlight settings. |
408 | ;; Currently we only have support for MySQL databases. | 440 | ;; Currently we only have support for MySQL databases. |
409 | ; enable_windlight = false; | 441 | ; enable_windlight = false |
442 | |||
410 | 443 | ||
411 | [DataSnapshot] | 444 | [DataSnapshot] |
412 | ;# {index_sims} {} {Enable data snapshotting (search)?} {true false} false | 445 | ;# {index_sims} {} {Enable data snapshotting (search)?} {true false} false |
@@ -417,7 +450,6 @@ | |||
417 | ;; and you can ignore the rest of these search-related configs. | 450 | ;; and you can ignore the rest of these search-related configs. |
418 | ; index_sims = false | 451 | ; index_sims = false |
419 | 452 | ||
420 | |||
421 | ;# {data_exposure} {index_sims:true} {How much data should be exposed?} {minimum all} minimum | 453 | ;# {data_exposure} {index_sims:true} {How much data should be exposed?} {minimum all} minimum |
422 | ;; The variable data_exposure controls what the regions expose: | 454 | ;; The variable data_exposure controls what the regions expose: |
423 | ;; minimum: exposes only things explicitly marked for search | 455 | ;; minimum: exposes only things explicitly marked for search |
@@ -462,6 +494,7 @@ | |||
462 | ;; Money Unit fee to create groups | 494 | ;; Money Unit fee to create groups |
463 | ; PriceGroupCreate = 0 | 495 | ; PriceGroupCreate = 0 |
464 | 496 | ||
497 | |||
465 | [XEngine] | 498 | [XEngine] |
466 | ;# {Enabled} {} {Enable the XEngine scripting engine?} {true false} true | 499 | ;# {Enabled} {} {Enable the XEngine scripting engine?} {true false} true |
467 | ;; Enable this engine in this OpenSim instance | 500 | ;; Enable this engine in this OpenSim instance |
@@ -556,9 +589,9 @@ | |||
556 | ;; Default is ./bin/ScriptEngines | 589 | ;; Default is ./bin/ScriptEngines |
557 | ; ScriptEnginesPath = "ScriptEngines" | 590 | ; ScriptEnginesPath = "ScriptEngines" |
558 | 591 | ||
592 | |||
559 | [MRM] | 593 | [MRM] |
560 | ;; Enables the Mini Region Modules Script Engine. | 594 | ;; Enables the Mini Region Modules Script Engine. |
561 | ;; default is false | ||
562 | ; Enabled = false | 595 | ; Enabled = false |
563 | 596 | ||
564 | ;; Runs MRM in a Security Sandbox | 597 | ;; Runs MRM in a Security Sandbox |
@@ -580,6 +613,7 @@ | |||
580 | ;; May represent a security risk if you disable this. | 613 | ;; May represent a security risk if you disable this. |
581 | ; OwnerOnly = true | 614 | ; OwnerOnly = true |
582 | 615 | ||
616 | |||
583 | [FreeSwitchVoice] | 617 | [FreeSwitchVoice] |
584 | ;; In order for this to work you need a functioning FreeSWITCH PBX set up. | 618 | ;; In order for this to work you need a functioning FreeSWITCH PBX set up. |
585 | ;; Configuration details at http://opensimulator.org/wiki/Freeswitch_Module | 619 | ;; Configuration details at http://opensimulator.org/wiki/Freeswitch_Module |
@@ -587,29 +621,49 @@ | |||
587 | 621 | ||
588 | ;; You need to load a local service for a standalone, and a remote service | 622 | ;; You need to load a local service for a standalone, and a remote service |
589 | ;; for a grid region. Use one of the lines below, as appropriate | 623 | ;; for a grid region. Use one of the lines below, as appropriate |
624 | ;; If you're using Freeswitch on a standalone then you will also need to configure the [FreeswitchService] section | ||
590 | ; LocalServiceModule = OpenSim.Services.FreeswitchService.dll:FreeswitchService | 625 | ; LocalServiceModule = OpenSim.Services.FreeswitchService.dll:FreeswitchService |
591 | ; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector | 626 | ; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector |
592 | 627 | ||
593 | ;; If using a remote module, specify the server URL | 628 | ;; If using a remote connector, specify the server URL |
594 | ; FreeswitchServiceURL = http://my.grid.server:8003/fsapi | 629 | ; FreeswitchServiceURL = http://my.grid.server:8003/fsapi |
595 | 630 | ||
631 | |||
596 | [FreeswitchService] | 632 | [FreeswitchService] |
597 | ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! | 633 | ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! |
598 | ;; !!!!!!STANDALONE ONLY!!!!!! | 634 | ;; !!!!!!STANDALONE ONLY!!!!!! |
599 | ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! | 635 | ;; !!!!!!!!!!!!!!!!!!!!!!!!!!! |
600 | ;; IP of your FS server | 636 | ;; The IP address of your FreeSWITCH server. The common case is for this to be the same as the server running the OpenSim standalone |
601 | ;ServerAddress = 85.25.142.92 | 637 | ;; This has to be set for the FreeSWITCH service to work |
638 | ;ServerAddress = 127.0.0.1 | ||
602 | 639 | ||
603 | ;; All other options are - well - optional | 640 | ;; The following configuration parameters are optional |
604 | ; Realm = "127.0.0.1" | 641 | |
605 | ; SIPProxy = "127.0.0.1:5060" | 642 | ;; By default, this is the same as the ServerAddress |
606 | ; EchoServer = "127.0.0.1" | 643 | ; Realm = 127.0.0.1 |
607 | ; EchoPort = 50505 | 644 | |
608 | ; AttemptSTUN = "false" | 645 | ;; By default, this is the same as the ServerAddress on port 5060 |
646 | ; SIPProxy = 127.0.0.1:5060 | ||
647 | |||
648 | ;; Default is 5000ms | ||
609 | ; DefaultTimeout = 5000 | 649 | ; DefaultTimeout = 5000 |
610 | ; Context = "default" | 650 | |
611 | ; UserName = "freeswitch" | 651 | ;; The dial plan context. Default is "default" |
612 | ; Password = "password" | 652 | ; Context = default |
653 | |||
654 | ;; Currently unused | ||
655 | ; UserName = freeswitch | ||
656 | |||
657 | ;; Currently unused | ||
658 | ; Password = password | ||
659 | |||
660 | ;; The following parameters are for STUN = Simple Traversal of UDP through NATs | ||
661 | ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal | ||
662 | ;; stun.freeswitch.org is not guaranteed to be running so use it in | ||
663 | ;; production at your own risk | ||
664 | ; EchoServer = 127.0.0.1 | ||
665 | ; EchoPort = 50505 | ||
666 | ; AttemptSTUN = false | ||
613 | 667 | ||
614 | [Groups] | 668 | [Groups] |
615 | ;# {Enabled} {} {Enable groups?} {true false} false | 669 | ;# {Enabled} {} {Enable groups?} {true false} false |
@@ -634,7 +688,7 @@ | |||
634 | ;# {ServicesConnectorModule} {Module:GroupsModule} {Service connector to use for groups} {XmlRpcGroupsServicesConnector SimianGroupsServicesConnector} XmlRpcGroupsServicesConnector | 688 | ;# {ServicesConnectorModule} {Module:GroupsModule} {Service connector to use for groups} {XmlRpcGroupsServicesConnector SimianGroupsServicesConnector} XmlRpcGroupsServicesConnector |
635 | ;; Service connectors to the Groups Service as used in the GroupsModule. Select one depending on | 689 | ;; Service connectors to the Groups Service as used in the GroupsModule. Select one depending on |
636 | ;; whether you're using a Flotsam XmlRpc backend or a SimianGrid backend | 690 | ;; whether you're using a Flotsam XmlRpc backend or a SimianGrid backend |
637 | ; ServicesConnectorModule = SimianGroupsServicesConnector | 691 | ; ServicesConnectorModule = XmlRpcGroupsServicesConnector |
638 | 692 | ||
639 | ;# {GroupsServerURI} {Module:GroupsModule} {Groups Server URI} {} | 693 | ;# {GroupsServerURI} {Module:GroupsModule} {Groups Server URI} {} |
640 | ;; URI for the groups services | 694 | ;; URI for the groups services |
@@ -654,6 +708,7 @@ | |||
654 | ; XmlRpcServiceReadKey = 1234 | 708 | ; XmlRpcServiceReadKey = 1234 |
655 | ; XmlRpcServiceWriteKey = 1234 | 709 | ; XmlRpcServiceWriteKey = 1234 |
656 | 710 | ||
711 | |||
657 | [InterestManagement] | 712 | [InterestManagement] |
658 | ;# {UpdatePrioritizationScheme} {} {Update prioritization scheme?} {BestAvatarResponsiveness Time Distance SimpleAngularDistance FrontBack} BestAvatarResponsiveness | 713 | ;# {UpdatePrioritizationScheme} {} {Update prioritization scheme?} {BestAvatarResponsiveness Time Distance SimpleAngularDistance FrontBack} BestAvatarResponsiveness |
659 | ;; This section controls how state updates are prioritized for each client | 714 | ;; This section controls how state updates are prioritized for each client |
@@ -661,24 +716,28 @@ | |||
661 | ;; SimpleAngularDistance, FrontBack | 716 | ;; SimpleAngularDistance, FrontBack |
662 | ; UpdatePrioritizationScheme = BestAvatarResponsiveness | 717 | ; UpdatePrioritizationScheme = BestAvatarResponsiveness |
663 | 718 | ||
719 | |||
664 | [MediaOnAPrim] | 720 | [MediaOnAPrim] |
665 | ;# {Enabled} {} {Enable Media-on-a-Prim (MOAP)} {true false} true | 721 | ;# {Enabled} {} {Enable Media-on-a-Prim (MOAP)} {true false} true |
666 | ;; Enable media on a prim facilities | 722 | ;; Enable media on a prim facilities |
667 | ; Enabled = true; | 723 | ; Enabled = true; |
668 | 724 | ||
725 | |||
669 | [Architecture] | 726 | [Architecture] |
670 | ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini | 727 | ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini |
671 | ;; Choose one of these architecture includes: | 728 | ;; Uncomment one of the following includes as required. For instance, to create a standalone OpenSim, |
672 | ;; Include-Architecture = "config-include/Standalone.ini" | 729 | ;; uncomment Include-Architecture = "config-include/Standalone.ini" |
673 | ;; Include-Architecture = "config-include/StandaloneHypergrid.ini" | 730 | ;; |
674 | ;; Include-Architecture = "config-include/Grid.ini" | 731 | ;; Then you will need to copy and edit the corresponding *Common.example file in config-include/ |
675 | ;; Include-Architecture = "config-include/GridHypergrid.ini" | 732 | ;; that the referenced .ini file goes on to include. |
676 | ;; Include-Architecture = "config-include/SimianGrid.ini" | 733 | ;; |
677 | ;; Include-Architecture = "config-include/HyperSimianGrid.ini" | 734 | ;; For instance, if you chose "config-include/Standalone.ini" then you will need to copy |
735 | ;; "config-include/StandaloneCommon.ini.example" to "config-include/StandaloneCommon.ini" before | ||
736 | ;; editing it to set the database and backend services that OpenSim will use. | ||
737 | ;; | ||
678 | ; Include-Architecture = "config-include/Standalone.ini" | 738 | ; Include-Architecture = "config-include/Standalone.ini" |
679 | 739 | ; Include-Architecture = "config-include/StandaloneHypergrid.ini" | |
680 | ;; Then choose | 740 | ; Include-Architecture = "config-include/Grid.ini" |
681 | ;; config-include/StandaloneCommon.ini.example (if you're in standlone) OR | 741 | ; Include-Architecture = "config-include/GridHypergrid.ini" |
682 | ;; config-include/GridCommon.ini.example (if you're connected to a grid) | 742 | ; Include-Architecture = "config-include/SimianGrid.ini" |
683 | ;; Copy to your own .ini there (without .example extension) and edit it | 743 | ; Include-Architecture = "config-include/HyperSimianGrid.ini" |
684 | ;; to customize your data | ||
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index db4bb6a..02fa7c5 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -1,3 +1,7 @@ | |||
1 | ; This file contains defaults for various settings in OpenSimulator. These can be overriden | ||
2 | ; by changing the same setting in OpenSim.ini (once OpenSim.ini.example has been copied to OpenSim.ini). | ||
3 | |||
4 | |||
1 | [Startup] | 5 | [Startup] |
2 | ; Set this to true if you want to log crashes to disk | 6 | ; Set this to true if you want to log crashes to disk |
3 | ; this can be useful when submitting bug reports. | 7 | ; this can be useful when submitting bug reports. |
@@ -10,15 +14,6 @@ | |||
10 | ; Place to create a PID file | 14 | ; Place to create a PID file |
11 | ; PIDFile = "/tmp/my.pid" | 15 | ; PIDFile = "/tmp/my.pid" |
12 | 16 | ||
13 | ; Http proxy support for llHTTPRequest and dynamic texture loading | ||
14 | ; Set HttpProxy to the URL for your proxy server if you would like | ||
15 | ; to proxy llHTTPRequests through a firewall | ||
16 | ; HttpProxy = "http://proxy.com" | ||
17 | ; Set HttpProxyExceptions to a list of regular expressions for | ||
18 | ; URLs that you don't want going through the proxy such as servers | ||
19 | ; inside your firewall, separate patterns with a ';' | ||
20 | ; HttpProxyExceptions = ".mydomain.com;localhost" | ||
21 | |||
22 | startup_console_commands_file = "startup_commands.txt" | 17 | startup_console_commands_file = "startup_commands.txt" |
23 | shutdown_console_commands_file = "shutdown_commands.txt" | 18 | shutdown_console_commands_file = "shutdown_commands.txt" |
24 | 19 | ||
@@ -154,12 +149,6 @@ | |||
154 | ; to false if you have compatibility problems. | 149 | ; to false if you have compatibility problems. |
155 | ;CacheSculptMaps = true | 150 | ;CacheSculptMaps = true |
156 | 151 | ||
157 | ; if you use Meshmerizer and want collisions for meshies, setting this to true | ||
158 | ; will cause OpenSim to attempt to decode meshies assets, extract the physics | ||
159 | ; mesh, and use it for collisions. This is currently experimental code and enabling | ||
160 | ; it may cause unexpected physics problems. | ||
161 | ;UseMeshiesPhysicsMesh = false | ||
162 | |||
163 | ; Choose one of the physics engines below | 152 | ; Choose one of the physics engines below |
164 | ; OpenDynamicsEngine is by some distance the most developed physics engine | 153 | ; OpenDynamicsEngine is by some distance the most developed physics engine |
165 | ; basicphysics effectively does not model physics at all, making all objects phantom | 154 | ; basicphysics effectively does not model physics at all, making all objects phantom |
@@ -287,6 +276,7 @@ | |||
287 | ;SMTP_SERVER_LOGIN=foo | 276 | ;SMTP_SERVER_LOGIN=foo |
288 | ;SMTP_SERVER_PASSWORD=bar | 277 | ;SMTP_SERVER_PASSWORD=bar |
289 | 278 | ||
279 | |||
290 | [Network] | 280 | [Network] |
291 | ConsoleUser = "Test" | 281 | ConsoleUser = "Test" |
292 | ConsolePass = "secret" | 282 | ConsolePass = "secret" |
@@ -317,6 +307,7 @@ | |||
317 | ; " (Mozilla Compatible)" to the text where there are problems with a web server | 307 | ; " (Mozilla Compatible)" to the text where there are problems with a web server |
318 | ;user_agent = "OpenSim LSL (Mozilla Compatible)" | 308 | ;user_agent = "OpenSim LSL (Mozilla Compatible)" |
319 | 309 | ||
310 | |||
320 | [XMLRPC] | 311 | [XMLRPC] |
321 | ; ## | 312 | ; ## |
322 | ; ## Scripting XMLRPC mapper | 313 | ; ## Scripting XMLRPC mapper |
@@ -330,6 +321,7 @@ | |||
330 | ;XmlRpcRouterModule = "XmlRpcRouterModule" | 321 | ;XmlRpcRouterModule = "XmlRpcRouterModule" |
331 | ;XmlRpcPort = 20800 | 322 | ;XmlRpcPort = 20800 |
332 | 323 | ||
324 | |||
333 | [ClientStack.LindenUDP] | 325 | [ClientStack.LindenUDP] |
334 | ; Set this to true to process incoming packets asynchronously. Networking is | 326 | ; Set this to true to process incoming packets asynchronously. Networking is |
335 | ; already separated from packet handling with a queue, so this will only | 327 | ; already separated from packet handling with a queue, so this will only |
@@ -422,6 +414,7 @@ | |||
422 | ; | 414 | ; |
423 | ;DisableFacelights = "false" | 415 | ;DisableFacelights = "false" |
424 | 416 | ||
417 | |||
425 | [Chat] | 418 | [Chat] |
426 | ; Controls whether the chat module is enabled. Default is true. | 419 | ; Controls whether the chat module is enabled. Default is true. |
427 | enabled = true; | 420 | enabled = true; |
@@ -450,6 +443,25 @@ | |||
450 | ; ForwardOfflineGroupMessages = true | 443 | ; ForwardOfflineGroupMessages = true |
451 | 444 | ||
452 | 445 | ||
446 | [Inventory] | ||
447 | ; Control whether multiple objects sent to inventory should be coaleseced into a single item | ||
448 | ; There are still some issues with coalescence, including the fact that rotation is not restored | ||
449 | ; and some assets may be missing from archive files. | ||
450 | CoalesceMultipleObjectsToInventory = true | ||
451 | |||
452 | |||
453 | [Mesh] | ||
454 | ; enable / disable Collada mesh support | ||
455 | ; default is true | ||
456 | ; AllowMeshUpload = true | ||
457 | |||
458 | ; if you use Meshmerizer and want collisions for meshies, setting this to true | ||
459 | ; will cause OpenSim to attempt to decode meshies assets, extract the physics | ||
460 | ; mesh, and use it for collisions. This is currently experimental code and enabling | ||
461 | ; it may cause unexpected physics problems. | ||
462 | ;UseMeshiesPhysicsMesh = false | ||
463 | |||
464 | |||
453 | [ODEPhysicsSettings] | 465 | [ODEPhysicsSettings] |
454 | ;## | 466 | ;## |
455 | ;## World Settings | 467 | ;## World Settings |
@@ -680,6 +692,7 @@ | |||
680 | ; path to default appearance XML file that specifies the look of the default avatars | 692 | ; path to default appearance XML file that specifies the look of the default avatars |
681 | ;default_appearance = default_appearance.xml | 693 | ;default_appearance = default_appearance.xml |
682 | 694 | ||
695 | |||
683 | [RestPlugins] | 696 | [RestPlugins] |
684 | ; Change this to true to enable REST Plugins. This must be true if you wish to use | 697 | ; Change this to true to enable REST Plugins. This must be true if you wish to use |
685 | ; REST Region or REST Asset and Inventory Plugins | 698 | ; REST Region or REST Asset and Inventory Plugins |
@@ -706,11 +719,10 @@ | |||
706 | flush-on-error = true | 719 | flush-on-error = true |
707 | 720 | ||
708 | 721 | ||
709 | ; Uncomment the following for IRC bridge | 722 | ; IRC bridge is experimental, so if it breaks... keep both parts... yada yada |
710 | ; experimental, so if it breaks... keep both parts... yada yada | ||
711 | ; also, not good error detection when it fails | 723 | ; also, not good error detection when it fails |
712 | ;[IRC] | 724 | [IRC] |
713 | ;enabled = true ; you need to set this otherwise it won't connect | 725 | enabled = false; you need to set this to true otherwise it won't connect |
714 | ;server = name.of.irc.server.on.the.net | 726 | ;server = name.of.irc.server.on.the.net |
715 | ;; user password - only use this if the server requires one | 727 | ;; user password - only use this if the server requires one |
716 | ;password = mypass | 728 | ;password = mypass |
@@ -767,14 +779,14 @@ | |||
767 | ;exclude_list=User 1,User 2,User 3 | 779 | ;exclude_list=User 1,User 2,User 3 |
768 | 780 | ||
769 | 781 | ||
770 | ;[CMS] | 782 | [CMS] |
771 | ;enabled = true | 783 | enabled = false |
772 | ;channel = 345 | 784 | ;channel = 345 |
773 | 785 | ||
774 | 786 | ||
775 | ; Uncomment the following to control the progression of daytime | 787 | ; The following settings control the progression of daytime |
776 | ; in the Sim. The defaults are what is shown below | 788 | ; in the Sim. The defaults are the same as the commented out settings |
777 | ;[Sun] | 789 | [Sun] |
778 | ; number of wall clock hours for an opensim day. 24.0 would mean realtime | 790 | ; number of wall clock hours for an opensim day. 24.0 would mean realtime |
779 | ;day_length = 4 | 791 | ;day_length = 4 |
780 | ; Year length in days | 792 | ; Year length in days |
@@ -821,12 +833,13 @@ | |||
821 | ; default is 1000 | 833 | ; default is 1000 |
822 | cloud_update_rate = 1000 | 834 | cloud_update_rate = 1000 |
823 | 835 | ||
824 | [LightShare] | ||
825 | 836 | ||
837 | [LightShare] | ||
826 | ; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer. | 838 | ; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer. |
827 | ; It has no ill effect on viewers which do not support server-side windlight settings. | 839 | ; It has no ill effect on viewers which do not support server-side windlight settings. |
828 | ; Currently we only have support for MySQL databases. | 840 | ; Currently we only have support for MySQL databases. |
829 | enable_windlight = false; | 841 | enable_windlight = false |
842 | |||
830 | 843 | ||
831 | [Trees] | 844 | [Trees] |
832 | ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying | 845 | ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying |
@@ -838,7 +851,6 @@ | |||
838 | 851 | ||
839 | 852 | ||
840 | [VectorRender] | 853 | [VectorRender] |
841 | |||
842 | ; the font to use for rendering text (default: Arial) | 854 | ; the font to use for rendering text (default: Arial) |
843 | ; font_name = "Arial" | 855 | ; font_name = "Arial" |
844 | 856 | ||
@@ -1032,6 +1044,7 @@ | |||
1032 | ;; Path to script assemblies | 1044 | ;; Path to script assemblies |
1033 | ; ScriptEnginesPath = "ScriptEngines" | 1045 | ; ScriptEnginesPath = "ScriptEngines" |
1034 | 1046 | ||
1047 | |||
1035 | [OpenGridProtocol] | 1048 | [OpenGridProtocol] |
1036 | ;These are the settings for the Open Grid Protocol.. the Agent Domain, Region Domain, you know.. | 1049 | ;These are the settings for the Open Grid Protocol.. the Agent Domain, Region Domain, you know.. |
1037 | ;On/true or Off/false | 1050 | ;On/true or Off/false |
@@ -1240,11 +1253,11 @@ | |||
1240 | ChildReprioritizationDistance = 20.0 | 1253 | ChildReprioritizationDistance = 20.0 |
1241 | 1254 | ||
1242 | 1255 | ||
1243 | [WebStats] | ||
1244 | ; View region statistics via a web page | 1256 | ; View region statistics via a web page |
1245 | ; See http://opensimulator.org/wiki/FAQ#Region_Statistics_on_a_Web_Page | 1257 | ; See http://opensimulator.org/wiki/FAQ#Region_Statistics_on_a_Web_Page |
1246 | ; Use a web browser and type in the "Login URI" + "/SStats/" | 1258 | ; Use a web browser and type in the "Login URI" + "/SStats/" |
1247 | ; For example- http://127.0.0.1:9000/SStats/ | 1259 | ; For example- http://127.0.0.1:9000/SStats/ |
1260 | [WebStats] | ||
1248 | ; enabled=false | 1261 | ; enabled=false |
1249 | 1262 | ||
1250 | 1263 | ||
diff --git a/bin/RegionConfig.ini.example b/bin/RegionConfig.ini.example index d45fe9d..ff00ddf 100644 --- a/bin/RegionConfig.ini.example +++ b/bin/RegionConfig.ini.example | |||
@@ -28,6 +28,7 @@ ExternalHostName = "SYSTEMIP" | |||
28 | ; PhysicalPrimMax = 10 | 28 | ; PhysicalPrimMax = 10 |
29 | ; ClampPrimSize = False | 29 | ; ClampPrimSize = False |
30 | ; MaxPrims = 15000 | 30 | ; MaxPrims = 15000 |
31 | ; MaxAgents = 100 | ||
31 | 32 | ||
32 | ; * | 33 | ; * |
33 | ; * Multi-Tenancy. Only set if needed | 34 | ; * Multi-Tenancy. Only set if needed |
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index f12a143..e2e9624 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example | |||
@@ -85,19 +85,37 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
85 | ; * This is the configuration for the freeswitch server in grid mode | 85 | ; * This is the configuration for the freeswitch server in grid mode |
86 | [FreeswitchService] | 86 | [FreeswitchService] |
87 | LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" | 87 | LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" |
88 | ;; IP of your FS server | 88 | |
89 | ;; The IP address of your FreeSWITCH server. | ||
89 | ; ServerAddress = 127.0.0.1 | 90 | ; ServerAddress = 127.0.0.1 |
90 | 91 | ||
91 | ;; All other options are - well - optional | 92 | ;; The following configuration parameters are optional |
92 | ; Realm = "127.0.0.1" | 93 | |
93 | ; SIPProxy = "127.0.0.1:5060" | 94 | ;; By default, this is the same as the ServerAddress |
94 | ; EchoServer = "127.0.0.1" | 95 | ; Realm = 127.0.0.1 |
95 | ; EchoPort = 50505 | 96 | |
96 | ; AttemptSTUN = "false" | 97 | ;; By default, this is the same as the ServerAddress on port 5060 |
98 | ; SIPProxy = 127.0.0.1:5060 | ||
99 | |||
100 | ;; Default is 5000ms | ||
97 | ; DefaultTimeout = 5000 | 101 | ; DefaultTimeout = 5000 |
98 | ; Context = "default" | 102 | |
99 | ; UserName = "freeswitch" | 103 | ;; The dial plan context. Default is "default" |
100 | ; Password = "password" | 104 | ; Context = default |
105 | |||
106 | ;; Currently unused | ||
107 | ; UserName = freeswitch | ||
108 | |||
109 | ;; Currently unused | ||
110 | ; Password = password | ||
111 | |||
112 | ;; The following parameters are for STUN = Simple Traversal of UDP through NATs | ||
113 | ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal | ||
114 | ;; stun.freeswitch.org is not guaranteed to be running so use it in | ||
115 | ;; production at your own risk | ||
116 | ; EchoServer = 127.0.0.1 | ||
117 | ; EchoPort = 50505 | ||
118 | ; AttemptSTUN = false | ||
101 | 119 | ||
102 | ; * This is the new style authentication service. Currently, only MySQL | 120 | ; * This is the new style authentication service. Currently, only MySQL |
103 | ; * is implemented. | 121 | ; * is implemented. |
diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 7c13076..4d16236 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example | |||
@@ -69,19 +69,37 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 | |||
69 | ; * This is the configuration for the freeswitch server in grid mode | 69 | ; * This is the configuration for the freeswitch server in grid mode |
70 | [FreeswitchService] | 70 | [FreeswitchService] |
71 | LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" | 71 | LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" |
72 | ;; IP of your FS server | 72 | |
73 | ;; The IP address of your FreeSWITCH server. | ||
73 | ; ServerAddress = 127.0.0.1 | 74 | ; ServerAddress = 127.0.0.1 |
74 | 75 | ||
75 | ;; All other options are - well - optional | 76 | ;; The following configuration parameters are optional |
76 | ; Realm = "127.0.0.1" | 77 | |
77 | ; SIPProxy = "127.0.0.1:5060" | 78 | ;; By default, this is the same as the ServerAddress |
78 | ; EchoServer = "127.0.0.1" | 79 | ; Realm = 127.0.0.1 |
79 | ; EchoPort = 50505 | 80 | |
80 | ; AttemptSTUN = "false" | 81 | ;; By default, this is the same as the ServerAddress on port 5060 |
82 | ; SIPProxy = 127.0.0.1:5060 | ||
83 | |||
84 | ;; Default is 5000ms | ||
81 | ; DefaultTimeout = 5000 | 85 | ; DefaultTimeout = 5000 |
82 | ; Context = "default" | 86 | |
83 | ; UserName = "freeswitch" | 87 | ;; The dial plan context. Default is "default" |
84 | ; Password = "password" | 88 | ; Context = default |
89 | |||
90 | ;; Currently unused | ||
91 | ; UserName = freeswitch | ||
92 | |||
93 | ;; Currently unused | ||
94 | ; Password = password | ||
95 | |||
96 | ;; The following parameters are for STUN = Simple Traversal of UDP through NATs | ||
97 | ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal | ||
98 | ;; stun.freeswitch.org is not guaranteed to be running so use it in | ||
99 | ;; production at your own risk | ||
100 | ; EchoServer = 127.0.0.1 | ||
101 | ; EchoPort = 50505 | ||
102 | ; AttemptSTUN = false | ||
85 | 103 | ||
86 | ; * This is the new style authentication service. Currently, only MySQL | 104 | ; * This is the new style authentication service. Currently, only MySQL |
87 | ; * is implemented. | 105 | ; * is implemented. |
diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index d6f15bb..dcebd63 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example | |||
@@ -28,10 +28,10 @@ | |||
28 | 28 | ||
29 | [HGInventoryAccessModule] | 29 | [HGInventoryAccessModule] |
30 | ProfileServerURI = "http://127.0.0.1:9000/profiles" | 30 | ProfileServerURI = "http://127.0.0.1:9000/profiles" |
31 | ;; If you want to protect your assets from being copied by foreign visitors | ||
32 | ;; uncomment the next line. You may want to do this on sims that have licensed content. | ||
33 | ; OutboundPermission = False | ||
34 | 31 | ||
32 | ;; If you want to protect your assets from being copied by foreign visitors | ||
33 | ;; uncomment the next line. You may want to do this on sims that have licensed content. | ||
34 | ; OutboundPermission = False | ||
35 | 35 | ||
36 | [Modules] | 36 | [Modules] |
37 | ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. | 37 | ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. |
@@ -45,16 +45,9 @@ | |||
45 | AssetCaching = "CenomeMemoryAssetCache" | 45 | AssetCaching = "CenomeMemoryAssetCache" |
46 | Include-CenomeCache = "config-include/CenomeCache.ini" | 46 | Include-CenomeCache = "config-include/CenomeCache.ini" |
47 | 47 | ||
48 | ;; Enable this to use Freeswitch on a standalone | ||
49 | ;FreeswitchServiceInConnector = True | ||
50 | |||
51 | ;; Authorization is not on by default, as it depends on external php | 48 | ;; Authorization is not on by default, as it depends on external php |
52 | ;AuthorizationServices = "LocalAuthorizationServicesConnector" | 49 | ;AuthorizationServices = "LocalAuthorizationServicesConnector" |
53 | 50 | ||
54 | [FreeswitchService] | ||
55 | ;; Configuration for the freeswitch service goes here | ||
56 | LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" | ||
57 | |||
58 | [GridService] | 51 | [GridService] |
59 | ;; For in-memory region storage (default) | 52 | ;; For in-memory region storage (default) |
60 | StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" | 53 | StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" |
@@ -74,9 +67,8 @@ | |||
74 | Region_Welcome_Area = "DefaultRegion, FallbackRegion" | 67 | Region_Welcome_Area = "DefaultRegion, FallbackRegion" |
75 | 68 | ||
76 | ; === HG ONLY === | 69 | ; === HG ONLY === |
77 | ;; change this to the address of your simulator | 70 | ;; change this to the address of your simulator |
78 | Gatekeeper="http://127.0.0.1:9000" | 71 | Gatekeeper="http://127.0.0.1:9000" |
79 | |||
80 | 72 | ||
81 | [LibraryModule] | 73 | [LibraryModule] |
82 | ; Set this if you want to change the name of the OpenSim Library | 74 | ; Set this if you want to change the name of the OpenSim Library |
diff --git a/prebuild.xml b/prebuild.xml index 870ebf3..49063da 100644 --- a/prebuild.xml +++ b/prebuild.xml | |||
@@ -931,7 +931,6 @@ | |||
931 | <Reference name="OpenSim.Framework"/> | 931 | <Reference name="OpenSim.Framework"/> |
932 | <Reference name="OpenSim.Framework.Communications"/> | 932 | <Reference name="OpenSim.Framework.Communications"/> |
933 | <Reference name="OpenSim.Framework.Console"/> | 933 | <Reference name="OpenSim.Framework.Console"/> |
934 | <Reference name="OpenSim.Framework.Servers.HttpServer"/> | ||
935 | <Reference name="OpenSim.Region.Framework"/> | 934 | <Reference name="OpenSim.Region.Framework"/> |
936 | <Reference name="OpenSim.Server.Base"/> | 935 | <Reference name="OpenSim.Server.Base"/> |
937 | <Reference name="OpenSim.Services.Base"/> | 936 | <Reference name="OpenSim.Services.Base"/> |
@@ -2889,6 +2888,7 @@ | |||
2889 | <!-- SADLY the way this works means you need to keep adding these paths --> | 2888 | <!-- SADLY the way this works means you need to keep adding these paths --> |
2890 | <Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/> | 2889 | <Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/> |
2891 | <Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/> | 2890 | <Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/> |
2891 | <Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/> | ||
2892 | <Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/> | 2892 | <Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/> |
2893 | <Match buildAction="EmbeddedResource" path="World/Archiver/Tests/Resources" pattern="*"/> | 2893 | <Match buildAction="EmbeddedResource" path="World/Archiver/Tests/Resources" pattern="*"/> |
2894 | <Match path="World/Land/Tests" pattern="*.cs" recurse="true"/> | 2894 | <Match path="World/Land/Tests" pattern="*.cs" recurse="true"/> |