aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs13
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs23
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs53
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs98
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs93
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs14
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs15
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs13
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs3
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs8
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs199
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs51
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs33
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs59
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs92
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs124
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs1166
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs78
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs7
-rw-r--r--OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs224
-rw-r--r--OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs24
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs70
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs219
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs121
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs67
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs325
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs47
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs155
-rw-r--r--OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs103
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs21
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs28
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs17
-rw-r--r--OpenSim/Region/DataSnapshot/DataRequestHandler.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs35
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs23
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs36
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs3
-rw-r--r--OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs10
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs48
-rw-r--r--OpenSim/Region/Framework/Interfaces/INPCModule.cs36
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs59
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs16
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs21
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs20
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUrlModule.cs1
-rw-r--r--OpenSim/Region/Framework/Interfaces/IWorldComm.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs49
-rw-r--r--OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Permissions.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs321
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs31
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs91
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs182
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs441
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs45
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs72
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs154
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs130
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs455
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs195
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs17
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs53
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs54
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs500
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs430
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs499
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs21
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs58
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs6
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs42
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs314
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs41
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs10
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs472
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs3
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs428
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionConnections.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs19
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs41
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs860
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs292
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs139
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs100
-rw-r--r--OpenSim/Region/UserStatistics/WebStatsModule.cs170
172 files changed, 8107 insertions, 3421 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index fb1e831..daae3e6 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -225,7 +225,7 @@ namespace OpenSim
225 /// </summary> 225 /// </summary>
226 private void RegisterConsoleCommands() 226 private void RegisterConsoleCommands()
227 { 227 {
228 m_console.Commands.AddCommand("Regions", false, "force update", 228 m_console.Commands.AddCommand("Objects", false, "force update",
229 "force update", 229 "force update",
230 "Force the update of all objects on clients", 230 "Force the update of all objects on clients",
231 HandleForceUpdate); 231 HandleForceUpdate);
@@ -306,7 +306,7 @@ namespace OpenSim
306 + " If this is not given then the oar is saved to region.oar in the current directory.", 306 + " If this is not given then the oar is saved to region.oar in the current directory.",
307 SaveOar); 307 SaveOar);
308 308
309 m_console.Commands.AddCommand("Regions", false, "edit scale", 309 m_console.Commands.AddCommand("Objects", false, "edit scale",
310 "edit scale <name> <x> <y> <z>", 310 "edit scale <name> <x> <y> <z>",
311 "Change the scale of a named prim", HandleEditScale); 311 "Change the scale of a named prim", HandleEditScale);
312 312
@@ -349,7 +349,7 @@ namespace OpenSim
349 "show ratings", 349 "show ratings",
350 "Show rating data", HandleShow); 350 "Show rating data", HandleShow);
351 351
352 m_console.Commands.AddCommand("Regions", false, "backup", 352 m_console.Commands.AddCommand("Objects", false, "backup",
353 "backup", 353 "backup",
354 "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); 354 "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
355 355
@@ -410,7 +410,7 @@ namespace OpenSim
410 "modules unload <name>", 410 "modules unload <name>",
411 "Unload a module", HandleModules); 411 "Unload a module", HandleModules);
412 412
413 m_console.Commands.AddCommand("Regions", false, "kill uuid", 413 m_console.Commands.AddCommand("Objects", false, "kill uuid",
414 "kill uuid <UUID>", 414 "kill uuid <UUID>",
415 "Kill an object by UUID", KillUUID); 415 "Kill an object by UUID", KillUUID);
416 } 416 }
@@ -618,10 +618,11 @@ namespace OpenSim
618 return; 618 return;
619 } 619 }
620 620
621 PopulateRegionEstateInfo(regInfo); 621 bool changed = PopulateRegionEstateInfo(regInfo);
622 IScene scene; 622 IScene scene;
623 CreateRegion(regInfo, true, out scene); 623 CreateRegion(regInfo, true, out scene);
624 regInfo.EstateSettings.Save(); 624 if (changed)
625 regInfo.EstateSettings.Save();
625 } 626 }
626 627
627 /// <summary> 628 /// <summary>
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index ddc7f10..0adb693 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -437,7 +437,7 @@ namespace OpenSim
437 scene.LoadPrimsFromStorage(regionInfo.originRegionID); 437 scene.LoadPrimsFromStorage(regionInfo.originRegionID);
438 438
439 // TODO : Try setting resource for region xstats here on scene 439 // TODO : Try setting resource for region xstats here on scene
440 MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo)); 440 MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
441 441
442 scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); 442 scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
443 scene.EventManager.TriggerParcelPrimCountUpdate(); 443 scene.EventManager.TriggerParcelPrimCountUpdate();
@@ -856,6 +856,9 @@ namespace OpenSim
856 return Util.UTF8.GetBytes("OK"); 856 return Util.UTF8.GetBytes("OK");
857 } 857 }
858 858
859 public string Name { get { return "SimStatus"; } }
860 public string Description { get { return "Simulator Status"; } }
861
859 public string ContentType 862 public string ContentType
860 { 863 {
861 get { return "text/plain"; } 864 get { return "text/plain"; }
@@ -880,6 +883,9 @@ namespace OpenSim
880 { 883 {
881 OpenSimBase m_opensim; 884 OpenSimBase m_opensim;
882 string osXStatsURI = String.Empty; 885 string osXStatsURI = String.Empty;
886
887 public string Name { get { return "XSimStatus"; } }
888 public string Description { get { return "Simulator XStatus"; } }
883 889
884 public XSimStatusHandler(OpenSimBase sim) 890 public XSimStatusHandler(OpenSimBase sim)
885 { 891 {
@@ -920,6 +926,9 @@ namespace OpenSim
920 { 926 {
921 OpenSimBase m_opensim; 927 OpenSimBase m_opensim;
922 string osUXStatsURI = String.Empty; 928 string osUXStatsURI = String.Empty;
929
930 public string Name { get { return "UXSimStatus"; } }
931 public string Description { get { return "Simulator UXStatus"; } }
923 932
924 public UXSimStatusHandler(OpenSimBase sim) 933 public UXSimStatusHandler(OpenSimBase sim)
925 { 934 {
@@ -1051,13 +1060,13 @@ namespace OpenSim
1051 /// Load the estate information for the provided RegionInfo object. 1060 /// Load the estate information for the provided RegionInfo object.
1052 /// </summary> 1061 /// </summary>
1053 /// <param name="regInfo"></param> 1062 /// <param name="regInfo"></param>
1054 public void PopulateRegionEstateInfo(RegionInfo regInfo) 1063 public bool PopulateRegionEstateInfo(RegionInfo regInfo)
1055 { 1064 {
1056 if (EstateDataService != null) 1065 if (EstateDataService != null)
1057 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false); 1066 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
1058 1067
1059 if (regInfo.EstateSettings.EstateID != 0) 1068 if (regInfo.EstateSettings.EstateID != 0)
1060 return; 1069 return false; // estate info in the database did not change
1061 1070
1062 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); 1071 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
1063 1072
@@ -1092,7 +1101,7 @@ namespace OpenSim
1092 } 1101 }
1093 1102
1094 if (defaultEstateJoined) 1103 if (defaultEstateJoined)
1095 return; 1104 return true; // need to update the database
1096 else 1105 else
1097 m_log.ErrorFormat( 1106 m_log.ErrorFormat(
1098 "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName); 1107 "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
@@ -1154,8 +1163,10 @@ namespace OpenSim
1154 MainConsole.Instance.Output("Joining the estate failed. Please try again."); 1163 MainConsole.Instance.Output("Joining the estate failed. Please try again.");
1155 } 1164 }
1156 } 1165 }
1157 } 1166 }
1158 } 1167
1168 return true; // need to update the database
1169 }
1159 } 1170 }
1160 1171
1161 public class OpenSimConfigSource 1172 public class OpenSimConfigSource
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index ef6dedb..d397893 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -158,7 +158,9 @@ namespace OpenSim.Region.ClientStack.Linden
158 try 158 try
159 { 159 {
160 // the root of all evil 160 // the root of all evil
161 m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest)); 161 m_HostCapsObj.RegisterHandler(
162 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
163
162 m_log.DebugFormat( 164 m_log.DebugFormat(
163 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); 165 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
164 166
@@ -166,7 +168,10 @@ namespace OpenSim.Region.ClientStack.Linden
166 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", 168 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
167 // capsBase + m_mapLayerPath, 169 // capsBase + m_mapLayerPath,
168 // GetMapLayer); 170 // GetMapLayer);
169 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); 171 IRequestHandler req
172 = new RestStreamHandler(
173 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
174
170 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); 175 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
171 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); 176 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
172 } 177 }
@@ -181,14 +186,22 @@ namespace OpenSim.Region.ClientStack.Linden
181 try 186 try
182 { 187 {
183 // I don't think this one works... 188 // I don't think this one works...
184 m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST", 189 m_HostCapsObj.RegisterHandler(
185 capsBase + m_newInventory, 190 "NewFileAgentInventory",
186 NewAgentInventoryRequest)); 191 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
187 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); 192 "POST",
193 capsBase + m_newInventory,
194 NewAgentInventoryRequest,
195 "NewFileAgentInventory",
196 null));
197
198 IRequestHandler req
199 = new RestStreamHandler(
200 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
201
188 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 202 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
189 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 203 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
190 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 204 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
191 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
192 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData); 205 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
193 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); 206 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
194 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost); 207 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
@@ -197,6 +210,12 @@ namespace OpenSim.Region.ClientStack.Linden
197 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler); 210 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
198 211
199 212
213
214 m_HostCapsObj.RegisterHandler(
215 "CopyInventoryFromNotecard",
216 new RestStreamHandler(
217 "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
218
200 // As of RC 1.22.9 of the Linden client this is 219 // As of RC 1.22.9 of the Linden client this is
201 // supported 220 // supported
202 221
@@ -245,7 +264,10 @@ namespace OpenSim.Region.ClientStack.Linden
245 264
246 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 265 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
247 { 266 {
248 m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); 267 m_log.DebugFormat(
268 "[CAPS]: Unauthorized CAPS client {0} from {1}",
269 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
270
249 return string.Empty; 271 return string.Empty;
250 } 272 }
251 273
@@ -296,7 +318,9 @@ namespace OpenSim.Region.ClientStack.Linden
296 m_dumpAssetsToFile); 318 m_dumpAssetsToFile);
297 uploader.OnUpLoad += TaskScriptUpdated; 319 uploader.OnUpLoad += TaskScriptUpdated;
298 320
299 m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); 321 m_HostCapsObj.HttpListener.AddStreamHandler(
322 new BinaryStreamHandler(
323 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
300 324
301 string protocol = "http://"; 325 string protocol = "http://";
302 326
@@ -423,8 +447,14 @@ namespace OpenSim.Region.ClientStack.Linden
423 AssetUploader uploader = 447 AssetUploader uploader =
424 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 448 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
425 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 449 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
450
426 m_HostCapsObj.HttpListener.AddStreamHandler( 451 m_HostCapsObj.HttpListener.AddStreamHandler(
427 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); 452 new BinaryStreamHandler(
453 "POST",
454 capsBase + uploaderPath,
455 uploader.uploaderCaps,
456 "NewAgentInventoryRequest",
457 m_HostCapsObj.AgentID.ToString()));
428 458
429 string protocol = "http://"; 459 string protocol = "http://";
430 460
@@ -740,7 +770,8 @@ namespace OpenSim.Region.ClientStack.Linden
740 uploader.OnUpLoad += ItemUpdated; 770 uploader.OnUpLoad += ItemUpdated;
741 771
742 m_HostCapsObj.HttpListener.AddStreamHandler( 772 m_HostCapsObj.HttpListener.AddStreamHandler(
743 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); 773 new BinaryStreamHandler(
774 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
744 775
745 string protocol = "http://"; 776 string protocol = "http://";
746 777
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index a91b02c..01ce194 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -109,10 +109,11 @@ namespace OpenSim.Region.ClientStack.Linden
109 "Comms", 109 "Comms",
110 false, 110 false,
111 "debug eq", 111 "debug eq",
112 "debug eq [0|1]", 112 "debug eq [0|1|2]",
113 "Turn on event queue debugging", 113 "Turn on event queue debugging"
114 "debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n" 114 + "<= 0 - turns off all event queue logging"
115 + "debug eq 0 will turn off event queue debugging.", 115 + ">= 1 - turns on outgoing event logging"
116 + ">= 2 - turns on poll notification",
116 HandleDebugEq); 117 HandleDebugEq);
117 } 118 }
118 else 119 else
@@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden
235// ClientClosed(client.AgentId); 236// ClientClosed(client.AgentId);
236// } 237// }
237 238
238 private void ClientClosed(UUID AgentID, Scene scene) 239 private void ClientClosed(UUID agentID, Scene scene)
239 { 240 {
240// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); 241// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
241 242
242 int count = 0; 243 int count = 0;
243 while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) 244 while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
244 { 245 {
245 Thread.Sleep(1000); 246 Thread.Sleep(1000);
246 } 247 }
247 248
248 lock (queues) 249 lock (queues)
249 { 250 {
250 queues.Remove(AgentID); 251 queues.Remove(agentID);
251 } 252 }
252 253
253 List<UUID> removeitems = new List<UUID>(); 254 List<UUID> removeitems = new List<UUID>();
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
256 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) 257 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
257 { 258 {
258// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); 259// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
259 if (ky == AgentID) 260 if (ky == agentID)
260 { 261 {
261 removeitems.Add(ky); 262 removeitems.Add(ky);
262 } 263 }
@@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden
267 UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; 268 UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
268 m_AvatarQueueUUIDMapping.Remove(ky); 269 m_AvatarQueueUUIDMapping.Remove(ky);
269 270
270 MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); 271 string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
272 MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
273
274// m_log.DebugFormat(
275// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
276// eqgPath, agentID, m_scene.RegionInfo.RegionName);
271 } 277 }
272 } 278 }
273 279
@@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
281 { 287 {
282 searchval = m_QueueUUIDAvatarMapping[ky]; 288 searchval = m_QueueUUIDAvatarMapping[ky];
283 289
284 if (searchval == AgentID) 290 if (searchval == agentID)
285 { 291 {
286 removeitems.Add(ky); 292 removeitems.Add(ky);
287 } 293 }
@@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden
305 //} 311 //}
306 } 312 }
307 313
314 /// <summary>
315 /// Generate an Event Queue Get handler path for the given eqg uuid.
316 /// </summary>
317 /// <param name='eqgUuid'></param>
318 private string GenerateEqgCapPath(UUID eqgUuid)
319 {
320 return string.Format("/CAPS/EQG/{0}/", eqgUuid);
321 }
322
308 public void OnRegisterCaps(UUID agentID, Caps caps) 323 public void OnRegisterCaps(UUID agentID, Caps caps)
309 { 324 {
310 // Register an event queue for the client 325 // Register an event queue for the client
@@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden
316 // Let's instantiate a Queue for this agent right now 331 // Let's instantiate a Queue for this agent right now
317 TryGetQueue(agentID); 332 TryGetQueue(agentID);
318 333
319 string capsBase = "/CAPS/EQG/"; 334 UUID eventQueueGetUUID;
320 UUID EventQueueGetUUID = UUID.Zero;
321 335
322 lock (m_AvatarQueueUUIDMapping) 336 lock (m_AvatarQueueUUIDMapping)
323 { 337 {
@@ -325,44 +339,50 @@ namespace OpenSim.Region.ClientStack.Linden
325 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 339 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
326 { 340 {
327 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 341 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
328 EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 342 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
329 } 343 }
330 else 344 else
331 { 345 {
332 EventQueueGetUUID = UUID.Random(); 346 eventQueueGetUUID = UUID.Random();
333 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); 347 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
334 } 348 }
335 } 349 }
336 350
337 lock (m_QueueUUIDAvatarMapping) 351 lock (m_QueueUUIDAvatarMapping)
338 { 352 {
339 if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) 353 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
340 m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); 354 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
341 } 355 }
342 356
343 lock (m_AvatarQueueUUIDMapping) 357 lock (m_AvatarQueueUUIDMapping)
344 { 358 {
345 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 359 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
346 m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); 360 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
347 } 361 }
348 362
363 string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
364
349 // Register this as a caps handler 365 // Register this as a caps handler
350 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about 366 // FIXME: Confusingly, we need to register separate as a capability so that the client is told about
351 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately 367 // EventQueueGet when it receive capability information, but then we replace the rest handler immediately
352 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but 368 // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
353 // really it should be possible to directly register the poll handler as a capability. 369 // really it should be possible to directly register the poll handler as a capability.
354 caps.RegisterHandler("EventQueueGet", 370 caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
355 new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
356// delegate(Hashtable m_dhttpMethod) 371// delegate(Hashtable m_dhttpMethod)
357// { 372// {
358// return ProcessQueue(m_dhttpMethod, agentID, caps); 373// return ProcessQueue(m_dhttpMethod, agentID, caps);
359// })); 374// }));
360 375
361 // This will persist this beyond the expiry of the caps handlers 376 // This will persist this beyond the expiry of the caps handlers
377 // TODO: Add EventQueueGet name/description for diagnostics
362 MainServer.Instance.AddPollServiceHTTPHandler( 378 MainServer.Instance.AddPollServiceHTTPHandler(
363 capsBase + EventQueueGetUUID.ToString() + "/", 379 eventQueueGetPath,
364 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); 380 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
365 381
382// m_log.DebugFormat(
383// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
384// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
385
366 Random rnd = new Random(Environment.TickCount); 386 Random rnd = new Random(Environment.TickCount);
367 lock (m_ids) 387 lock (m_ids)
368 { 388 {
@@ -384,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden
384 return false; 404 return false;
385 } 405 }
386 406
407 /// <summary>
408 /// Logs a debug line for an outbound event queue message if appropriate.
409 /// </summary>
410 /// <param name='element'>Element containing message</param>
411 private void LogOutboundDebugMessage(OSD element, UUID agentId)
412 {
413 if (element is OSDMap)
414 {
415 OSDMap ev = (OSDMap)element;
416 m_log.DebugFormat(
417 "Eq OUT {0,-30} to {1,-20} {2,-20}",
418 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
419 }
420 }
421
387 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) 422 public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
388 { 423 {
389// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); 424 if (DebugLevel >= 2)
425 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
390 426
391 Queue<OSD> queue = TryGetQueue(pAgentId); 427 Queue<OSD> queue = TryGetQueue(pAgentId);
392 OSD element; 428 OSD element;
@@ -410,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden
410 } 446 }
411 else 447 else
412 { 448 {
413 if (DebugLevel > 0 && element is OSDMap) 449 if (DebugLevel > 0)
414 { 450 LogOutboundDebugMessage(element, pAgentId);
415 OSDMap ev = (OSDMap)element;
416 m_log.DebugFormat(
417 "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
418 ev["message"], m_scene.GetScenePresence(pAgentId).Name);
419 }
420 451
421 array.Add(element); 452 array.Add(element);
422 453
@@ -426,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden
426 { 457 {
427 element = queue.Dequeue(); 458 element = queue.Dequeue();
428 459
429 if (DebugLevel > 0 && element is OSDMap) 460 if (DebugLevel > 0)
430 { 461 LogOutboundDebugMessage(element, pAgentId);
431 OSDMap ev = (OSDMap)element;
432 m_log.DebugFormat(
433 "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
434 ev["message"], m_scene.GetScenePresence(pAgentId).Name);
435 }
436 462
437 array.Add(element); 463 array.Add(element);
438 thisID++; 464 thisID++;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index a5209b7..c25b58c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -60,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
60 CapabilitiesModule capsModule = new CapabilitiesModule(); 60 CapabilitiesModule capsModule = new CapabilitiesModule();
61 EventQueueGetModule eqgModule = new EventQueueGetModule(); 61 EventQueueGetModule eqgModule = new EventQueueGetModule();
62 62
63 m_scene = SceneHelpers.SetupScene(); 63 m_scene = new SceneHelpers().SetupScene();
64 SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule); 64 SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
65 } 65 }
66 66
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
index 14501c7..cb5afcc 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
@@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
132 capUrl = "/CAPS/" + UUID.Random(); 132 capUrl = "/CAPS/" + UUID.Random();
133 133
134 IRequestHandler reqHandler 134 IRequestHandler reqHandler
135 = new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest); 135 = new RestStreamHandler(
136 "POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
136 137
137 caps.RegisterHandler(capName, reqHandler); 138 caps.RegisterHandler(capName, reqHandler);
138 } 139 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index e7bd2e7..0d7b1fc 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden
120 { 120 {
121// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 121// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
122 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); 122 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
123 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), 123 IRequestHandler reqHandler
124 delegate(Hashtable m_dhttpMethod) 124 = new RestHTTPHandler(
125 { 125 "GET",
126 return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); 126 "/CAPS/" + UUID.Random(),
127 }); 127 httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
128 "GetMesh",
129 agentID.ToString());
128 130
129 caps.RegisterHandler("GetMesh", reqHandler); 131 caps.RegisterHandler("GetMesh", reqHandler);
130 } 132 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index fffcee2..5ae9cc3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
130 if (m_URL == "localhost") 130 if (m_URL == "localhost")
131 { 131 {
132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
133 caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); 133 caps.RegisterHandler(
134 "GetTexture",
135 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
134 } 136 }
135 else 137 else
136 { 138 {
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
index 18c7eae..44a6883 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden
117 117
118 public void RegisterCaps(UUID agentID, Caps caps) 118 public void RegisterCaps(UUID agentID, Caps caps)
119 { 119 {
120 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag); 120 IRequestHandler reqHandler
121 = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString());
122
121 caps.RegisterHandler("MeshUploadFlag", reqHandler); 123 caps.RegisterHandler("MeshUploadFlag", reqHandler);
122 m_agentID = agentID; 124 m_agentID = agentID;
123 } 125 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
index 91872c5..52c4f44 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -115,67 +115,66 @@ namespace OpenSim.Region.ClientStack.Linden
115 UUID capID = UUID.Random(); 115 UUID capID = UUID.Random();
116 116
117// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); 117// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
118 caps.RegisterHandler("NewFileAgentInventoryVariablePrice", 118 caps.RegisterHandler(
119 119 "NewFileAgentInventoryVariablePrice",
120 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST", 120 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
121 "/CAPS/" + capID.ToString(), 121 "POST",
122 delegate(LLSDAssetUploadRequest req) 122 "/CAPS/" + capID.ToString(),
123 { 123 req => NewAgentInventoryRequest(req, agentID),
124 return NewAgentInventoryRequest(req,agentID); 124 "NewFileAgentInventoryVariablePrice",
125 })); 125 agentID.ToString()));
126
127 } 126 }
128 127
129 #endregion 128 #endregion
130 129
131 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) 130 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
132 { 131 {
133
134 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit 132 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
135 // You need to be aware of this and 133 // you need to be aware of this
136
137 134
138 //if (llsdRequest.asset_type == "texture" || 135 //if (llsdRequest.asset_type == "texture" ||
139 // llsdRequest.asset_type == "animation" || 136 // llsdRequest.asset_type == "animation" ||
140 // llsdRequest.asset_type == "sound") 137 // llsdRequest.asset_type == "sound")
141 // { 138 // {
142 // check user level 139 // check user level
143 ScenePresence avatar = null;
144 IClientAPI client = null;
145 m_scene.TryGetScenePresence(agentID, out avatar);
146 140
147 if (avatar != null) 141 ScenePresence avatar = null;
142 IClientAPI client = null;
143 m_scene.TryGetScenePresence(agentID, out avatar);
144
145 if (avatar != null)
146 {
147 client = avatar.ControllingClient;
148
149 if (avatar.UserLevel < m_levelUpload)
148 { 150 {
149 client = avatar.ControllingClient; 151 if (client != null)
150 152 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
151 if (avatar.UserLevel < m_levelUpload) 153
152 { 154 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
153 if (client != null) 155 errorResponse.rsvp = "";
154 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); 156 errorResponse.state = "error";
155 157 return errorResponse;
156 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
157 errorResponse.rsvp = "";
158 errorResponse.state = "error";
159 return errorResponse;
160 }
161 } 158 }
159 }
162 160
163 // check funds 161 // check funds
164 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>(); 162 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
165 163
166 if (mm != null) 164 if (mm != null)
165 {
166 if (!mm.UploadCovered(agentID, mm.UploadCharge))
167 { 167 {
168 if (!mm.UploadCovered(agentID, mm.UploadCharge)) 168 if (client != null)
169 { 169 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
170 if (client != null) 170
171 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 171 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
172 172 errorResponse.rsvp = "";
173 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); 173 errorResponse.state = "error";
174 errorResponse.rsvp = ""; 174 return errorResponse;
175 errorResponse.state = "error";
176 return errorResponse;
177 }
178 } 175 }
176 }
177
179 // } 178 // }
180 179
181 string assetName = llsdRequest.name; 180 string assetName = llsdRequest.name;
@@ -189,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
189 AssetUploader uploader = 188 AssetUploader uploader =
190 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 189 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
191 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); 190 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
191
192 MainServer.Instance.AddStreamHandler( 192 MainServer.Instance.AddStreamHandler(
193 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); 193 new BinaryStreamHandler(
194 "POST",
195 capsBase + uploaderPath,
196 uploader.uploaderCaps,
197 "NewFileAgentInventoryVariablePrice",
198 agentID.ToString()));
194 199
195 string protocol = "http://"; 200 string protocol = "http://";
196 201
@@ -199,10 +204,9 @@ namespace OpenSim.Region.ClientStack.Linden
199 204
200 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + 205 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
201 uploaderPath; 206 uploaderPath;
202 207
203 208
204 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); 209 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
205
206 210
207 uploadResponse.rsvp = uploaderURL; 211 uploadResponse.rsvp = uploaderURL;
208 uploadResponse.state = "upload"; 212 uploadResponse.state = "upload";
@@ -220,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
220 pinventoryItem, pparentFolder, pdata, pinventoryType, 224 pinventoryItem, pparentFolder, pdata, pinventoryType,
221 passetType,agentID); 225 passetType,agentID);
222 }; 226 };
227
223 return uploadResponse; 228 return uploadResponse;
224 } 229 }
225 230
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
index 1c47f0e..4ccfc43 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden
66 66
67// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); 67// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
68 68
69 caps.RegisterHandler("ObjectAdd", 69 caps.RegisterHandler(
70 new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/", 70 "ObjectAdd",
71 delegate(Hashtable m_dhttpMethod) 71 new RestHTTPHandler(
72 { 72 "POST",
73 return ProcessAdd(m_dhttpMethod, agentID, caps); 73 "/CAPS/OA/" + capuuid + "/",
74 })); 74 httpMethod => ProcessAdd(httpMethod, agentID, caps),
75 "ObjectAdd",
76 agentID.ToString()));;
75 } 77 }
76 78
77 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) 79 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 7a3d97e..f0f3984 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden
106 UUID capID = UUID.Random(); 106 UUID capID = UUID.Random();
107 107
108// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID); 108// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
109 caps.RegisterHandler("UploadObjectAsset", 109 caps.RegisterHandler(
110 new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/", 110 "UploadObjectAsset",
111 delegate(Hashtable m_dhttpMethod) 111 new RestHTTPHandler(
112 { 112 "POST",
113 return ProcessAdd(m_dhttpMethod, agentID, caps); 113 "/CAPS/OA/" + capID + "/",
114 })); 114 httpMethod => ProcessAdd(httpMethod, agentID, caps),
115 "UploadObjectAsset",
116 agentID.ToString()));
117
115 /* 118 /*
116 caps.RegisterHandler("NewFileAgentInventoryVariablePrice", 119 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
117 120
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
index 1dd8938..8ed0fb3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden
154 public void RegisterCaps(UUID agentID, Caps caps) 154 public void RegisterCaps(UUID agentID, Caps caps)
155 { 155 {
156 IRequestHandler reqHandler 156 IRequestHandler reqHandler
157 = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest); 157 = new RestHTTPHandler(
158 "GET", "/CAPS/" + UUID.Random(),
159 HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
158 160
159 caps.RegisterHandler("SimulatorFeatures", reqHandler); 161 caps.RegisterHandler("SimulatorFeatures", reqHandler);
160 } 162 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
index 45d6071..b3d61a8 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden
106 "POST", 106 "POST",
107 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, 107 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
108 new UploadBakedTextureHandler( 108 new UploadBakedTextureHandler(
109 caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture)); 109 caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
110 "UploadBakedTexture",
111 agentID.ToString()));
110 } 112 }
111 } 113 }
112} \ No newline at end of file 114} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 10f43d1..2359bd6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden
144 capUrl = "/CAPS/" + UUID.Random(); 144 capUrl = "/CAPS/" + UUID.Random();
145 145
146 IRequestHandler reqHandler 146 IRequestHandler reqHandler
147 = new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest); 147 = new RestStreamHandler(
148 "POST",
149 capUrl,
150 m_webFetchHandler.FetchInventoryDescendentsRequest,
151 "FetchInventoryDescendents2",
152 agentID.ToString());
148 153
149 caps.RegisterHandler(capName, reqHandler); 154 caps.RegisterHandler(capName, reqHandler);
150 } 155 }
@@ -160,4 +165,4 @@ namespace OpenSim.Region.ClientStack.Linden
160// capName, capUrl, m_scene.RegionInfo.RegionName, agentID); 165// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
161 } 166 }
162 } 167 }
163} 168} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 2d46a5b..c1b5781 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -12134,21 +12134,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12134 protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID) 12134 protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
12135 { 12135 {
12136 UUID requestID = UUID.Zero; 12136 UUID requestID = UUID.Zero;
12137 if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) 12137 int sourceType = transferRequest.TransferInfo.SourceType;
12138
12139 if (sourceType == (int)SourceType.Asset)
12138 { 12140 {
12139 requestID = new UUID(transferRequest.TransferInfo.Params, 0); 12141 requestID = new UUID(transferRequest.TransferInfo.Params, 0);
12140 } 12142 }
12141 else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) 12143 else if (sourceType == (int)SourceType.SimInventoryItem)
12142 { 12144 {
12143 requestID = new UUID(transferRequest.TransferInfo.Params, 80); 12145 requestID = new UUID(transferRequest.TransferInfo.Params, 80);
12144 } 12146 }
12145 else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate) 12147 else if (sourceType == (int)SourceType.SimEstate)
12146 { 12148 {
12147 requestID = taskID; 12149 requestID = taskID;
12148 } 12150 }
12149 12151
12150 12152// m_log.DebugFormat(
12151// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12153// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12154// requestID, taskID, (SourceType)sourceType, Name);
12152 12155
12153 12156
12154 //Note, the bool returned from the below function is useless since it is always false. 12157 //Note, the bool returned from the below function is useless since it is always false.
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 75f783b..dda4444 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -916,7 +916,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
916 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; 916 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
917 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; 917 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
918 918
919 m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint); 919 m_log.DebugFormat(
920 "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}",
921 uccp.CircuitCode.Code, buffer.RemoteEndPoint);
920 922
921 remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; 923 remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
922 924
@@ -1352,7 +1354,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1352 } 1354 }
1353 else 1355 else
1354 { 1356 {
1355 m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID); 1357 m_log.DebugFormat(
1358 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1359 packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName);
1356 } 1360 }
1357 } 1361 }
1358 1362
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index a575e36..1321470 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -158,7 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
158 TestHelpers.InMethod(); 158 TestHelpers.InMethod();
159// XmlConfigurator.Configure(); 159// XmlConfigurator.Configure();
160 160
161 TestScene scene = SceneHelpers.SetupScene(); 161 TestScene scene = new SceneHelpers().SetupScene();
162 uint myCircuitCode = 123456; 162 uint myCircuitCode = 123456;
163 UUID myAgentUuid = TestHelpers.ParseTail(0x1); 163 UUID myAgentUuid = TestHelpers.ParseTail(0x1);
164 UUID mySessionUuid = TestHelpers.ParseTail(0x2); 164 UUID mySessionUuid = TestHelpers.ParseTail(0x2);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
index 1b68d68..5fcf376 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
79 79
80 J2KDecoderModule j2kdm = new J2KDecoderModule(); 80 J2KDecoderModule j2kdm = new J2KDecoderModule();
81 81
82 scene = SceneHelpers.SetupScene(); 82 SceneHelpers sceneHelpers = new SceneHelpers();
83 scene = sceneHelpers.SetupScene();
83 SceneHelpers.SetupSceneModules(scene, j2kdm); 84 SceneHelpers.SetupSceneModules(scene, j2kdm);
84 85
85 tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene); 86 tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index 6e3a58e..6e78d6d 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -111,7 +111,7 @@ namespace OpenSim.Region.ClientStack
111 server.Start(); 111 server.Start();
112 } 112 }
113 } 113 }
114 114
115 base.StartupSpecific(); 115 base.StartupSpecific();
116 } 116 }
117 117
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 127ca1d..7054825 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache
83 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); 83 private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
84 private int m_WaitOnInprogressTimeout = 3000; 84 private int m_WaitOnInprogressTimeout = 3000;
85#else 85#else
86 private List<string> m_CurrentlyWriting = new List<string>(); 86 private HashSet<string> m_CurrentlyWriting = new HashSet<string>();
87#endif 87#endif
88 88
89 private bool m_FileCacheEnabled = true; 89 private bool m_FileCacheEnabled = true;
@@ -272,7 +272,11 @@ namespace Flotsam.RegionModules.AssetCache
272 // the other thread has updated the time for us. 272 // the other thread has updated the time for us.
273 try 273 try
274 { 274 {
275 File.SetLastAccessTime(filename, DateTime.Now); 275 lock (m_CurrentlyWriting)
276 {
277 if (!m_CurrentlyWriting.Contains(filename))
278 File.SetLastAccessTime(filename, DateTime.Now);
279 }
276 } 280 }
277 catch 281 catch
278 { 282 {
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index 5adb845..c91b25f 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); 65 config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
66 66
67 m_cache = new FlotsamAssetCache(); 67 m_cache = new FlotsamAssetCache();
68 m_scene = SceneHelpers.SetupScene(); 68 m_scene = new SceneHelpers().SetupScene();
69 SceneHelpers.SetupSceneModules(m_scene, config, m_cache); 69 SceneHelpers.SetupSceneModules(m_scene, config, m_cache);
70 } 70 }
71 71
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 78ae5e9..7a91481 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private Scene m_scene; 52 private Scene m_scene;
53 private IDialogModule m_dialogModule; 53 private IInventoryAccessModule m_invAccessModule;
54 54
55 /// <summary> 55 /// <summary>
56 /// Are attachments enabled? 56 /// Are attachments enabled?
@@ -72,7 +72,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
72 public void AddRegion(Scene scene) 72 public void AddRegion(Scene scene)
73 { 73 {
74 m_scene = scene; 74 m_scene = scene;
75 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
76 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 75 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
77 76
78 if (Enabled) 77 if (Enabled)
@@ -89,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
89 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; 88 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
90 } 89 }
91 90
92 public void RegionLoaded(Scene scene) {} 91 public void RegionLoaded(Scene scene)
92 {
93 m_invAccessModule = m_scene.RequestModuleInterface<IInventoryAccessModule>();
94 }
93 95
94 public void Close() 96 public void Close()
95 { 97 {
@@ -189,7 +191,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
189 } 191 }
190 catch (Exception e) 192 catch (Exception e)
191 { 193 {
192 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); 194 UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId;
195 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}",
196 attach.ItemID, attach.AssetID, p, agentId, e.Message, e.StackTrace);
193 } 197 }
194 } 198 }
195 } 199 }
@@ -440,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
440 lock (sp.AttachmentsSyncLock) 444 lock (sp.AttachmentsSyncLock)
441 { 445 {
442 // Save avatar attachment information 446 // Save avatar attachment information
443 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); 447// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
444 448
445 bool changed = sp.Appearance.DetachAttachment(itemID); 449 bool changed = sp.Appearance.DetachAttachment(itemID);
446 if (changed && m_scene.AvatarFactory != null) 450 if (changed && m_scene.AvatarFactory != null)
@@ -520,9 +524,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
520 524
521 if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) 525 if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
522 { 526 {
523 m_log.DebugFormat( 527// m_log.DebugFormat(
524 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 528// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
525 grp.UUID, grp.AttachmentPoint); 529// grp.UUID, grp.AttachmentPoint);
526 530
527 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 531 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
528 532
@@ -553,12 +557,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
553 } 557 }
554 grp.HasGroupChanged = false; // Prevent it being saved over and over 558 grp.HasGroupChanged = false; // Prevent it being saved over and over
555 } 559 }
556 else 560// else
557 { 561// {
558 m_log.DebugFormat( 562// m_log.DebugFormat(
559 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", 563// "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
560 grp.UUID, grp.AttachmentPoint); 564// grp.UUID, grp.AttachmentPoint);
561 } 565// }
562 } 566 }
563 567
564 /// <summary> 568 /// <summary>
@@ -576,9 +580,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
576 private void AttachToAgent( 580 private void AttachToAgent(
577 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) 581 IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
578 { 582 {
579 // m_log.DebugFormat( 583// m_log.DebugFormat(
580 // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", 584// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
581 // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); 585// so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
582 586
583 so.DetachFromBackup(); 587 so.DetachFromBackup();
584 588
@@ -627,6 +631,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
627 /// <returns>The user inventory item created that holds the attachment.</returns> 631 /// <returns>The user inventory item created that holds the attachment.</returns>
628 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) 632 private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp)
629 { 633 {
634 if (m_invAccessModule == null)
635 return null;
636
630 // m_log.DebugFormat( 637 // m_log.DebugFormat(
631 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 638 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
632 // grp.Name, grp.LocalId, remoteClient.Name); 639 // grp.Name, grp.LocalId, remoteClient.Name);
@@ -700,16 +707,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
700 // sets itemID so client can show item as 'attached' in inventory 707 // sets itemID so client can show item as 'attached' in inventory
701 grp.FromItemID = item.ID; 708 grp.FromItemID = item.ID;
702 709
703 if (m_scene.AddInventoryItem(item))
704 {
705 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
706 }
707 else
708 {
709 if (m_dialogModule != null)
710 m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed");
711 }
712
713 return item; 710 return item;
714 } 711 }
715 712
@@ -758,76 +755,75 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
758 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 755 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
759 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) 756 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
760 { 757 {
761 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 758 if (m_invAccessModule == null)
762 if (invAccess != null) 759 return null;
760
761 lock (sp.AttachmentsSyncLock)
763 { 762 {
764 lock (sp.AttachmentsSyncLock) 763 SceneObjectGroup objatt;
764
765 if (itemID != UUID.Zero)
766 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
767 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
768 false, false, sp.UUID, true);
769 else
770 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
771 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
772 false, false, sp.UUID, true);
773
774 // m_log.DebugFormat(
775 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
776 // objatt.Name, remoteClient.Name, AttachmentPt);
777
778 if (objatt != null)
765 { 779 {
766 SceneObjectGroup objatt; 780 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
767 781 objatt.HasGroupChanged = false;
768 if (itemID != UUID.Zero) 782 bool tainted = false;
769 objatt = invAccess.RezObject(sp.ControllingClient, 783 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
770 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 784 tainted = true;
771 false, false, sp.UUID, true);
772 else
773 objatt = invAccess.RezObject(sp.ControllingClient,
774 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
775 false, false, sp.UUID, true);
776
777 // m_log.DebugFormat(
778 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
779 // objatt.Name, remoteClient.Name, AttachmentPt);
780
781 if (objatt != null)
782 {
783 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
784 objatt.HasGroupChanged = false;
785 bool tainted = false;
786 if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
787 tainted = true;
788
789 // This will throw if the attachment fails
790 try
791 {
792 AttachObject(sp, objatt, attachmentPt, false);
793 }
794 catch (Exception e)
795 {
796 m_log.ErrorFormat(
797 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
798 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
799
800 // Make sure the object doesn't stick around and bail
801 sp.RemoveAttachment(objatt);
802 m_scene.DeleteSceneObject(objatt, false);
803 return null;
804 }
805
806 if (tainted)
807 objatt.HasGroupChanged = true;
808
809 if (doc != null)
810 {
811 objatt.LoadScriptState(doc);
812 objatt.ResetOwnerChangeFlag();
813 }
814
815 // Fire after attach, so we don't get messy perms dialogs
816 // 4 == AttachedRez
817 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
818 objatt.ResumeScripts();
819
820 // Do this last so that event listeners have access to all the effects of the attachment
821 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
822 785
823 return objatt; 786 // This will throw if the attachment fails
787 try
788 {
789 AttachObject(sp, objatt, attachmentPt, false);
824 } 790 }
825 else 791 catch (Exception e)
792 {
793 m_log.ErrorFormat(
794 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
795 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
796
797 // Make sure the object doesn't stick around and bail
798 sp.RemoveAttachment(objatt);
799 m_scene.DeleteSceneObject(objatt, false);
800 return null;
801 }
802
803 if (doc != null)
826 { 804 {
827 m_log.WarnFormat( 805 objatt.LoadScriptState(doc);
828 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", 806 objatt.ResetOwnerChangeFlag();
829 itemID, sp.Name, attachmentPt);
830 } 807 }
808
809 if (tainted)
810 objatt.HasGroupChanged = true;
811
812 // Fire after attach, so we don't get messy perms dialogs
813 // 4 == AttachedRez
814 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
815 objatt.ResumeScripts();
816
817 // Do this last so that event listeners have access to all the effects of the attachment
818 m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
819
820 return objatt;
821 }
822 else
823 {
824 m_log.WarnFormat(
825 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
826 itemID, sp.Name, attachmentPt);
831 } 827 }
832 } 828 }
833 829
@@ -843,9 +839,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
843 /// <param name="att"></param> 839 /// <param name="att"></param>
844 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 840 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
845 { 841 {
846 // m_log.DebugFormat( 842// m_log.DebugFormat(
847 // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 843// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
848 // att.Name, sp.Name, AttachmentPt, itemID); 844// att.Name, sp.Name, AttachmentPt, itemID);
849 845
850 if (UUID.Zero == itemID) 846 if (UUID.Zero == itemID)
851 { 847 {
@@ -908,9 +904,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
908 904
909 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) 905 private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent)
910 { 906 {
911 // m_log.DebugFormat( 907// m_log.DebugFormat(
912 // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", 908// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
913 // objectLocalID, remoteClient.Name, AttachmentPt, silent); 909// objectLocalID, remoteClient.Name, AttachmentPt, silent);
914 910
915 if (!Enabled) 911 if (!Enabled)
916 return; 912 return;
@@ -946,13 +942,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
946 // Calls attach with a Zero position 942 // Calls attach with a Zero position
947 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) 943 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
948 { 944 {
949 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); 945// m_log.Debug(
946// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
947// + ", AttachmentPoint: " + AttachmentPt);
950 948
951 // Save avatar attachment information 949 // Save avatar attachment information
952 m_log.Debug( 950 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
953 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
954 + ", AttachmentPoint: " + AttachmentPt);
955
956 } 951 }
957 } 952 }
958 catch (Exception e) 953 catch (Exception e)
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index bfe5e4a..5e89eec 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
72 config.AddConfig("Modules"); 72 config.AddConfig("Modules");
73 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 73 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
74 74
75 scene = SceneHelpers.SetupScene(); 75 scene = new SceneHelpers().SetupScene();
76 m_attMod = new AttachmentsModule(); 76 m_attMod = new AttachmentsModule();
77 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); 77 SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
78 } 78 }
@@ -99,12 +99,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
99 public void TestAddAttachmentFromGround() 99 public void TestAddAttachmentFromGround()
100 { 100 {
101 TestHelpers.InMethod(); 101 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 102// TestHelpers.EnableLogging();
103 103
104 AddPresence(); 104 AddPresence();
105 string attName = "att"; 105 string attName = "att";
106 106
107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; 107 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup;
108 108
109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); 109 m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
110 110
@@ -123,6 +123,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
123 Assert.That( 123 Assert.That(
124 m_presence.Appearance.GetAttachpoint(attSo.FromItemID), 124 m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
125 Is.EqualTo((int)AttachmentPoint.Chest)); 125 Is.EqualTo((int)AttachmentPoint.Chest));
126
127 InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
128 Assert.That(attachmentItem, Is.Not.Null);
129 Assert.That(attachmentItem.Name, Is.EqualTo(attName));
130
131 InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object);
132 Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
133
134// TestHelpers.DisableLogging();
126 } 135 }
127 136
128 [Test] 137 [Test]
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 2bebd30..875c073 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
158 // Process the baked texture array 158 // Process the baked texture array
159 if (textureEntry != null) 159 if (textureEntry != null)
160 { 160 {
161 m_log.InfoFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 161// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
162 162
163// WriteBakedTexturesReport(sp, m_log.DebugFormat); 163// WriteBakedTexturesReport(sp, m_log.DebugFormat);
164 164
@@ -208,7 +208,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
208 ScenePresence sp = m_scene.GetScenePresence(agentId); 208 ScenePresence sp = m_scene.GetScenePresence(agentId);
209 if (sp == null) 209 if (sp == null)
210 { 210 {
211 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); 211 // This is expected if the user has gone away.
212// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
212 return false; 213 return false;
213 } 214 }
214 215
@@ -248,10 +249,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
248 249
249 if (bakedTextureFace == null) 250 if (bakedTextureFace == null)
250 { 251 {
251 m_log.WarnFormat( 252 // This can happen legitimately, since some baked textures might not exist
252 "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", 253 //m_log.WarnFormat(
253 bakeType, sp.Name, m_scene.RegionInfo.RegionName); 254 // "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
254 255 // bakeType, sp.Name, m_scene.RegionInfo.RegionName);
255 continue; 256 continue;
256 } 257 }
257 258
@@ -337,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
337 return false; 338 return false;
338 } 339 }
339 340
340 m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 341// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
341 342
342 // If we only found default textures, then the appearance is not cached 343 // If we only found default textures, then the appearance is not cached
343 return (defonly ? false : true); 344 return (defonly ? false : true);
@@ -370,11 +371,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
370 if (missingTexturesOnly) 371 if (missingTexturesOnly)
371 { 372 {
372 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 373 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
374 {
373 continue; 375 continue;
376 }
374 else 377 else
378 {
379 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
380 // grid asset service (which means that they are not available to the new region and so have
381 // to be re-requested from the client).
382 //
383 // The only available core OpenSimulator behaviour right now
384 // is not to store these textures, temporarily or otherwise.
375 m_log.DebugFormat( 385 m_log.DebugFormat(
376 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 386 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
377 face.TextureID, idx, sp.Name); 387 face.TextureID, idx, sp.Name);
388 }
378 } 389 }
379 else 390 else
380 { 391 {
@@ -417,7 +428,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
417// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); 428// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
418 429
419 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); 430 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
420 bakedTextures[bakeType] = faceTextures[ftIndex]; 431 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
432 bakedTextures[bakeType] = texture;
421 } 433 }
422 434
423 return bakedTextures; 435 return bakedTextures;
@@ -482,7 +494,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
482 ScenePresence sp = m_scene.GetScenePresence(agentid); 494 ScenePresence sp = m_scene.GetScenePresence(agentid);
483 if (sp == null) 495 if (sp == null)
484 { 496 {
485 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 497 // This is expected if the user has gone away.
498// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
486 return; 499 return;
487 } 500 }
488 501
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index 11a0a86..848b3bf 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
53 UUID userId = TestHelpers.ParseTail(0x1); 53 UUID userId = TestHelpers.ParseTail(0x1);
54 54
55 AvatarFactoryModule afm = new AvatarFactoryModule(); 55 AvatarFactoryModule afm = new AvatarFactoryModule();
56 TestScene scene = SceneHelpers.SetupScene(); 56 TestScene scene = new SceneHelpers().SetupScene();
57 SceneHelpers.SetupSceneModules(scene, afm); 57 SceneHelpers.SetupSceneModules(scene, afm);
58 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); 58 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
59 59
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
81 CoreAssetCache assetCache = new CoreAssetCache(); 81 CoreAssetCache assetCache = new CoreAssetCache();
82 82
83 AvatarFactoryModule afm = new AvatarFactoryModule(); 83 AvatarFactoryModule afm = new AvatarFactoryModule();
84 TestScene scene = SceneHelpers.SetupScene(assetCache); 84 TestScene scene = new SceneHelpers(assetCache).SetupScene();
85 SceneHelpers.SetupSceneModules(scene, afm); 85 SceneHelpers.SetupSceneModules(scene, afm);
86 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); 86 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
87 87
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 4d8fb90..6ffc7e6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -197,6 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
197 string fromName = c.From; 197 string fromName = c.From;
198 string fromNamePrefix = ""; 198 string fromNamePrefix = "";
199 UUID fromID = UUID.Zero; 199 UUID fromID = UUID.Zero;
200 UUID targetID = c.TargetUUID;
200 string message = c.Message; 201 string message = c.Message;
201 IScene scene = c.Scene; 202 IScene scene = c.Scene;
202 Vector3 fromPos = c.Position; 203 Vector3 fromPos = c.Position;
@@ -235,17 +236,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
235 message = message.Substring(0, 1000); 236 message = message.Substring(0, 1000);
236 237
237// m_log.DebugFormat( 238// m_log.DebugFormat(
238// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}", 239// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}",
239// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType); 240// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID);
240 241
241 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 242 HashSet<UUID> receiverIDs = new HashSet<UUID>();
242 243
243 foreach (Scene s in m_scenes) 244 foreach (Scene s in m_scenes)
244 { 245 {
245 // This should use ForEachClient, but clients don't have a position. 246 if (targetID == UUID.Zero)
246 // If camera is moved into client, then camera position can be used 247 {
247 s.ForEachRootScenePresence( 248 // This should use ForEachClient, but clients don't have a position.
248 delegate(ScenePresence presence) 249 // If camera is moved into client, then camera position can be used
250 s.ForEachRootScenePresence(
251 delegate(ScenePresence presence)
252 {
253 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false))
254 receiverIDs.Add(presence.UUID);
255 }
256 );
257 }
258 else
259 {
260 // This is a send to a specific client eg from llRegionSayTo
261 // no need to check distance etc, jand send is as say
262 ScenePresence presence = s.GetScenePresence(targetID);
263 if (presence != null && !presence.IsChildAgent)
249 { 264 {
250 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); 265 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
251 if (Presencecheck != null) 266 if (Presencecheck != null)
@@ -256,15 +271,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
256 // objects on a parcel with access restrictions 271 // objects on a parcel with access restrictions
257 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) 272 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
258 { 273 {
259 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType)) 274 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
260 receiverIDs.Add(presence.UUID); 275 receiverIDs.Add(presence.UUID);
261 } 276 }
262 } 277 }
263
264 } 278 }
265 ); 279 }
266 } 280 }
267 281
268 (scene as Scene).EventManager.TriggerOnChatToClients( 282 (scene as Scene).EventManager.TriggerOnChatToClients(
269 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 283 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
270 } 284 }
@@ -344,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
344 /// precondition</returns> 358 /// precondition</returns>
345 protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, 359 protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
346 UUID fromAgentID, string fromName, ChatTypeEnum type, 360 UUID fromAgentID, string fromName, ChatTypeEnum type,
347 string message, ChatSourceType src) 361 string message, ChatSourceType src, bool ignoreDistance)
348 { 362 {
349 // don't send stuff to child agents 363 // don't send stuff to child agents
350 if (presence.IsChildAgent) return false; 364 if (presence.IsChildAgent) return false;
@@ -355,12 +369,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
355 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 369 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
356 370
357 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 371 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
358 372
359 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 373 if (!ignoreDistance)
360 type == ChatTypeEnum.Say && dis > m_saydistance ||
361 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
362 { 374 {
363 return false; 375 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
376 type == ChatTypeEnum.Say && dis > m_saydistance ||
377 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
378 {
379 return false;
380 }
364 } 381 }
365 382
366 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 383 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 0babeb5..3a91465 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
96 ScenePresence killingAvatar = null; 96 ScenePresence killingAvatar = null;
97// string killingAvatarMessage; 97// string killingAvatarMessage;
98 98
99 // check to see if it is an NPC and just remove it
100 INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface<INPCModule>();
101 if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene))
102 {
103 return;
104 }
105
99 if (killerObjectLocalID == 0) 106 if (killerObjectLocalID == 0)
100 deadAvatarMessage = "You committed suicide!"; 107 deadAvatarMessage = "You committed suicide!";
101 else 108 else
@@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
145 catch (InvalidOperationException) 152 catch (InvalidOperationException)
146 { } 153 { }
147 154
148 deadAvatar.Health = 100; 155 deadAvatar.setHealthWithUpdate(100.0f);
149 deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); 156 deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient);
150 } 157 }
151 158
@@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
154 try 161 try
155 { 162 {
156 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 163 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
157 164 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
158 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) 165 || avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
159 { 166 {
160 avatar.Invulnerable = false; 167 avatar.Invulnerable = false;
161 } 168 }
162 else 169 else
163 { 170 {
164 avatar.Invulnerable = true; 171 avatar.Invulnerable = true;
172 if (avatar.Health < 100.0f)
173 {
174 avatar.setHealthWithUpdate(100.0f);
175 }
165 } 176 }
166 } 177 }
167 catch (Exception) 178 catch (Exception)
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index f64c161..24ec435 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
162 } 162 }
163 } 163 }
164 164
165 protected void InitModule(IConfigSource config) 165 protected virtual void InitModule(IConfigSource config)
166 { 166 {
167 IConfig friendsConfig = config.Configs["Friends"]; 167 IConfig friendsConfig = config.Configs["Friends"];
168 if (friendsConfig != null) 168 if (friendsConfig != null)
@@ -449,29 +449,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
449 /// </summary> 449 /// </summary>
450 public IClientAPI LocateClientObject(UUID agentID) 450 public IClientAPI LocateClientObject(UUID agentID)
451 { 451 {
452 Scene scene = GetClientScene(agentID);
453 if (scene != null)
454 {
455 ScenePresence presence = scene.GetScenePresence(agentID);
456 if (presence != null)
457 return presence.ControllingClient;
458 }
459
460 return null;
461 }
462
463 /// <summary>
464 /// Find the scene for an agent
465 /// </summary>
466 private Scene GetClientScene(UUID agentId)
467 {
468 lock (m_Scenes) 452 lock (m_Scenes)
469 { 453 {
470 foreach (Scene scene in m_Scenes) 454 foreach (Scene scene in m_Scenes)
471 { 455 {
472 ScenePresence presence = scene.GetScenePresence(agentId); 456 ScenePresence presence = scene.GetScenePresence(agentID);
473 if (presence != null && !presence.IsChildAgent) 457 if (presence != null && !presence.IsChildAgent)
474 return scene; 458 return presence.ControllingClient;
475 } 459 }
476 } 460 }
477 461
@@ -498,7 +482,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
498 Util.FireAndForget( 482 Util.FireAndForget(
499 delegate 483 delegate
500 { 484 {
501 m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count); 485 m_log.DebugFormat(
486 "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
487 friendList.Count, agentID, online);
488
502 // Notify about this user status 489 // Notify about this user status
503 StatusNotify(friendList, agentID, online); 490 StatusNotify(friendList, agentID, online);
504 } 491 }
@@ -515,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
515 { 502 {
516 // Try local 503 // Try local
517 if (LocalStatusNotification(userID, friendID, online)) 504 if (LocalStatusNotification(userID, friendID, online))
518 return; 505 continue;
519 506
520 // The friend is not here [as root]. Let's forward. 507 // The friend is not here [as root]. Let's forward.
521 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 508 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -523,11 +510,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
523 { 510 {
524 PresenceInfo friendSession = null; 511 PresenceInfo friendSession = null;
525 foreach (PresenceInfo pinfo in friendSessions) 512 foreach (PresenceInfo pinfo in friendSessions)
513 {
526 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 514 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
527 { 515 {
528 friendSession = pinfo; 516 friendSession = pinfo;
529 break; 517 break;
530 } 518 }
519 }
531 520
532 if (friendSession != null) 521 if (friendSession != null)
533 { 522 {
@@ -546,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
546 } 535 }
547 } 536 }
548 537
549 private void OnInstantMessage(IClientAPI client, GridInstantMessage im) 538 protected virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im)
550 { 539 {
551 if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) 540 if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered)
552 { 541 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 9a6d277..06f27e2 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 private int m_levelHGFriends = 0;
54
53 IUserManagement m_uMan; 55 IUserManagement m_uMan;
54 public IUserManagement UserManagementModule 56 public IUserManagement UserManagementModule
55 { 57 {
@@ -87,6 +89,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
87 m_StatusNotifier = new HGStatusNotifier(this); 89 m_StatusNotifier = new HGStatusNotifier(this);
88 } 90 }
89 91
92 protected override void InitModule(IConfigSource config)
93 {
94 base.InitModule(config);
95
96 // Additionally to the base method
97 IConfig friendsConfig = config.Configs["HGFriendsModule"];
98 if (friendsConfig != null)
99 {
100 m_levelHGFriends = friendsConfig.GetInt("LevelHGFriends", 0);
101
102 // TODO: read in all config variables pertaining to
103 // HG friendship permissions
104 }
105 }
106
90 #endregion 107 #endregion
91 108
92 #region IFriendsSimConnector 109 #region IFriendsSimConnector
@@ -105,6 +122,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
105 122
106 #endregion 123 #endregion
107 124
125 protected override void OnInstantMessage(IClientAPI client, GridInstantMessage im)
126 {
127 if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered)
128 {
129 // we got a friendship offer
130 UUID principalID = new UUID(im.fromAgentID);
131 UUID friendID = new UUID(im.toAgentID);
132
133 // Check if friendID is foreigner and if principalID has the permission
134 // to request friendships with foreigners. If not, return immediately.
135 if (!UserManagementModule.IsLocalGridUser(friendID))
136 {
137 ScenePresence avatar = null;
138 ((Scene)client.Scene).TryGetScenePresence(principalID, out avatar);
139
140 if (avatar == null)
141 return;
142
143 if (avatar.UserLevel < m_levelHGFriends)
144 {
145 client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false);
146 return;
147 }
148 }
149 }
150
151 base.OnInstantMessage(client, im);
152 }
153
108 protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) 154 protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
109 { 155 {
110 // Update the local cache. Yes, we need to do it right here 156 // Update the local cache. Yes, we need to do it right here
@@ -369,12 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
369 415
370 protected override void StoreBackwards(UUID friendID, UUID agentID) 416 protected override void StoreBackwards(UUID friendID, UUID agentID)
371 { 417 {
372 Boolean agentIsLocal = true; 418 bool agentIsLocal = true;
373 Boolean friendIsLocal = true; 419// bool friendIsLocal = true;
420
374 if (UserManagementModule != null) 421 if (UserManagementModule != null)
375 { 422 {
376 agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); 423 agentIsLocal = UserManagementModule.IsLocalGridUser(agentID);
377 friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); 424// friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
378 } 425 }
379 426
380 // Is the requester a local user? 427 // Is the requester a local user?
@@ -461,7 +508,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
461 { 508 {
462 friendUUI = finfo.Friend; 509 friendUUI = finfo.Friend;
463 theFriendUUID = friendUUI; 510 theFriendUUID = friendUUI;
464 UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; 511 UUID utmp = UUID.Zero;
512 string url = String.Empty;
513 string first = String.Empty;
514 string last = String.Empty;
515
465 // If it's confirming the friendship, we already have the full UUI with the secret 516 // If it's confirming the friendship, we already have the full UUI with the secret
466 if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) 517 if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
467 { 518 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index 45b4264..7a197f7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
78 config.AddConfig("FriendsService"); 78 config.AddConfig("FriendsService");
79 config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); 79 config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
80 80
81 m_scene = SceneHelpers.SetupScene(); 81 m_scene = new SceneHelpers().SetupScene();
82 m_fm = new FriendsModule(); 82 m_fm = new FriendsModule();
83 SceneHelpers.SetupSceneModules(m_scene, config, m_fm); 83 SceneHelpers.SetupSceneModules(m_scene, config, m_fm);
84 } 84 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 8560c73..6587ead 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -39,6 +39,9 @@ using OpenSim.Framework.Serialization.External;
39using OpenSim.Region.CoreModules.World.Archiver; 39using OpenSim.Region.CoreModules.World.Archiver;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using Ionic.Zlib;
43using GZipStream = Ionic.Zlib.GZipStream;
44using CompressionMode = Ionic.Zlib.CompressionMode;
42 45
43namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 46namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
44{ 47{
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
91 /// Constructor 94 /// Constructor
92 /// </summary> 95 /// </summary>
93 public InventoryArchiveWriteRequest( 96 public InventoryArchiveWriteRequest(
94 Guid id, InventoryArchiverModule module, Scene scene, 97 Guid id, InventoryArchiverModule module, Scene scene,
95 UserAccount userInfo, string invPath, string savePath) 98 UserAccount userInfo, string invPath, string savePath)
96 : this( 99 : this(
97 id, 100 id,
@@ -99,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
99 scene, 102 scene,
100 userInfo, 103 userInfo,
101 invPath, 104 invPath,
102 new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress)) 105 new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression))
103 { 106 {
104 } 107 }
105 108
@@ -107,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
107 /// Constructor 110 /// Constructor
108 /// </summary> 111 /// </summary>
109 public InventoryArchiveWriteRequest( 112 public InventoryArchiveWriteRequest(
110 Guid id, InventoryArchiverModule module, Scene scene, 113 Guid id, InventoryArchiverModule module, Scene scene,
111 UserAccount userInfo, string invPath, Stream saveStream) 114 UserAccount userInfo, string invPath, Stream saveStream)
112 { 115 {
113 m_id = id; 116 m_id = id;
@@ -125,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
125 { 128 {
126 Exception reportedException = null; 129 Exception reportedException = null;
127 bool succeeded = true; 130 bool succeeded = true;
128 131
129 try 132 try
130 { 133 {
131 m_archiveWriter.Close(); 134 m_archiveWriter.Close();
@@ -146,6 +149,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
146 149
147 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) 150 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
148 { 151 {
152 if (options.ContainsKey("exclude"))
153 {
154 if (((List<String>)options["exclude"]).Contains(inventoryItem.Name) ||
155 ((List<String>)options["exclude"]).Contains(inventoryItem.ID.ToString()))
156 {
157 if (options.ContainsKey("verbose"))
158 {
159 m_log.InfoFormat(
160 "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
161 inventoryItem.Name, inventoryItem.ID, path);
162 }
163 return;
164 }
165 }
166
149 if (options.ContainsKey("verbose")) 167 if (options.ContainsKey("verbose"))
150 m_log.InfoFormat( 168 m_log.InfoFormat(
151 "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", 169 "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
@@ -175,9 +193,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
175 /// <param name="options"></param> 193 /// <param name="options"></param>
176 /// <param name="userAccountService"></param> 194 /// <param name="userAccountService"></param>
177 protected void SaveInvFolder( 195 protected void SaveInvFolder(
178 InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, 196 InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself,
179 Dictionary<string, object> options, IUserAccountService userAccountService) 197 Dictionary<string, object> options, IUserAccountService userAccountService)
180 { 198 {
199 if (options.ContainsKey("excludefolders"))
200 {
201 if (((List<String>)options["excludefolders"]).Contains(inventoryFolder.Name) ||
202 ((List<String>)options["excludefolders"]).Contains(inventoryFolder.ID.ToString()))
203 {
204 if (options.ContainsKey("verbose"))
205 {
206 m_log.InfoFormat(
207 "[INVENTORY ARCHIVER]: Skipping folder {0} at {1}",
208 inventoryFolder.Name, path);
209 }
210 return;
211 }
212 }
213
214 if (options.ContainsKey("verbose"))
215 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name);
216
181 if (saveThisFolderItself) 217 if (saveThisFolderItself)
182 { 218 {
183 path += CreateArchiveFolderName(inventoryFolder); 219 path += CreateArchiveFolderName(inventoryFolder);
@@ -186,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
186 m_archiveWriter.WriteDir(path); 222 m_archiveWriter.WriteDir(path);
187 } 223 }
188 224
189 InventoryCollection contents 225 InventoryCollection contents
190 = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); 226 = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID);
191 227
192 foreach (InventoryFolderBase childFolder in contents.Folders) 228 foreach (InventoryFolderBase childFolder in contents.Folders)
@@ -213,16 +249,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
213 InventoryFolderBase inventoryFolder = null; 249 InventoryFolderBase inventoryFolder = null;
214 InventoryItemBase inventoryItem = null; 250 InventoryItemBase inventoryItem = null;
215 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); 251 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
216 252
217 bool saveFolderContentsOnly = false; 253 bool saveFolderContentsOnly = false;
218 254
219 // Eliminate double slashes and any leading / on the path. 255 // Eliminate double slashes and any leading / on the path.
220 string[] components 256 string[] components
221 = m_invPath.Split( 257 = m_invPath.Split(
222 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); 258 new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);
223 259
224 int maxComponentIndex = components.Length - 1; 260 int maxComponentIndex = components.Length - 1;
225 261
226 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the 262 // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
227 // folder itself. This may get more sophisicated later on 263 // folder itself. This may get more sophisicated later on
228 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) 264 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
@@ -230,13 +266,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
230 saveFolderContentsOnly = true; 266 saveFolderContentsOnly = true;
231 maxComponentIndex--; 267 maxComponentIndex--;
232 } 268 }
233 269
234 m_invPath = String.Empty; 270 m_invPath = String.Empty;
235 for (int i = 0; i <= maxComponentIndex; i++) 271 for (int i = 0; i <= maxComponentIndex; i++)
236 { 272 {
237 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; 273 m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
238 } 274 }
239 275
240 // Annoyingly Split actually returns the original string if the input string consists only of delimiters 276 // Annoyingly Split actually returns the original string if the input string consists only of delimiters
241 // Therefore if we still start with a / after the split, then we need the root folder 277 // Therefore if we still start with a / after the split, then we need the root folder
242 if (m_invPath.Length == 0) 278 if (m_invPath.Length == 0)
@@ -246,25 +282,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
246 else 282 else
247 { 283 {
248 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); 284 m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
249 List<InventoryFolderBase> candidateFolders 285 List<InventoryFolderBase> candidateFolders
250 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); 286 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath);
251 if (candidateFolders.Count > 0) 287 if (candidateFolders.Count > 0)
252 inventoryFolder = candidateFolders[0]; 288 inventoryFolder = candidateFolders[0];
253 } 289 }
254 290
255 // The path may point to an item instead 291 // The path may point to an item instead
256 if (inventoryFolder == null) 292 if (inventoryFolder == null)
257 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); 293 inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
258 294
259 if (null == inventoryFolder && null == inventoryItem) 295 if (null == inventoryFolder && null == inventoryItem)
260 { 296 {
261 // We couldn't find the path indicated 297 // We couldn't find the path indicated
262 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); 298 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
263 Exception e = new InventoryArchiverException(errorMessage); 299 Exception e = new InventoryArchiverException(errorMessage);
264 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); 300 m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
265 throw e; 301 throw e;
266 } 302 }
267 303
268 m_archiveWriter = new TarArchiveWriter(m_saveStream); 304 m_archiveWriter = new TarArchiveWriter(m_saveStream);
269 305
270 m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); 306 m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
@@ -278,10 +314,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
278 { 314 {
279 m_log.DebugFormat( 315 m_log.DebugFormat(
280 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", 316 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
281 inventoryFolder.Name, 317 inventoryFolder.Name,
282 inventoryFolder.ID, 318 inventoryFolder.ID,
283 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); 319 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
284 320
285 //recurse through all dirs getting dirs and files 321 //recurse through all dirs getting dirs and files
286 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); 322 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
287 } 323 }
@@ -290,10 +326,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
290 m_log.DebugFormat( 326 m_log.DebugFormat(
291 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", 327 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
292 inventoryItem.Name, inventoryItem.ID, m_invPath); 328 inventoryItem.Name, inventoryItem.ID, m_invPath);
293 329
294 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); 330 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
295 } 331 }
296 332
297 // Don't put all this profile information into the archive right now. 333 // Don't put all this profile information into the archive right now.
298 //SaveUsers(); 334 //SaveUsers();
299 335
@@ -352,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
352 /// 388 ///
353 /// These names are prepended with an inventory folder's UUID so that more than one folder can have the 389 /// These names are prepended with an inventory folder's UUID so that more than one folder can have the
354 /// same name 390 /// same name
355 /// 391 ///
356 /// <param name="folder"></param> 392 /// <param name="folder"></param>
357 /// <returns></returns> 393 /// <returns></returns>
358 public static string CreateArchiveFolderName(InventoryFolderBase folder) 394 public static string CreateArchiveFolderName(InventoryFolderBase folder)
@@ -366,7 +402,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
366 /// 402 ///
367 /// These names are prepended with an inventory item's UUID so that more than one item can have the 403 /// These names are prepended with an inventory item's UUID so that more than one item can have the
368 /// same name 404 /// same name
369 /// 405 ///
370 /// <param name="item"></param> 406 /// <param name="item"></param>
371 /// <returns></returns> 407 /// <returns></returns>
372 public static string CreateArchiveItemName(InventoryItemBase item) 408 public static string CreateArchiveItemName(InventoryItemBase item)
@@ -412,7 +448,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
412 public string CreateControlFile(Dictionary<string, object> options) 448 public string CreateControlFile(Dictionary<string, object> options)
413 { 449 {
414 int majorVersion, minorVersion; 450 int majorVersion, minorVersion;
415 451
416 if (options.ContainsKey("home")) 452 if (options.ContainsKey("home"))
417 { 453 {
418 majorVersion = 1; 454 majorVersion = 1;
@@ -422,10 +458,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
422 { 458 {
423 majorVersion = 0; 459 majorVersion = 0;
424 minorVersion = 3; 460 minorVersion = 3;
425 } 461 }
426 462
427 m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); 463 m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
428 464
429 StringWriter sw = new StringWriter(); 465 StringWriter sw = new StringWriter();
430 XmlTextWriter xtw = new XmlTextWriter(sw); 466 XmlTextWriter xtw = new XmlTextWriter(sw);
431 xtw.Formatting = Formatting.Indented; 467 xtw.Formatting = Formatting.Indented;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index ac22c3f..cf87010 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -47,18 +47,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
47 public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule 47 public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule
48 { 48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 public string Name { get { return "Inventory Archiver Module"; } } 51 public string Name { get { return "Inventory Archiver Module"; } }
52 52
53 public bool IsSharedModule { get { return true; } } 53 public bool IsSharedModule { get { return true; } }
54 54
55 /// <value> 55 /// <value>
56 /// Enable or disable checking whether the iar user is actually logged in 56 /// Enable or disable checking whether the iar user is actually logged in
57 /// </value> 57 /// </value>
58// public bool DisablePresenceChecks { get; set; } 58// public bool DisablePresenceChecks { get; set; }
59 59
60 public event InventoryArchiveSaved OnInventoryArchiveSaved; 60 public event InventoryArchiveSaved OnInventoryArchiveSaved;
61 61
62 /// <summary> 62 /// <summary>
63 /// The file to load and save inventory if no filename has been specified 63 /// The file to load and save inventory if no filename has been specified
64 /// </summary> 64 /// </summary>
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
68 /// Pending save completions initiated from the console 68 /// Pending save completions initiated from the console
69 /// </value> 69 /// </value>
70 protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); 70 protected List<Guid> m_pendingConsoleSaves = new List<Guid>();
71 71
72 /// <value> 72 /// <value>
73 /// All scenes that this module knows about 73 /// All scenes that this module knows about
74 /// </value> 74 /// </value>
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
106 { 106 {
107 scene.RegisterModuleInterface<IInventoryArchiverModule>(this); 107 scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
108 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; 108 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
109 109
110 scene.AddCommand( 110 scene.AddCommand(
111 "Archiving", this, "load iar", 111 "Archiving", this, "load iar",
112 "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", 112 "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
@@ -119,11 +119,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
119 + "<IAR path> is the filesystem path or URI from which to load the IAR." 119 + "<IAR path> is the filesystem path or URI from which to load the IAR."
120 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), 120 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
121 HandleLoadInvConsoleCommand); 121 HandleLoadInvConsoleCommand);
122 122
123 scene.AddCommand( 123 scene.AddCommand(
124 "Archiving", this, "save iar", 124 "Archiving", this, "save iar",
125 "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", 125 "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]",
126 "Save user inventory archive (IAR).", 126 "Save user inventory archive (IAR).",
127 "<first> is the user's first name.\n" 127 "<first> is the user's first name.\n"
128 + "<last> is the user's last name.\n" 128 + "<last> is the user's last name.\n"
129 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" 129 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
@@ -131,32 +131,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
131 + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) 131 + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
132 + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" 132 + "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
133 + "-c|--creators preserves information about foreign creators.\n" 133 + "-c|--creators preserves information about foreign creators.\n"
134 + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
135 + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
134 + "-v|--verbose extra debug messages.\n" 136 + "-v|--verbose extra debug messages.\n"
135 + "--noassets stops assets being saved to the IAR.", 137 + "--noassets stops assets being saved to the IAR.",
136 HandleSaveInvConsoleCommand); 138 HandleSaveInvConsoleCommand);
137 139
138 m_aScene = scene; 140 m_aScene = scene;
139 } 141 }
140 142
141 m_scenes[scene.RegionInfo.RegionID] = scene; 143 m_scenes[scene.RegionInfo.RegionID] = scene;
142 } 144 }
143 145
144 public void PostInitialise() {} 146 public void PostInitialise() {}
145 147
146 public void Close() {} 148 public void Close() {}
147 149
148 /// <summary> 150 /// <summary>
149 /// Trigger the inventory archive saved event. 151 /// Trigger the inventory archive saved event.
150 /// </summary> 152 /// </summary>
151 protected internal void TriggerInventoryArchiveSaved( 153 protected internal void TriggerInventoryArchiveSaved(
152 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 154 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
153 Exception reportedException) 155 Exception reportedException)
154 { 156 {
155 InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; 157 InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
156 if (handlerInventoryArchiveSaved != null) 158 if (handlerInventoryArchiveSaved != null)
157 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); 159 handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
158 } 160 }
159 161
160 public bool ArchiveInventory( 162 public bool ArchiveInventory(
161 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) 163 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
162 { 164 {
@@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
164 } 166 }
165 167
166 public bool ArchiveInventory( 168 public bool ArchiveInventory(
167 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, 169 Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
168 Dictionary<string, object> options) 170 Dictionary<string, object> options)
169 { 171 {
170 if (m_scenes.Count > 0) 172 if (m_scenes.Count > 0)
@@ -188,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
188 190
189 return false; 191 return false;
190 } 192 }
191 193
192 return true; 194 return true;
193// } 195// }
194// else 196// else
@@ -202,15 +204,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
202 204
203 return false; 205 return false;
204 } 206 }
205 207
206 public bool ArchiveInventory( 208 public bool ArchiveInventory(
207 Guid id, string firstName, string lastName, string invPath, string pass, string savePath, 209 Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
208 Dictionary<string, object> options) 210 Dictionary<string, object> options)
209 { 211 {
210 if (m_scenes.Count > 0) 212 if (m_scenes.Count > 0)
211 { 213 {
212 UserAccount userInfo = GetUserInfo(firstName, lastName, pass); 214 UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
213 215
214 if (userInfo != null) 216 if (userInfo != null)
215 { 217 {
216// if (CheckPresence(userInfo.PrincipalID)) 218// if (CheckPresence(userInfo.PrincipalID))
@@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
228 230
229 return false; 231 return false;
230 } 232 }
231 233
232 return true; 234 return true;
233// } 235// }
234// else 236// else
@@ -239,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
239// } 241// }
240 } 242 }
241 } 243 }
242 244
243 return false; 245 return false;
244 } 246 }
245 247
@@ -247,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
247 { 249 {
248 return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); 250 return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
249 } 251 }
250 252
251 public bool DearchiveInventory( 253 public bool DearchiveInventory(
252 string firstName, string lastName, string invPath, string pass, Stream loadStream, 254 string firstName, string lastName, string invPath, string pass, Stream loadStream,
253 Dictionary<string, object> options) 255 Dictionary<string, object> options)
254 { 256 {
255 if (m_scenes.Count > 0) 257 if (m_scenes.Count > 0)
@@ -295,22 +297,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
295 297
296 return false; 298 return false;
297 } 299 }
298 300
299 public bool DearchiveInventory( 301 public bool DearchiveInventory(
300 string firstName, string lastName, string invPath, string pass, string loadPath, 302 string firstName, string lastName, string invPath, string pass, string loadPath,
301 Dictionary<string, object> options) 303 Dictionary<string, object> options)
302 { 304 {
303 if (m_scenes.Count > 0) 305 if (m_scenes.Count > 0)
304 { 306 {
305 UserAccount userInfo = GetUserInfo(firstName, lastName, pass); 307 UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
306 308
307 if (userInfo != null) 309 if (userInfo != null)
308 { 310 {
309// if (CheckPresence(userInfo.PrincipalID)) 311// if (CheckPresence(userInfo.PrincipalID))
310// { 312// {
311 InventoryArchiveReadRequest request; 313 InventoryArchiveReadRequest request;
312 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); 314 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
313 315
314 try 316 try
315 { 317 {
316 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); 318 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge);
@@ -324,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
324 326
325 return false; 327 return false;
326 } 328 }
327 329
328 UpdateClientWithLoadedNodes(userInfo, request.Execute()); 330 UpdateClientWithLoadedNodes(userInfo, request.Execute());
329 331
330 return true; 332 return true;
@@ -340,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
340 342
341 return false; 343 return false;
342 } 344 }
343 345
344 /// <summary> 346 /// <summary>
345 /// Load inventory from an inventory file archive 347 /// Load inventory from an inventory file archive
346 /// </summary> 348 /// </summary>
@@ -351,26 +353,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
351 { 353 {
352 Dictionary<string, object> options = new Dictionary<string, object>(); 354 Dictionary<string, object> options = new Dictionary<string, object>();
353 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); 355 OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
354 356
355 List<string> mainParams = optionSet.Parse(cmdparams); 357 List<string> mainParams = optionSet.Parse(cmdparams);
356 358
357 if (mainParams.Count < 6) 359 if (mainParams.Count < 6)
358 { 360 {
359 m_log.Error( 361 m_log.Error(
360 "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); 362 "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]");
361 return; 363 return;
362 } 364 }
363 365
364 string firstName = mainParams[2]; 366 string firstName = mainParams[2];
365 string lastName = mainParams[3]; 367 string lastName = mainParams[3];
366 string invPath = mainParams[4]; 368 string invPath = mainParams[4];
367 string pass = mainParams[5]; 369 string pass = mainParams[5];
368 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); 370 string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
369 371
370 m_log.InfoFormat( 372 m_log.InfoFormat(
371 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", 373 "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
372 loadPath, invPath, firstName, lastName); 374 loadPath, invPath, firstName, lastName);
373 375
374 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) 376 if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
375 m_log.InfoFormat( 377 m_log.InfoFormat(
376 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", 378 "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
@@ -381,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
381 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); 383 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
382 } 384 }
383 } 385 }
384 386
385 /// <summary> 387 /// <summary>
386 /// Save inventory to a file archive 388 /// Save inventory to a file archive
387 /// </summary> 389 /// </summary>
@@ -398,6 +400,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
398 ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); 400 ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
399 ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); 401 ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
400 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); 402 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
403 ops.Add("e|exclude=", delegate(string v)
404 {
405 if (!options.ContainsKey("exclude"))
406 options["exclude"] = new List<String>();
407 ((List<String>)options["exclude"]).Add(v);
408 });
409 ops.Add("f|excludefolder=", delegate(string v)
410 {
411 if (!options.ContainsKey("excludefolders"))
412 options["excludefolders"] = new List<String>();
413 ((List<String>)options["excludefolders"]).Add(v);
414 });
401 415
402 List<string> mainParams = ops.Parse(cmdparams); 416 List<string> mainParams = ops.Parse(cmdparams);
403 417
@@ -406,10 +420,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
406 if (mainParams.Count < 6) 420 if (mainParams.Count < 6)
407 { 421 {
408 m_log.Error( 422 m_log.Error(
409 "[INVENTORY ARCHIVER]: usage is save iar [-h|--home=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>] [-c|--creators] [-v|--verbose]"); 423 "[INVENTORY ARCHIVER]: save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]");
410 return; 424 return;
411 } 425 }
412 426
413 if (options.ContainsKey("home")) 427 if (options.ContainsKey("home"))
414 m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); 428 m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR");
415 429
@@ -418,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
418 string invPath = mainParams[4]; 432 string invPath = mainParams[4];
419 string pass = mainParams[5]; 433 string pass = mainParams[5];
420 string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); 434 string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
421 435
422 m_log.InfoFormat( 436 m_log.InfoFormat(
423 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", 437 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
424 savePath, invPath, firstName, lastName); 438 savePath, invPath, firstName, lastName);
@@ -433,9 +447,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
433 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); 447 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
434 } 448 }
435 } 449 }
436 450
437 private void SaveInvConsoleCommandCompleted( 451 private void SaveInvConsoleCommandCompleted(
438 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 452 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
439 Exception reportedException) 453 Exception reportedException)
440 { 454 {
441 lock (m_pendingConsoleSaves) 455 lock (m_pendingConsoleSaves)
@@ -445,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
445 else 459 else
446 return; 460 return;
447 } 461 }
448 462
449 if (succeeded) 463 if (succeeded)
450 { 464 {
451 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); 465 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName);
@@ -453,11 +467,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
453 else 467 else
454 { 468 {
455 m_log.ErrorFormat( 469 m_log.ErrorFormat(
456 "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", 470 "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}",
457 userInfo.FirstName, userInfo.LastName, reportedException.Message); 471 userInfo.FirstName, userInfo.LastName, reportedException.Message);
458 } 472 }
459 } 473 }
460 474
461 /// <summary> 475 /// <summary>
462 /// Get user information for the given name. 476 /// Get user information for the given name.
463 /// </summary> 477 /// </summary>
@@ -467,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
467 /// <returns></returns> 481 /// <returns></returns>
468 protected UserAccount GetUserInfo(string firstName, string lastName, string pass) 482 protected UserAccount GetUserInfo(string firstName, string lastName, string pass)
469 { 483 {
470 UserAccount account 484 UserAccount account
471 = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); 485 = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName);
472 486
473 if (null == account) 487 if (null == account)
474 { 488 {
475 m_log.ErrorFormat( 489 m_log.ErrorFormat(
476 "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", 490 "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}",
477 firstName, lastName); 491 firstName, lastName);
478 return null; 492 return null;
479 } 493 }
@@ -488,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
488 else 502 else
489 { 503 {
490 m_log.ErrorFormat( 504 m_log.ErrorFormat(
491 "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", 505 "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.",
492 firstName, lastName); 506 firstName, lastName);
493 return null; 507 return null;
494 } 508 }
@@ -499,7 +513,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
499 return null; 513 return null;
500 } 514 }
501 } 515 }
502 516
503 /// <summary> 517 /// <summary>
504 /// Notify the client of loaded nodes if they are logged in 518 /// Notify the client of loaded nodes if they are logged in
505 /// </summary> 519 /// </summary>
@@ -508,22 +522,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
508 { 522 {
509 if (loadedNodes.Count == 0) 523 if (loadedNodes.Count == 0)
510 return; 524 return;
511 525
512 foreach (Scene scene in m_scenes.Values) 526 foreach (Scene scene in m_scenes.Values)
513 { 527 {
514 ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); 528 ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID);
515 529
516 if (user != null && !user.IsChildAgent) 530 if (user != null && !user.IsChildAgent)
517 { 531 {
518 foreach (InventoryNodeBase node in loadedNodes) 532 foreach (InventoryNodeBase node in loadedNodes)
519 { 533 {
520// m_log.DebugFormat( 534// m_log.DebugFormat(
521// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", 535// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}",
522// user.Name, node.Name); 536// user.Name, node.Name);
523 537
524 user.ControllingClient.SendBulkUpdateInventory(node); 538 user.ControllingClient.SendBulkUpdateInventory(node);
525 } 539 }
526 540
527 break; 541 break;
528 } 542 }
529 } 543 }
@@ -538,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
538// { 552// {
539// if (DisablePresenceChecks) 553// if (DisablePresenceChecks)
540// return true; 554// return true;
541// 555//
542// foreach (Scene scene in m_scenes.Values) 556// foreach (Scene scene in m_scenes.Values)
543// { 557// {
544// ScenePresence p; 558// ScenePresence p;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index 19ef571..90ae69d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
100// log4net.Config.XmlConfigurator.Configure(); 100// log4net.Config.XmlConfigurator.Configure();
101 101
102 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 102 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
103 Scene scene = SceneHelpers.SetupScene(); 103 Scene scene = new SceneHelpers().SetupScene();
104 SceneHelpers.SetupSceneModules(scene, archiverModule); 104 SceneHelpers.SetupSceneModules(scene, archiverModule);
105 105
106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); 106 UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index e409c8e..b112b6d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
61 SerialiserModule serialiserModule = new SerialiserModule(); 61 SerialiserModule serialiserModule = new SerialiserModule();
62 m_archiverModule = new InventoryArchiverModule(); 62 m_archiverModule = new InventoryArchiverModule();
63 63
64 m_scene = SceneHelpers.SetupScene(); 64 m_scene = new SceneHelpers().SetupScene();
65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); 65 SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
66 } 66 }
67 67
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
index 417c20c..6eb3605 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs
@@ -62,7 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
62 62
63 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 63 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
64 64
65 Scene scene = SceneHelpers.SetupScene(); 65 Scene scene = new SceneHelpers().SetupScene();
66 SceneHelpers.SetupSceneModules(scene, archiverModule); 66 SceneHelpers.SetupSceneModules(scene, archiverModule);
67 67
68 // Create user 68 // Create user
@@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
179 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 179 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
180 180
181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene 181 // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
182 Scene scene = SceneHelpers.SetupScene(); 182 Scene scene = new SceneHelpers().SetupScene();
183 183
184 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 184 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
185 185
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
222 222
223 SerialiserModule serialiserModule = new SerialiserModule(); 223 SerialiserModule serialiserModule = new SerialiserModule();
224 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 224 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
225 Scene scene = SceneHelpers.SetupScene(); 225 Scene scene = new SceneHelpers().SetupScene();
226 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 226 SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
227 227
228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); 228 UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
@@ -247,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
247 247
248 InventoryArchiverModule archiverModule = new InventoryArchiverModule(); 248 InventoryArchiverModule archiverModule = new InventoryArchiverModule();
249 249
250 Scene scene = SceneHelpers.SetupScene(); 250 Scene scene = new SceneHelpers().SetupScene();
251 SceneHelpers.SetupSceneModules(scene, archiverModule); 251 SceneHelpers.SetupSceneModules(scene, archiverModule);
252 252
253 // Create user 253 // Create user
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
326 TestHelpers.InMethod(); 326 TestHelpers.InMethod();
327// log4net.Config.XmlConfigurator.Configure(); 327// log4net.Config.XmlConfigurator.Configure();
328 328
329 Scene scene = SceneHelpers.SetupScene(); 329 Scene scene = new SceneHelpers().SetupScene();
330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 330 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
331 331
332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); 332 Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
@@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
393 TestHelpers.InMethod(); 393 TestHelpers.InMethod();
394 //log4net.Config.XmlConfigurator.Configure(); 394 //log4net.Config.XmlConfigurator.Configure();
395 395
396 Scene scene = SceneHelpers.SetupScene(); 396 Scene scene = new SceneHelpers().SetupScene();
397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 397 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
398 398
399 string folder1ExistingName = "a"; 399 string folder1ExistingName = "a";
@@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
444 TestHelpers.InMethod(); 444 TestHelpers.InMethod();
445// log4net.Config.XmlConfigurator.Configure(); 445// log4net.Config.XmlConfigurator.Configure();
446 446
447 Scene scene = SceneHelpers.SetupScene(); 447 Scene scene = new SceneHelpers().SetupScene();
448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); 448 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
449 449
450 string folder1ExistingName = "a"; 450 string folder1ExistingName = "a";
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index bc5c1ff..92cf9d1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -240,13 +240,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
240 { 240 {
241 ScenePresence sp = scene.GetScenePresence(client.AgentId); 241 ScenePresence sp = scene.GetScenePresence(client.AgentId);
242 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); 242 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
243 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); 243
244 if (transferMod != null && sp != null && eq != null) 244 if (transferMod != null && sp != null)
245 transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); 245 transferMod.DoTeleport(
246 sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f),
247 Vector3.UnitX, teleportflags);
246 } 248 }
247 } 249 }
248 } 250 }
249 } 251 }
250 } 252 }
251 } 253 }
252} 254} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index dcfdf8f..a889984 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -151,6 +151,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
151 Scene scene = (Scene)(client.Scene); 151 Scene scene = (Scene)(client.Scene);
152 ScenePresence presence = scene.GetScenePresence(client.AgentId); 152 ScenePresence presence = scene.GetScenePresence(client.AgentId);
153 153
154 // Round up Z co-ordinate rather than round-down by casting. This stops tall avatars from being given
155 // a teleport Z co-ordinate by short avatars that drops them through or embeds them in thin floors on
156 // arrival.
157 //
158 // Ideally we would give the exact float position adjusting for the relative height of the two avatars
159 // but it looks like a float component isn't possible with a parcel ID.
154 UUID dest = Util.BuildFakeParcelID( 160 UUID dest = Util.BuildFakeParcelID(
155 scene.RegionInfo.RegionHandle, 161 scene.RegionInfo.RegionHandle,
156 (uint)presence.AbsolutePosition.X, 162 (uint)presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 2b790f4..5d9d67f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -30,7 +30,6 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Reflection; 31using System.Reflection;
32using System.Threading; 32using System.Threading;
33
34using OpenSim.Framework; 33using OpenSim.Framework;
35using OpenSim.Framework.Capabilities; 34using OpenSim.Framework.Capabilities;
36using OpenSim.Framework.Client; 35using OpenSim.Framework.Client;
@@ -47,29 +46,58 @@ using Nini.Config;
47 46
48namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 47namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
49{ 48{
50 public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule 49 /// <summary>
50 /// The possible states that an agent can be in when its being transferred between regions.
51 /// </summary>
52 /// <remarks>
53 /// This is a state machine.
54 ///
55 /// [Entry] => Preparing
56 /// Preparing => { Transferring || CleaningUp || [Exit] }
57 /// Transferring => { ReceivedAtDestination || CleaningUp }
58 /// ReceivedAtDestination => CleaningUp
59 /// CleaningUp => [Exit]
60 ///
61 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
62 /// However, any state can transition to CleaningUp if the teleport has failed.
63 /// </remarks>
64 enum AgentTransferState
65 {
66 Preparing, // The agent is being prepared for transfer
67 Transferring, // The agent is in the process of being transferred to a destination
68 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
69 CleaningUp // The agent is being changed to child/removed after a transfer
70 }
71
72 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
51 { 73 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 74 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 75
76 public const int DefaultMaxTransferDistance = 4095;
77 public const bool EnableWaitForCallbackFromTeleportDestDefault = true;
78
54 /// <summary> 79 /// <summary>
55 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. 80 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
56 /// </summary> 81 /// </summary>
57 private int m_MaxTransferDistance = 4095; 82 public int MaxTransferDistance { get; set; }
58 public int MaxTransferDistance
59 {
60 get { return m_MaxTransferDistance; }
61 set { m_MaxTransferDistance = value; }
62 }
63 83
64 private int m_levelHGTeleport = 0; 84 /// <summary>
85 /// If true then on a teleport, the source region waits for a callback from the destination region. If
86 /// a callback fails to arrive within a set time then the user is pulled back into the source region.
87 /// </summary>
88 public bool EnableWaitForCallbackFromTeleportDest { get; set; }
65 89
66 protected bool m_Enabled = false; 90 protected bool m_Enabled = false;
67 protected Scene m_aScene; 91
68 protected List<Scene> m_Scenes = new List<Scene>(); 92 protected Scene m_scene;
69 protected List<UUID> m_agentsInTransit; 93
94 private Dictionary<UUID, AgentTransferState> m_agentsInTransit;
95
70 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = 96 private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
71 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 97 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
72 98
99 private IEventQueue m_eqModule;
100
73 #region ISharedRegionModule 101 #region ISharedRegionModule
74 102
75 public Type ReplaceableInterface 103 public Type ReplaceableInterface
@@ -105,11 +133,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
105 IConfig transferConfig = source.Configs["EntityTransfer"]; 133 IConfig transferConfig = source.Configs["EntityTransfer"];
106 if (transferConfig != null) 134 if (transferConfig != null)
107 { 135 {
108 MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); 136 EnableWaitForCallbackFromTeleportDest
109 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); 137 = transferConfig.GetBoolean("wait_for_callback", EnableWaitForCallbackFromTeleportDestDefault);
138
139 MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance);
140 }
141 else
142 {
143 MaxTransferDistance = DefaultMaxTransferDistance;
110 } 144 }
111 145
112 m_agentsInTransit = new List<UUID>(); 146 m_agentsInTransit = new Dictionary<UUID, AgentTransferState>();
113 m_Enabled = true; 147 m_Enabled = true;
114 } 148 }
115 149
@@ -122,10 +156,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
122 if (!m_Enabled) 156 if (!m_Enabled)
123 return; 157 return;
124 158
125 if (m_aScene == null) 159 m_scene = scene;
126 m_aScene = scene;
127 160
128 m_Scenes.Add(scene);
129 scene.RegisterModuleInterface<IEntityTransferModule>(this); 161 scene.RegisterModuleInterface<IEntityTransferModule>(this);
130 scene.EventManager.OnNewClient += OnNewClient; 162 scene.EventManager.OnNewClient += OnNewClient;
131 } 163 }
@@ -136,26 +168,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
136 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 168 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
137 } 169 }
138 170
139 public virtual void Close() 171 public virtual void Close() {}
140 {
141 if (!m_Enabled)
142 return;
143 }
144
145 public virtual void RemoveRegion(Scene scene)
146 {
147 if (!m_Enabled)
148 return;
149 if (scene == m_aScene)
150 m_aScene = null;
151 172
152 m_Scenes.Remove(scene); 173 public virtual void RemoveRegion(Scene scene) {}
153 }
154 174
155 public virtual void RegionLoaded(Scene scene) 175 public virtual void RegionLoaded(Scene scene)
156 { 176 {
157 if (!m_Enabled) 177 if (!m_Enabled)
158 return; 178 return;
179
180 m_eqModule = m_scene.RequestModuleInterface<IEventQueue>();
159 } 181 }
160 182
161 #endregion 183 #endregion
@@ -164,170 +186,257 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
164 186
165 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 187 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
166 { 188 {
189 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
190 {
191 // This user will be a God in the destination scene, too
192 teleportFlags |= (uint)TeleportFlags.Godlike;
193 }
194
167 if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) 195 if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
168 return; 196 return;
169 197
170 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
171
172 // Reset animations; the viewer does that in teleports. 198 // Reset animations; the viewer does that in teleports.
173 sp.Animator.ResetAnimations(); 199 sp.Animator.ResetAnimations();
174 200
201 string destinationRegionName = "(not found)";
202
175 try 203 try
176 { 204 {
177 if (regionHandle == sp.Scene.RegionInfo.RegionHandle) 205 if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
178 { 206 {
179 m_log.DebugFormat( 207 destinationRegionName = sp.Scene.RegionInfo.RegionName;
180 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}",
181 position, sp.Scene.RegionInfo.RegionName);
182 208
183 // Teleport within the same region 209 TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags);
184 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 210 }
185 { 211 else // Another region possibly in another simulator
186 Vector3 emergencyPos = new Vector3(128, 128, 128); 212 {
213 GridRegion finalDestination;
214 TeleportAgentToDifferentRegion(
215 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
187 216
188 m_log.WarnFormat( 217 if (finalDestination != null)
189 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 218 destinationRegionName = finalDestination.RegionName;
190 position, sp.Name, sp.UUID, emergencyPos); 219 }
191 position = emergencyPos; 220 }
192 } 221 catch (Exception e)
222 {
223 m_log.ErrorFormat(
224 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
225 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
226 e.Message, e.StackTrace);
193 227
194 // TODO: Get proper AVG Height 228 // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail.
195 float localAVHeight = 1.56f; 229 ResetFromTransit(sp.UUID);
196 float posZLimit = 22;
197 230
198 // TODO: Check other Scene HeightField 231 sp.ControllingClient.SendTeleportFailed("Internal error");
199 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) 232 }
200 { 233 }
201 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
202 }
203 234
204 float newPosZ = posZLimit + localAVHeight; 235 /// <summary>
205 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 236 /// Teleports the agent within its current region.
206 { 237 /// </summary>
207 position.Z = newPosZ; 238 /// <param name="sp"></param>
208 } 239 /// <param name="position"></param>
240 /// <param name="lookAt"></param>
241 /// <param name="teleportFlags"></param
242 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
243 {
244 m_log.DebugFormat(
245 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
246 sp.Name, position, sp.Scene.RegionInfo.RegionName);
247
248 if (!SetInTransit(sp.UUID))
249 {
250 m_log.DebugFormat(
251 "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.",
252 sp.Name, sp.UUID, position);
209 253
210 sp.ControllingClient.SendTeleportStart(teleportFlags); 254 return;
255 }
256
257 // Teleport within the same region
258 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0)
259 {
260 Vector3 emergencyPos = new Vector3(128, 128, 128);
211 261
212 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 262 m_log.WarnFormat(
213 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; 263 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
214 sp.Teleport(position); 264 position, sp.Name, sp.UUID, emergencyPos);
215 265
216 foreach (SceneObjectGroup grp in sp.GetAttachments()) 266 position = emergencyPos;
217 { 267 }
218 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); 268
219 } 269 // TODO: Get proper AVG Height
270 float localAVHeight = 1.56f;
271 float posZLimit = 22;
272
273 // TODO: Check other Scene HeightField
274 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize)
275 {
276 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
277 }
278
279 float newPosZ = posZLimit + localAVHeight;
280 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
281 {
282 position.Z = newPosZ;
283 }
284
285 UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
286
287 sp.ControllingClient.SendTeleportStart(teleportFlags);
288
289 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
290 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
291 sp.Velocity = Vector3.Zero;
292 sp.Teleport(position);
293
294 UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination);
295
296 foreach (SceneObjectGroup grp in sp.GetAttachments())
297 {
298 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
299 }
300
301 UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
302 ResetFromTransit(sp.UUID);
303 }
304
305 /// <summary>
306 /// Teleports the agent to a different region.
307 /// </summary>
308 /// <param name='sp'></param>
309 /// <param name='regionHandle'>/param>
310 /// <param name='position'></param>
311 /// <param name='lookAt'></param>
312 /// <param name='teleportFlags'></param>
313 /// <param name='finalDestination'></param>
314 private void TeleportAgentToDifferentRegion(
315 ScenePresence sp, ulong regionHandle, Vector3 position,
316 Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination)
317 {
318 uint x = 0, y = 0;
319 Utils.LongToUInts(regionHandle, out x, out y);
320 GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y);
321
322 if (reg != null)
323 {
324 finalDestination = GetFinalDestination(reg);
325
326 if (finalDestination == null)
327 {
328 m_log.WarnFormat(
329 "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}",
330 sp.Name, sp.UUID);
331
332 sp.ControllingClient.SendTeleportFailed("Problem at destination");
333 return;
220 } 334 }
221 else // Another region possibly in another simulator 335
336 // Check that these are not the same coordinates
337 if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX &&
338 finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY)
222 { 339 {
223 uint x = 0, y = 0; 340 // Can't do. Viewer crashes
224 Utils.LongToUInts(regionHandle, out x, out y); 341 sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again.");
225 GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); 342 return;
343 }
226 344
227 if (reg != null) 345 //
228 { 346 // This is it
229 GridRegion finalDestination = GetFinalDestination(reg); 347 //
230 if (finalDestination == null) 348 DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags);
231 { 349 //
232 m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); 350 //
233 sp.ControllingClient.SendTeleportFailed("Problem at destination"); 351 //
234 return; 352 }
235 } 353 else
354 {
355 finalDestination = null;
236 356
237 // check if HyperGrid teleport is allowed, based on user level 357 // TP to a place that doesn't exist (anymore)
238 int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID); 358 // Inform the viewer about that
359 sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
239 360
240 if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport)) 361 // and set the map-tile to '(Offline)'
241 { 362 uint regX, regY;
242 m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); 363 Utils.LongToUInts(regionHandle, out regX, out regY);
243 sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted");
244 return;
245 }
246 364
247 uint curX = 0, curY = 0; 365 MapBlockData block = new MapBlockData();
248 Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); 366 block.X = (ushort)(regX / Constants.RegionSize);
249 int curCellX = (int)(curX / Constants.RegionSize); 367 block.Y = (ushort)(regY / Constants.RegionSize);
250 int curCellY = (int)(curY / Constants.RegionSize); 368 block.Access = 254; // == not there
251 int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize);
252 int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize);
253 369
370 List<MapBlockData> blocks = new List<MapBlockData>();
371 blocks.Add(block);
372 sp.ControllingClient.SendMapBlock(blocks, 0);
373 }
374 }
375
376 /// <summary>
377 /// Determines whether this instance is within the max transfer distance.
378 /// </summary>
379 /// <param name="sourceRegion"></param>
380 /// <param name="destRegion"></param>
381 /// <returns>
382 /// <c>true</c> if this instance is within max transfer distance; otherwise, <c>false</c>.
383 /// </returns>
384 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
385 {
254// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); 386// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
255// 387//
256// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", 388// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
257// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); 389// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
258 390
259 // Check that these are not the same coordinates 391 // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position.
260 if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && 392 return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance
261 finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) 393 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
262 { 394 }
263 // Can't do. Viewer crashes
264 sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again.");
265 return;
266 }
267
268 if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance)
269 {
270 sp.ControllingClient.SendTeleportFailed(
271 string.Format(
272 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
273 finalDestination.RegionName, destCellX, destCellY,
274 sp.Scene.RegionInfo.RegionName, curCellX, curCellY,
275 MaxTransferDistance));
276
277 return;
278 }
279 395
280 // 396 public void DoTeleport(
281 // This is it 397 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
282 // 398 Vector3 position, Vector3 lookAt, uint teleportFlags)
283 DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); 399 {
284 // 400 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
285 // 401 // of whether the destination region completes the teleport.
286 // 402 if (!SetInTransit(sp.UUID))
287 }
288 else
289 {
290 // TP to a place that doesn't exist (anymore)
291 // Inform the viewer about that
292 sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
293
294 // and set the map-tile to '(Offline)'
295 uint regX, regY;
296 Utils.LongToUInts(regionHandle, out regX, out regY);
297
298 MapBlockData block = new MapBlockData();
299 block.X = (ushort)(regX / Constants.RegionSize);
300 block.Y = (ushort)(regY / Constants.RegionSize);
301 block.Access = 254; // == not there
302
303 List<MapBlockData> blocks = new List<MapBlockData>();
304 blocks.Add(block);
305 sp.ControllingClient.SendMapBlock(blocks, 0);
306 }
307 }
308 }
309 catch (Exception e)
310 { 403 {
311 m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0} {1}", e.Message, e.StackTrace); 404 m_log.DebugFormat(
312 sp.ControllingClient.SendTeleportFailed("Internal error"); 405 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
406 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
407
408 return;
313 } 409 }
314 }
315 410
316 public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
317 {
318 if (reg == null || finalDestination == null) 411 if (reg == null || finalDestination == null)
319 { 412 {
320 sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); 413 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
321 return; 414 ResetFromTransit(sp.UUID);
322 }
323 415
324 if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
325 return; 416 return;
417 }
326 418
327 m_log.DebugFormat( 419 m_log.DebugFormat(
328 "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", 420 "[ENTITY TRANSFER MODULE]: Teleporting {0} {1} from {2} to {3} ({4}) {5}/{6}",
421 sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName,
329 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); 422 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
330 423
424 RegionInfo sourceRegion = sp.Scene.RegionInfo;
425
426 if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination))
427 {
428 sp.ControllingClient.SendTeleportFailed(
429 string.Format(
430 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
431 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
432 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
433 MaxTransferDistance));
434
435 ResetFromTransit(sp.UUID);
436
437 return;
438 }
439
331 uint newRegionX = (uint)(reg.RegionHandle >> 40); 440 uint newRegionX = (uint)(reg.RegionHandle >> 40);
332 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); 441 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
333 uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); 442 uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40);
@@ -341,15 +450,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
341 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 450 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
342 if (endPoint != null && endPoint.Address != null) 451 if (endPoint != null && endPoint.Address != null)
343 { 452 {
344 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 453 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
345 // both regions 454 ResetFromTransit(sp.UUID);
346 if (sp.ParentID != (uint)0)
347 sp.StandUp();
348 455
349 if (!sp.ValidateAttachments()) 456 return;
350 m_log.DebugFormat( 457 }
351 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 458
352 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 459 if (!sp.ValidateAttachments())
460 m_log.DebugFormat(
461 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
462 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
353 463
354// if (!sp.ValidateAttachments()) 464// if (!sp.ValidateAttachments())
355// { 465// {
@@ -357,194 +467,219 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
357// return; 467// return;
358// } 468// }
359 469
360 string reason; 470 string reason;
361 string version; 471 string version;
362 if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) 472 if (!m_scene.SimulationService.QueryAccess(
363 { 473 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
364 sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); 474 {
365 return; 475 sp.ControllingClient.SendTeleportFailed(reason);
366 } 476 ResetFromTransit(sp.UUID);
367 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
368
369 sp.ControllingClient.SendTeleportStart(teleportFlags);
370
371 // the avatar.Close below will clear the child region list. We need this below for (possibly)
372 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
373 //List<ulong> childRegions = avatar.KnownRegionHandles;
374 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
375 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
376 // once we reach here...
377 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
378
379 string capsPath = String.Empty;
380
381 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
382 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
383 agentCircuit.startpos = position;
384 agentCircuit.child = true;
385 agentCircuit.Appearance = sp.Appearance;
386 if (currentAgentCircuit != null)
387 {
388 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
389 agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
390 agentCircuit.Viewer = currentAgentCircuit.Viewer;
391 agentCircuit.Channel = currentAgentCircuit.Channel;
392 agentCircuit.Mac = currentAgentCircuit.Mac;
393 agentCircuit.Id0 = currentAgentCircuit.Id0;
394 }
395 477
396 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 478 m_log.DebugFormat(
397 { 479 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
398 // brand new agent, let's create a new caps seed 480 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
399 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
400 }
401 481
402 // Let's create an agent there if one doesn't exist yet. 482 return;
403 bool logout = false; 483 }
404 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
405 {
406 sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}",
407 reason));
408 return;
409 }
410 484
411 // OK, it got this agent. Let's close some child agents 485 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
412 sp.CloseChildAgents(newRegionX, newRegionY);
413 IClientIPEndpoint ipepClient;
414 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
415 {
416 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
417 #region IP Translation for NAT
418 // Uses ipepClient above
419 if (sp.ClientView.TryGet(out ipepClient))
420 {
421 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
422 }
423 #endregion
424 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
425 486
426 if (eq != null) 487 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
427 { 488 // both regions
428 eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); 489 if (sp.ParentID != (uint)0)
490 sp.StandUp();
429 491
430 // ES makes the client send a UseCircuitCode message to the destination, 492 sp.ControllingClient.SendTeleportStart(teleportFlags);
431 // which triggers a bunch of things there.
432 // So let's wait
433 Thread.Sleep(200);
434 493
435 eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 494 // the avatar.Close below will clear the child region list. We need this below for (possibly)
495 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
496 //List<ulong> childRegions = avatar.KnownRegionHandles;
497 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
498 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
499 // once we reach here...
500 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
436 501
437 } 502 string capsPath = String.Empty;
438 else
439 {
440 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
441 }
442 }
443 else
444 {
445 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
446 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
447 }
448 503
504 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
505 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
506 agentCircuit.startpos = position;
507 agentCircuit.child = true;
508 agentCircuit.Appearance = sp.Appearance;
509 if (currentAgentCircuit != null)
510 {
511 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
512 agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
513 agentCircuit.Viewer = currentAgentCircuit.Viewer;
514 agentCircuit.Channel = currentAgentCircuit.Channel;
515 agentCircuit.Mac = currentAgentCircuit.Mac;
516 agentCircuit.Id0 = currentAgentCircuit.Id0;
517 }
449 518
450 SetInTransit(sp.UUID); 519 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
520 {
521 // brand new agent, let's create a new caps seed
522 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
523 }
451 524
452 // Let's send a full update of the agent. This is a synchronous call. 525 // Let's create an agent there if one doesn't exist yet.
453 AgentData agent = new AgentData(); 526 bool logout = false;
454 sp.CopyTo(agent); 527 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
455 agent.Position = position; 528 {
456 SetCallbackURL(agent, sp.Scene.RegionInfo); 529 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
530 ResetFromTransit(sp.UUID);
457 531
458 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 532 m_log.DebugFormat(
533 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
534 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
535
536 return;
537 }
538
539 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
540 UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
541
542 // OK, it got this agent. Let's close some child agents
543 sp.CloseChildAgents(newRegionX, newRegionY);
459 544
460 if (!UpdateAgent(reg, finalDestination, agent)) 545 IClientIPEndpoint ipepClient;
546 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
547 {
548 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
549 #region IP Translation for NAT
550 // Uses ipepClient above
551 if (sp.ClientView.TryGet(out ipepClient))
461 { 552 {
462 // Region doesn't take it 553 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
463 m_log.WarnFormat(
464 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
465 sp.Name, finalDestination.RegionName);
466
467 Fail(sp, finalDestination, logout);
468 return;
469 } 554 }
555 #endregion
556 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
470 557
471 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 558 if (m_eqModule != null)
559 {
560 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID);
472 561
473 m_log.DebugFormat( 562 // ES makes the client send a UseCircuitCode message to the destination,
474 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); 563 // which triggers a bunch of things there.
564 // So let's wait
565 Thread.Sleep(200);
566
567 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
475 568
476 if (eq != null)
477 {
478 eq.TeleportFinishEvent(destinationHandle, 13, endPoint,
479 0, teleportFlags, capsPath, sp.UUID);
480 } 569 }
481 else 570 else
482 { 571 {
483 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, 572 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
484 teleportFlags, capsPath);
485 } 573 }
574 }
575 else
576 {
577 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
578 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
579 }
486 580
487 // Let's set this to true tentatively. This does not trigger OnChildAgent 581 // Let's send a full update of the agent. This is a synchronous call.
488 sp.IsChildAgent = true; 582 AgentData agent = new AgentData();
583 sp.CopyTo(agent);
584 agent.Position = position;
585 SetCallbackURL(agent, sp.Scene.RegionInfo);
489 586
490 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which 587 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
491 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
492 // that the client contacted the destination before we close things here.
493 if (!WaitForCallback(sp.UUID))
494 {
495 m_log.WarnFormat(
496 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
497 sp.Name, finalDestination.RegionName);
498
499 Fail(sp, finalDestination, logout);
500 return;
501 }
502 588
503 // For backwards compatibility 589 if (!UpdateAgent(reg, finalDestination, agent))
504 if (version == "Unknown" || version == string.Empty) 590 {
505 { 591 // Region doesn't take it
506 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it 592 m_log.WarnFormat(
507 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); 593 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.",
508 CrossAttachmentsIntoNewRegion(finalDestination, sp, true); 594 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
509 } 595
596 Fail(sp, finalDestination, logout);
597 return;
598 }
510 599
511 // May need to logout or other cleanup 600 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest");
512 AgentHasMovedAway(sp, logout);
513 601
514 // Well, this is it. The agent is over there. 602 m_log.DebugFormat(
515 KillEntity(sp.Scene, sp.LocalId); 603 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
604 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
516 605
517 // Now let's make it officially a child agent 606 if (m_eqModule != null)
518 sp.MakeChildAgent(); 607 {
608 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
609 }
610 else
611 {
612 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
613 teleportFlags, capsPath);
614 }
519 615
520// sp.Scene.CleanDroppedAttachments(); 616 // Let's set this to true tentatively. This does not trigger OnChildAgent
617 sp.IsChildAgent = true;
521 618
522 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 619 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
620 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
621 // that the client contacted the destination before we close things here.
622 if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID))
623 {
624 m_log.WarnFormat(
625 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
626 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
627
628 Fail(sp, finalDestination, logout);
629 return;
630 }
523 631
524 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 632 UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
525 {
526 Thread.Sleep(5000);
527 sp.Close();
528 sp.Scene.IncomingCloseAgent(sp.UUID);
529 }
530 else
531 {
532 // now we have a child agent in this region.
533 sp.Reset();
534 }
535 633
536 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 634 // For backwards compatibility
537 if (sp.Scene.NeedSceneCacheClear(sp.UUID)) 635 if (version == "Unknown" || version == string.Empty)
538 { 636 {
539 m_log.DebugFormat( 637 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
540 "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", 638 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one...");
541 sp.UUID); 639 CrossAttachmentsIntoNewRegion(finalDestination, sp, true);
542 } 640 }
641
642 // May need to logout or other cleanup
643 AgentHasMovedAway(sp, logout);
644
645 // Well, this is it. The agent is over there.
646 KillEntity(sp.Scene, sp.LocalId);
647
648 // Now let's make it officially a child agent
649 sp.MakeChildAgent();
650
651// sp.Scene.CleanDroppedAttachments();
652
653 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
654
655 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
656 {
657 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
658 // they regard the new region as the current region after receiving the AgentMovementComplete
659 // response. If close is sent before then, it will cause the viewer to quit instead.
660 //
661 // This sleep can be increased if necessary. However, whilst it's active,
662 // an agent cannot teleport back to this region if it has teleported away.
663 Thread.Sleep(2000);
664
665 sp.Close();
666 sp.Scene.IncomingCloseAgent(sp.UUID);
543 } 667 }
544 else 668 else
545 { 669 {
546 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 670 // now we have a child agent in this region.
671 sp.Reset();
672 }
673
674 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
675 if (sp.Scene.NeedSceneCacheClear(sp.UUID))
676 {
677 m_log.DebugFormat(
678 "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
679 sp.UUID);
547 } 680 }
681
682 ResetFromTransit(sp.UUID);
548 } 683 }
549 684
550 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 685 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
@@ -560,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
560 EnableChildAgents(sp); 695 EnableChildAgents(sp);
561 696
562 // Finally, kill the agent we just created at the destination. 697 // Finally, kill the agent we just created at the destination.
563 m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); 698 m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
564 699
565 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 700 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
566 } 701 }
@@ -568,7 +703,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
568 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 703 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
569 { 704 {
570 logout = false; 705 logout = false;
571 bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); 706 bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
572 707
573 if (success) 708 if (success)
574 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); 709 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
@@ -578,19 +713,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
578 713
579 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) 714 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent)
580 { 715 {
581 return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); 716 return m_scene.SimulationService.UpdateAgent(finalDestination, agent);
582 } 717 }
583 718
584 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) 719 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region)
585 { 720 {
586 agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; 721 agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/";
587 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Set callback URL to {0}", agent.CallbackURI);
588 722
723 m_log.DebugFormat(
724 "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}",
725 agent.CallbackURI, region.RegionName);
589 } 726 }
590 727
591 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) 728 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
592 { 729 {
593 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); 730 if (sp.Scene.AttachmentsModule != null)
731 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
594 } 732 }
595 733
596 protected void KillEntity(Scene scene, uint localID) 734 protected void KillEntity(Scene scene, uint localID)
@@ -615,7 +753,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
615 753
616 protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) 754 protected virtual bool IsOutsideRegion(Scene s, Vector3 pos)
617 { 755 {
618
619 if (s.TestBorderCross(pos, Cardinals.N)) 756 if (s.TestBorderCross(pos, Cardinals.N))
620 return true; 757 return true;
621 if (s.TestBorderCross(pos, Cardinals.S)) 758 if (s.TestBorderCross(pos, Cardinals.S))
@@ -628,7 +765,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
628 return false; 765 return false;
629 } 766 }
630 767
631
632 #endregion 768 #endregion
633 769
634 #region Landmark Teleport 770 #region Landmark Teleport
@@ -640,7 +776,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
640 /// <param name="position"></param> 776 /// <param name="position"></param>
641 public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) 777 public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
642 { 778 {
643 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); 779 GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
644 780
645 if (info == null) 781 if (info == null)
646 { 782 {
@@ -663,10 +799,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
663 799
664 public virtual bool TeleportHome(UUID id, IClientAPI client) 800 public virtual bool TeleportHome(UUID id, IClientAPI client)
665 { 801 {
666 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); 802 m_log.DebugFormat(
803 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
667 804
668 //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); 805 //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId);
669 GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); 806 GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString());
670 807
671 if (uinfo != null) 808 if (uinfo != null)
672 { 809 {
@@ -676,7 +813,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
676 client.SendTeleportFailed("You don't have a home position set."); 813 client.SendTeleportFailed("You don't have a home position set.");
677 return false; 814 return false;
678 } 815 }
679 GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 816 GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
680 if (regionInfo == null) 817 if (regionInfo == null)
681 { 818 {
682 // can't find the Home region: Tell viewer and abort 819 // can't find the Home region: Tell viewer and abort
@@ -684,8 +821,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
684 return false; 821 return false;
685 } 822 }
686 823
687 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", 824 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
688 regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); 825 client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY);
689 826
690 // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... 827 // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point...
691 ((Scene)(client.Scene)).RequestTeleportLocation( 828 ((Scene)(client.Scene)).RequestTeleportLocation(
@@ -736,7 +873,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
736 873
737 neighbourx--; 874 neighbourx--;
738 newpos.X = Constants.RegionSize - enterDistance; 875 newpos.X = Constants.RegionSize - enterDistance;
739
740 } 876 }
741 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 877 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
742 { 878 {
@@ -922,107 +1058,123 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
922 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1058 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
923 bool isFlying, string version) 1059 bool isFlying, string version)
924 { 1060 {
1061 if (neighbourRegion == null)
1062 return agent;
1063
925 try 1064 try
926 { 1065 {
1066 SetInTransit(agent.UUID);
1067
927 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1068 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
928 1069
929 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); 1070 m_log.DebugFormat(
1071 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1072 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
930 1073
931 Scene m_scene = agent.Scene; 1074 Scene m_scene = agent.Scene;
932
933 if (neighbourRegion != null)
934 {
935 if (!agent.ValidateAttachments())
936 m_log.DebugFormat(
937 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
938 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
939 1075
940 pos = pos + agent.Velocity; 1076 if (!agent.ValidateAttachments())
941 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); 1077 m_log.DebugFormat(
1078 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1079 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
942 1080
943 agent.RemoveFromPhysicalScene(); 1081 pos = pos + agent.Velocity;
944 SetInTransit(agent.UUID); 1082 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
945 1083
946 AgentData cAgent = new AgentData(); 1084 agent.RemoveFromPhysicalScene();
947 agent.CopyTo(cAgent);
948 cAgent.Position = pos;
949 if (isFlying)
950 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
951 1085
952 // We don't need the callback anymnore 1086 AgentData cAgent = new AgentData();
953 cAgent.CallbackURI = String.Empty; 1087 agent.CopyTo(cAgent);
1088 cAgent.Position = pos;
1089 if (isFlying)
1090 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
954 1091
955 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1092 // We don't need the callback anymnore
956 { 1093 cAgent.CallbackURI = String.Empty;
957 // region doesn't take it
958 ReInstantiateScripts(agent);
959 agent.AddToPhysicalScene(isFlying);
960 ResetFromTransit(agent.UUID);
961 return agent;
962 }
963
964 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
965 agent.ControllingClient.RequestClientInfo();
966
967 //m_log.Debug("BEFORE CROSS");
968 //Scene.DumpChildrenSeeds(UUID);
969 //DumpKnownRegions();
970 string agentcaps;
971 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
972 {
973 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
974 neighbourRegion.RegionHandle);
975 return agent;
976 }
977 // No turning back
978 agent.IsChildAgent = true;
979 1094
980 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1095 // Beyond this point, extra cleanup is needed beyond removing transit state
981 1096 UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
982 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
983 1097
984 IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); 1098 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
985 if (eq != null) 1099 {
986 { 1100 // region doesn't take it
987 eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1101 UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
988 capsPath, agent.UUID, agent.ControllingClient.SessionId);
989 }
990 else
991 {
992 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
993 capsPath);
994 }
995 1102
996 // SUCCESS! 1103 ReInstantiateScripts(agent);
997 agent.MakeChildAgent(); 1104 agent.AddToPhysicalScene(isFlying);
998 ResetFromTransit(agent.UUID); 1105 ResetFromTransit(agent.UUID);
999 1106
1000 // now we have a child agent in this region. Request all interesting data about other (root) agents 1107 return agent;
1001 agent.SendOtherAgentsAvatarDataToMe(); 1108 }
1002 agent.SendOtherAgentsAppearanceToMe();
1003 1109
1004 // Backwards compatibility. Best effort 1110 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
1005 if (version == "Unknown" || version == string.Empty) 1111 agent.ControllingClient.RequestClientInfo();
1006 {
1007 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1008 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1009 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1010 }
1011 1112
1113 //m_log.Debug("BEFORE CROSS");
1114 //Scene.DumpChildrenSeeds(UUID);
1115 //DumpKnownRegions();
1116 string agentcaps;
1117 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1118 {
1119 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1120 neighbourRegion.RegionHandle);
1121 return agent;
1122 }
1123 // No turning back
1124 agent.IsChildAgent = true;
1012 1125
1013 // Next, let's close the child agent connections that are too far away. 1126 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1014 agent.CloseChildAgents(neighbourx, neighboury); 1127
1015 1128 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1016 AgentHasMovedAway(agent, false); 1129
1017 1130 if (m_eqModule != null)
1018 // the user may change their profile information in other region, 1131 {
1019 // so the userinfo in UserProfileCache is not reliable any more, delete it 1132 m_eqModule.CrossRegion(
1020 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1133 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1021 if (agent.Scene.NeedSceneCacheClear(agent.UUID)) 1134 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1022 { 1135 }
1023 m_log.DebugFormat( 1136 else
1024 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); 1137 {
1025 } 1138 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1139 capsPath);
1140 }
1141
1142 // SUCCESS!
1143 UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1144
1145 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1146 UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1147
1148 agent.MakeChildAgent();
1149
1150 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1151 // but not sure yet what the side effects would be.
1152 ResetFromTransit(agent.UUID);
1153
1154 // now we have a child agent in this region. Request all interesting data about other (root) agents
1155 agent.SendOtherAgentsAvatarDataToMe();
1156 agent.SendOtherAgentsAppearanceToMe();
1157
1158 // Backwards compatibility. Best effort
1159 if (version == "Unknown" || version == string.Empty)
1160 {
1161 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1162 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1163 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1164 }
1165
1166 // Next, let's close the child agent connections that are too far away.
1167 agent.CloseChildAgents(neighbourx, neighboury);
1168
1169 AgentHasMovedAway(agent, false);
1170
1171 // the user may change their profile information in other region,
1172 // so the userinfo in UserProfileCache is not reliable any more, delete it
1173 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1174 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1175 {
1176 m_log.DebugFormat(
1177 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1026 } 1178 }
1027 1179
1028 //m_log.Debug("AFTER CROSS"); 1180 //m_log.Debug("AFTER CROSS");
@@ -1034,11 +1186,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1034 m_log.ErrorFormat( 1186 m_log.ErrorFormat(
1035 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", 1187 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1036 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); 1188 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1189
1190 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1037 } 1191 }
1038 1192
1039 return agent; 1193 return agent;
1040 } 1194 }
1041 1195
1042 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1196 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
1043 { 1197 {
1044 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; 1198 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
@@ -1186,7 +1340,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1186 { 1340 {
1187 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 1341 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
1188 { 1342 {
1189
1190 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 1343 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1191 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); 1344 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
1192 agent.BaseFolder = UUID.Zero; 1345 agent.BaseFolder = UUID.Zero;
@@ -1211,7 +1364,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1211 seeds.Add(neighbour.RegionHandle, agent.CapsPath); 1364 seeds.Add(neighbour.RegionHandle, agent.CapsPath);
1212 } 1365 }
1213 else 1366 else
1367 {
1214 agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); 1368 agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle);
1369 }
1215 1370
1216 cagents.Add(agent); 1371 cagents.Add(agent);
1217 } 1372 }
@@ -1322,24 +1477,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1322 // after a cross here 1477 // after a cross here
1323 Thread.Sleep(500); 1478 Thread.Sleep(500);
1324 1479
1325 Scene m_scene = sp.Scene; 1480 Scene scene = sp.Scene;
1326 1481
1327 uint x, y; 1482 m_log.DebugFormat(
1328 Utils.LongToUInts(reg.RegionHandle, out x, out y); 1483 "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
1329 x = x / Constants.RegionSize; 1484 sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
1330 y = y / Constants.RegionSize;
1331 m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")");
1332 1485
1333 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); 1486 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
1334 1487
1335 string reason = String.Empty; 1488 string reason = String.Empty;
1336 1489
1337 bool regionAccepted = m_scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason); 1490 bool regionAccepted = scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason);
1338 1491
1339 if (regionAccepted && newAgent) 1492 if (regionAccepted && newAgent)
1340 { 1493 {
1341 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); 1494 if (m_eqModule != null)
1342 if (eq != null)
1343 { 1495 {
1344 #region IP Translation for NAT 1496 #region IP Translation for NAT
1345 IClientIPEndpoint ipepClient; 1497 IClientIPEndpoint ipepClient;
@@ -1351,10 +1503,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1351 1503
1352 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + 1504 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " +
1353 "and EstablishAgentCommunication with seed cap {4}", 1505 "and EstablishAgentCommunication with seed cap {4}",
1354 m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); 1506 scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath);
1355 1507
1356 eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); 1508 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID);
1357 eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 1509 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
1358 } 1510 }
1359 else 1511 else
1360 { 1512 {
@@ -1362,8 +1514,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1362 // TODO: make Event Queue disablable! 1514 // TODO: make Event Queue disablable!
1363 } 1515 }
1364 1516
1365 m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); 1517 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
1366 } 1518 }
1519
1520 if (!regionAccepted)
1521 m_log.WarnFormat(
1522 "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
1523 reg.RegionName, sp.Name, sp.UUID, reason);
1367 } 1524 }
1368 1525
1369 /// <summary> 1526 /// <summary>
@@ -1475,8 +1632,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1475 #region Agent Arrived 1632 #region Agent Arrived
1476 public void AgentArrivedAtDestination(UUID id) 1633 public void AgentArrivedAtDestination(UUID id)
1477 { 1634 {
1478 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); 1635 lock (m_agentsInTransit)
1479 ResetFromTransit(id); 1636 {
1637 if (!m_agentsInTransit.ContainsKey(id))
1638 {
1639 m_log.WarnFormat(
1640 "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active",
1641 m_scene.RegionInfo.RegionName, id);
1642
1643 return;
1644 }
1645
1646 AgentTransferState currentState = m_agentsInTransit[id];
1647
1648 if (currentState == AgentTransferState.ReceivedAtDestination)
1649 {
1650 // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification.
1651 m_log.WarnFormat(
1652 "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received",
1653 m_scene.RegionInfo.RegionName, id);
1654 }
1655 else if (currentState != AgentTransferState.Transferring)
1656 {
1657 m_log.ErrorFormat(
1658 "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}",
1659 m_scene.RegionInfo.RegionName, id, currentState);
1660
1661 return;
1662 }
1663
1664 m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination;
1665 }
1480 } 1666 }
1481 1667
1482 #endregion 1668 #endregion
@@ -1747,8 +1933,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1747 //// And the new channel... 1933 //// And the new channel...
1748 //if (m_interregionCommsOut != null) 1934 //if (m_interregionCommsOut != null)
1749 // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); 1935 // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true);
1750 if (m_aScene.SimulationService != null) 1936 if (m_scene.SimulationService != null)
1751 successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true); 1937 successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true);
1752 1938
1753 if (successYN) 1939 if (successYN)
1754 { 1940 {
@@ -1827,50 +2013,138 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1827 2013
1828 #region Misc 2014 #region Misc
1829 2015
1830 protected bool WaitForCallback(UUID id) 2016 private bool WaitForCallback(UUID id)
1831 { 2017 {
2018 lock (m_agentsInTransit)
2019 {
2020 if (!IsInTransit(id))
2021 throw new Exception(
2022 string.Format(
2023 "Asked to wait for destination callback for agent with ID {0} but it is not in transit"));
2024
2025 AgentTransferState currentState = m_agentsInTransit[id];
2026
2027 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
2028 throw new Exception(
2029 string.Format(
2030 "Asked to wait for destination callback for agent with ID {0} but it is in state {1}",
2031 currentState));
2032 }
2033
1832 int count = 200; 2034 int count = 200;
1833 while (m_agentsInTransit.Contains(id) && count-- > 0) 2035
2036 // There should be no race condition here since no other code should be removing the agent transfer or
2037 // changing the state to another other than Transferring => ReceivedAtDestination.
2038 while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0)
1834 { 2039 {
1835 //m_log.Debug(" >>> Waiting... " + count); 2040// m_log.Debug(" >>> Waiting... " + count);
1836 Thread.Sleep(100); 2041 Thread.Sleep(100);
1837 } 2042 }
1838 2043
1839 if (count > 0) 2044 return count > 0;
1840 return true;
1841 else
1842 return false;
1843 } 2045 }
1844 2046
1845 protected void SetInTransit(UUID id) 2047 /// <summary>
2048 /// Set that an agent is in transit.
2049 /// </summary>
2050 /// <param name='id'>The ID of the agent being teleported</param>
2051 /// <returns>true if the agent was not already in transit, false if it was</returns>
2052 private bool SetInTransit(UUID id)
1846 { 2053 {
1847 lock (m_agentsInTransit) 2054 lock (m_agentsInTransit)
1848 { 2055 {
1849 if (!m_agentsInTransit.Contains(id)) 2056 if (!m_agentsInTransit.ContainsKey(id))
1850 m_agentsInTransit.Add(id); 2057 {
2058 m_agentsInTransit[id] = AgentTransferState.Preparing;
2059 return true;
2060 }
1851 } 2061 }
2062
2063 return false;
1852 } 2064 }
1853 2065
1854 protected bool IsInTransit(UUID id) 2066 /// <summary>
2067 /// Updates the state of an agent that is already in transit.
2068 /// </summary>
2069 /// <param name='id'></param>
2070 /// <param name='newState'></param>
2071 /// <returns></returns>
2072 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
2073 private void UpdateInTransit(UUID id, AgentTransferState newState)
1855 { 2074 {
1856 lock (m_agentsInTransit) 2075 lock (m_agentsInTransit)
1857 { 2076 {
1858 if (m_agentsInTransit.Contains(id)) 2077 // Illegal to try and update an agent that's not actually in transit.
1859 return true; 2078 if (!m_agentsInTransit.ContainsKey(id))
2079 throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id));
2080
2081 AgentTransferState oldState = m_agentsInTransit[id];
2082
2083 bool transitionOkay = false;
2084
2085 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
2086 transitionOkay = true;
2087 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
2088 transitionOkay = true;
2089 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
2090 transitionOkay = true;
2091
2092 if (transitionOkay)
2093 m_agentsInTransit[id] = newState;
2094 else
2095 throw new Exception(
2096 string.Format(
2097 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}",
2098 id, oldState, newState));
1860 } 2099 }
1861 return false;
1862 } 2100 }
1863 2101
1864 protected bool ResetFromTransit(UUID id) 2102 public bool IsInTransit(UUID id)
2103 {
2104 lock (m_agentsInTransit)
2105 return m_agentsInTransit.ContainsKey(id);
2106 }
2107
2108 /// <summary>
2109 /// Removes an agent from the transit state machine.
2110 /// </summary>
2111 /// <param name='id'></param>
2112 /// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns>
2113 private bool ResetFromTransit(UUID id)
1865 { 2114 {
1866 lock (m_agentsInTransit) 2115 lock (m_agentsInTransit)
1867 { 2116 {
1868 if (m_agentsInTransit.Contains(id)) 2117 if (m_agentsInTransit.ContainsKey(id))
1869 { 2118 {
2119 AgentTransferState state = m_agentsInTransit[id];
2120
2121 if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
2122 {
2123 // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
2124 // to be handled properly - ResetFromTransit() could be invoked at any step along the process
2125 m_log.WarnFormat(
2126 "[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first",
2127 state, AgentTransferState.CleaningUp);
2128
2129// throw new Exception(
2130// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
2131// state, AgentTransferState.CleaningUp);
2132 }
2133
1870 m_agentsInTransit.Remove(id); 2134 m_agentsInTransit.Remove(id);
2135
2136 m_log.DebugFormat(
2137 "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}",
2138 id, m_scene.RegionInfo.RegionName);
2139
1871 return true; 2140 return true;
1872 } 2141 }
1873 } 2142 }
2143
2144 m_log.WarnFormat(
2145 "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.",
2146 id, m_scene.RegionInfo.RegionName);
2147
1874 return false; 2148 return false;
1875 } 2149 }
1876 2150
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 8b5ad23..44ea2b1 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -45,11 +45,12 @@ using Nini.Config;
45 45
46namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 46namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
47{ 47{
48 public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule 48 public class HGEntityTransferModule
49 : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule
49 { 50 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 52
52 private bool m_Initialized = false; 53 private int m_levelHGTeleport = 0;
53 54
54 private GatekeeperServiceConnector m_GatekeeperConnector; 55 private GatekeeperServiceConnector m_GatekeeperConnector;
55 56
@@ -63,11 +64,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
63 public override void Initialise(IConfigSource source) 64 public override void Initialise(IConfigSource source)
64 { 65 {
65 IConfig moduleConfig = source.Configs["Modules"]; 66 IConfig moduleConfig = source.Configs["Modules"];
67
66 if (moduleConfig != null) 68 if (moduleConfig != null)
67 { 69 {
68 string name = moduleConfig.GetString("EntityTransferModule", ""); 70 string name = moduleConfig.GetString("EntityTransferModule", "");
69 if (name == Name) 71 if (name == Name)
70 { 72 {
73 IConfig transferConfig = source.Configs["EntityTransfer"];
74 if (transferConfig != null)
75 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
76
71 InitialiseCommon(source); 77 InitialiseCommon(source);
72 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 78 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
73 } 79 }
@@ -77,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
77 public override void AddRegion(Scene scene) 83 public override void AddRegion(Scene scene)
78 { 84 {
79 base.AddRegion(scene); 85 base.AddRegion(scene);
86
80 if (m_Enabled) 87 if (m_Enabled)
81 {
82 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); 88 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this);
83 }
84 } 89 }
85 90
86 protected override void OnNewClient(IClientAPI client) 91 protected override void OnNewClient(IClientAPI client)
@@ -93,33 +98,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
93 public override void RegionLoaded(Scene scene) 98 public override void RegionLoaded(Scene scene)
94 { 99 {
95 base.RegionLoaded(scene); 100 base.RegionLoaded(scene);
96 if (m_Enabled)
97 if (!m_Initialized)
98 {
99 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
100 m_Initialized = true;
101
102 }
103 101
102 if (m_Enabled)
103 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
104 } 104 }
105
105 public override void RemoveRegion(Scene scene) 106 public override void RemoveRegion(Scene scene)
106 { 107 {
107 base.AddRegion(scene); 108 base.AddRegion(scene);
109
108 if (m_Enabled) 110 if (m_Enabled)
109 {
110 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); 111 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
111 }
112 } 112 }
113 113
114
115 #endregion 114 #endregion
116 115
117 #region HG overrides of IEntiryTransferModule 116 #region HG overrides of IEntiryTransferModule
118 117
119 protected override GridRegion GetFinalDestination(GridRegion region) 118 protected override GridRegion GetFinalDestination(GridRegion region)
120 { 119 {
121 int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); 120 int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, region.RegionID);
122 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); 121 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags);
122
123 if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 123 if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
124 { 124 {
125 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); 125 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID);
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
130 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); 130 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI);
131 return real_destination; 131 return real_destination;
132 } 132 }
133
133 return region; 134 return region;
134 } 135 }
135 136
@@ -138,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
138 if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 139 if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
139 return true; 140 return true;
140 141
141 int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); 142 int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID);
142 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 143 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
143 return true; 144 return true;
144 145
@@ -151,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
151 if (logout) 152 if (logout)
152 { 153 {
153 // Log them out of this grid 154 // Log them out of this grid
154 m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 155 m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
155 } 156 }
156 } 157 }
157 158
@@ -160,10 +161,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
160 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); 161 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
161 reason = string.Empty; 162 reason = string.Empty;
162 logout = false; 163 logout = false;
163 int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); 164 int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID);
164 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 165 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
165 { 166 {
166 // this user is going to another grid 167 // this user is going to another grid
168 // check if HyperGrid teleport is allowed, based on user level
169 if (sp.UserLevel < m_levelHGTeleport)
170 {
171 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
172 reason = "Hypergrid teleport not allowed";
173 return false;
174 }
175
167 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) 176 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI"))
168 { 177 {
169 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); 178 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString();
@@ -193,10 +202,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
193 202
194 public override bool TeleportHome(UUID id, IClientAPI client) 203 public override bool TeleportHome(UUID id, IClientAPI client)
195 { 204 {
196 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); 205 m_log.DebugFormat(
206 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
197 207
198 // Let's find out if this is a foreign user or a local user 208 // Let's find out if this is a foreign user or a local user
199 IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); 209 IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>();
200 if (uMan != null && uMan.IsLocalGridUser(id)) 210 if (uMan != null && uMan.IsLocalGridUser(id))
201 { 211 {
202 // local grid user 212 // local grid user
@@ -232,13 +242,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
232 return false; 242 return false;
233 } 243 }
234 244
235 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
236 GridRegion homeGatekeeper = MakeRegion(aCircuit); 245 GridRegion homeGatekeeper = MakeRegion(aCircuit);
237 246
238 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 247 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
239 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 248 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
240 249
241 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); 250 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
242 return true; 251 return true;
243 } 252 }
244 253
@@ -252,19 +261,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
252 { 261 {
253 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", 262 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
254 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); 263 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
264
255 if (lm.Gatekeeper == string.Empty) 265 if (lm.Gatekeeper == string.Empty)
256 { 266 {
257 base.RequestTeleportLandmark(remoteClient, lm); 267 base.RequestTeleportLandmark(remoteClient, lm);
258 return; 268 return;
259 } 269 }
260 270
261 GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); 271 GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
262 272
263 // Local region? 273 // Local region?
264 if (info != null) 274 if (info != null)
265 { 275 {
266 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, 276 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
267 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); 277 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
278
268 return; 279 return;
269 } 280 }
270 else 281 else
@@ -275,21 +286,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
275 GridRegion gatekeeper = new GridRegion(); 286 GridRegion gatekeeper = new GridRegion();
276 gatekeeper.ServerURI = lm.Gatekeeper; 287 gatekeeper.ServerURI = lm.Gatekeeper;
277 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); 288 GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
289
278 if (finalDestination != null) 290 if (finalDestination != null)
279 { 291 {
280 ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); 292 ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
281 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); 293 IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
282 IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); 294
283 if (transferMod != null && sp != null && eq != null) 295 if (transferMod != null && sp != null)
284 transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position, 296 transferMod.DoTeleport(
285 Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq); 297 sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX,
298 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
286 } 299 }
287 300
288 } 301 }
289 302
290 // can't find the region: Tell viewer and abort 303 // can't find the region: Tell viewer and abort
291 remoteClient.SendTeleportFailed("The teleport destination could not be found."); 304 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
292
293 } 305 }
294 306
295 #endregion 307 #endregion
@@ -304,8 +316,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
304 IUserAgentService security = new UserAgentServiceConnector(url); 316 IUserAgentService security = new UserAgentServiceConnector(url);
305 return security.VerifyClient(aCircuit.SessionID, token); 317 return security.VerifyClient(aCircuit.SessionID, token);
306 } 318 }
307 else 319 else
308 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); 320 {
321 m_log.DebugFormat(
322 "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!",
323 aCircuit.firstname, aCircuit.lastname);
324 }
309 325
310 return false; 326 return false;
311 } 327 }
@@ -322,8 +338,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
322 } 338 }
323 339
324 // Let's find out if this is a foreign user or a local user 340 // Let's find out if this is a foreign user or a local user
325 IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); 341 IUserManagement uMan = m_scene.RequestModuleInterface<IUserManagement>();
326 UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); 342// UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId);
327 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) 343 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
328 { 344 {
329 // local grid user 345 // local grid user
@@ -346,7 +362,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
346 362
347 #endregion 363 #endregion
348 364
349
350 private GridRegion MakeRegion(AgentCircuitData aCircuit) 365 private GridRegion MakeRegion(AgentCircuitData aCircuit)
351 { 366 {
352 GridRegion region = new GridRegion(); 367 GridRegion region = new GridRegion();
@@ -363,6 +378,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
363 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); 378 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
364 return region; 379 return region;
365 } 380 }
366
367 } 381 }
368} 382} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index a71584a..cf72b58 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -364,8 +364,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
364 { 364 {
365 m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); 365 m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
366 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); 366 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
367 List<UUID> fids = new List<UUID>(); 367
368 List<UUID> iids = new List<UUID>();
369 List<InventoryFolderBase> keep = new List<InventoryFolderBase>(); 368 List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
370 369
371 foreach (InventoryFolderBase f in content.Folders) 370 foreach (InventoryFolderBase f in content.Folders)
@@ -395,4 +394,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
395 394
396 #endregion 395 #endregion
397 } 396 }
398} 397} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index ee9961f..31820e0 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
175 sbyte assetType, 175 sbyte assetType,
176 byte wearableType, uint nextOwnerMask, int creationDate) 176 byte wearableType, uint nextOwnerMask, int creationDate)
177 { 177 {
178 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); 178 m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID);
179 179
180 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 180 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
181 return; 181 return;
@@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
210 else 210 else
211 { 211 {
212 m_log.ErrorFormat( 212 m_log.ErrorFormat(
213 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", 213 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
214 remoteClient.AgentId); 214 remoteClient.AgentId);
215 } 215 }
216 } 216 }
@@ -288,16 +288,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
288 else 288 else
289 { 289 {
290 m_log.ErrorFormat( 290 m_log.ErrorFormat(
291 "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", 291 "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update",
292 itemID); 292 itemID);
293 } 293 }
294 294
295 return UUID.Zero; 295 return UUID.Zero;
296 } 296 }
297 297
298 public virtual UUID CopyToInventory(DeRezAction action, UUID folderID, 298 public virtual List<InventoryItemBase> CopyToInventory(
299 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) 299 DeRezAction action, UUID folderID,
300 List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment)
300 { 301 {
302 List<InventoryItemBase> copiedItems = new List<InventoryItemBase>();
303
301 Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>(); 304 Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>();
302 305
303 if (CoalesceMultipleObjectsToInventory) 306 if (CoalesceMultipleObjectsToInventory)
@@ -324,16 +327,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
324 } 327 }
325 } 328 }
326 329
327 // This is method scoped and will be returned. It will be the 330// m_log.DebugFormat(
328 // last created asset id 331// "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}",
329 UUID assetID = UUID.Zero; 332// bundlesToCopy.Count, folderID, action, remoteClient.Name);
330 333
331 // Each iteration is really a separate asset being created, 334 // Each iteration is really a separate asset being created,
332 // with distinct destinations as well. 335 // with distinct destinations as well.
333 foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values) 336 foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values)
334 assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient); 337 copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
335 338
336 return assetID; 339 return copiedItems;
337 } 340 }
338 341
339 /// <summary> 342 /// <summary>
@@ -344,12 +347,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
344 /// <param name="folderID"></param> 347 /// <param name="folderID"></param>
345 /// <param name="objlist"></param> 348 /// <param name="objlist"></param>
346 /// <param name="remoteClient"></param> 349 /// <param name="remoteClient"></param>
347 /// <returns></returns> 350 /// <param name="asAttachment">Should be true if the bundle is being copied as an attachment. This prevents
348 protected UUID CopyBundleToInventory( 351 /// attempted serialization of any script state which would abort any operating scripts.</param>
349 DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient) 352 /// <returns>The inventory item created by the copy</returns>
353 protected InventoryItemBase CopyBundleToInventory(
354 DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient,
355 bool asAttachment)
350 { 356 {
351 UUID assetID = UUID.Zero;
352
353 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); 357 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
354 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); 358 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
355 359
@@ -401,18 +405,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
401 405
402 string itemXml; 406 string itemXml;
403 407
408 // If we're being called from a script, then trying to serialize that same script's state will not complete
409 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
410 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
411 // without state on relog. Arguably, this is what we want anyway.
404 if (objlist.Count > 1) 412 if (objlist.Count > 1)
405 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); 413 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
406 else 414 else
407 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); 415 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
408 416
409 // Restore the position of each group now that it has been stored to inventory. 417 // Restore the position of each group now that it has been stored to inventory.
410 foreach (SceneObjectGroup objectGroup in objlist) 418 foreach (SceneObjectGroup objectGroup in objlist)
411 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; 419 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
412 420
413 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); 421 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
422
423// m_log.DebugFormat(
424// "[INVENTORY ACCESS MODULE]: Created item is {0}",
425// item != null ? item.ID.ToString() : "NULL");
426
414 if (item == null) 427 if (item == null)
415 return UUID.Zero; 428 return null;
416 429
417 // Can't know creator is the same, so null it in inventory 430 // Can't know creator is the same, so null it in inventory
418 if (objlist.Count > 1) 431 if (objlist.Count > 1)
@@ -422,7 +435,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
422 } 435 }
423 else 436 else
424 { 437 {
425 item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); 438 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
439 item.CreatorData = objlist[0].RootPart.CreatorData;
426 item.SaleType = objlist[0].RootPart.ObjectSaleType; 440 item.SaleType = objlist[0].RootPart.ObjectSaleType;
427 item.SalePrice = objlist[0].RootPart.SalePrice; 441 item.SalePrice = objlist[0].RootPart.SalePrice;
428 } 442 }
@@ -435,8 +449,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
435 objlist[0].OwnerID.ToString()); 449 objlist[0].OwnerID.ToString());
436 m_Scene.AssetService.Store(asset); 450 m_Scene.AssetService.Store(asset);
437 451
438 item.AssetID = asset.FullID; 452 item.AssetID = asset.FullID;
439 assetID = asset.FullID;
440 453
441 if (DeRezAction.SaveToExistingUserInventoryItem == action) 454 if (DeRezAction.SaveToExistingUserInventoryItem == action)
442 { 455 {
@@ -469,9 +482,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
469 482
470 // This is a hook to do some per-asset post-processing for subclasses that need that 483 // This is a hook to do some per-asset post-processing for subclasses that need that
471 if (remoteClient != null) 484 if (remoteClient != null)
472 ExportAsset(remoteClient.AgentId, assetID); 485 ExportAsset(remoteClient.AgentId, asset.FullID);
473 486
474 return assetID; 487 return item;
475 } 488 }
476 489
477 protected virtual void ExportAsset(UUID agentID, UUID assetID) 490 protected virtual void ExportAsset(UUID agentID, UUID assetID)
@@ -617,7 +630,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
617 if (null == item) 630 if (null == item)
618 { 631 {
619 m_log.DebugFormat( 632 m_log.DebugFormat(
620 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", 633 "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.",
621 so.Name, so.UUID); 634 so.Name, so.UUID);
622 635
623 return null; 636 return null;
@@ -668,7 +681,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
668 { 681 {
669 // Catch all. Use lost & found 682 // Catch all. Use lost & found
670 // 683 //
671
672 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 684 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
673 } 685 }
674 } 686 }
@@ -718,7 +730,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
718 730
719 if (item == null) 731 if (item == null)
720 { 732 {
721
722 return null; 733 return null;
723 } 734 }
724 735
@@ -748,7 +759,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
748 else 759 else
749 { 760 {
750 m_log.WarnFormat( 761 m_log.WarnFormat(
751 "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", 762 "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()",
752 assetID, remoteClient.Name); 763 assetID, remoteClient.Name);
753 } 764 }
754 765
@@ -859,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
859 SceneObjectPart rootPart = group.RootPart; 870 SceneObjectPart rootPart = group.RootPart;
860 871
861// m_log.DebugFormat( 872// m_log.DebugFormat(
862// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 873// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
863// group.Name, group.LocalId, group.UUID, 874// group.Name, group.LocalId, group.UUID,
864// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, 875// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
865// remoteClient.Name); 876// remoteClient.Name);
@@ -867,7 +878,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
867// Vector3 storedPosition = group.AbsolutePosition; 878// Vector3 storedPosition = group.AbsolutePosition;
868 if (group.UUID == UUID.Zero) 879 if (group.UUID == UUID.Zero)
869 { 880 {
870 m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); 881 m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3");
871 } 882 }
872 883
873 foreach (SceneObjectPart part in group.Parts) 884 foreach (SceneObjectPart part in group.Parts)
@@ -928,7 +939,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
928 } 939 }
929 940
930// m_log.DebugFormat( 941// m_log.DebugFormat(
931// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 942// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
932// group.Name, group.LocalId, group.UUID, 943// group.Name, group.LocalId, group.UUID,
933// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, 944// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
934// remoteClient.Name); 945// remoteClient.Name);
@@ -1023,8 +1034,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1023 1034
1024 so.FromFolderID = item.Folder; 1035 so.FromFolderID = item.Folder;
1025 1036
1026// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", 1037// m_log.DebugFormat(
1027// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1038// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
1039// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
1028 1040
1029 if ((rootPart.OwnerID != item.Owner) || 1041 if ((rootPart.OwnerID != item.Owner) ||
1030 (item.CurrentPermissions & 16) != 0 || 1042 (item.CurrentPermissions & 16) != 0 ||
@@ -1160,7 +1172,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1160 if (assetRequestItem.AssetID != requestID) 1172 if (assetRequestItem.AssetID != requestID)
1161 { 1173 {
1162 m_log.WarnFormat( 1174 m_log.WarnFormat(
1163 "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", 1175 "[INVENTORY ACCESS MODULE]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
1164 Name, requestID, itemID, assetRequestItem.AssetID); 1176 Name, requestID, itemID, assetRequestItem.AssetID);
1165 1177
1166 return false; 1178 return false;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index e74310c..21d8bd7 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -64,8 +64,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
64 IConfigSource config = new IniConfigSource(); 64 IConfigSource config = new IniConfigSource();
65 config.AddConfig("Modules"); 65 config.AddConfig("Modules");
66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 66 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
67 67
68 m_scene = SceneHelpers.SetupScene(); 68 SceneHelpers sceneHelpers = new SceneHelpers();
69 m_scene = sceneHelpers.SetupScene();
69 SceneHelpers.SetupSceneModules(m_scene, config, m_iam); 70 SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
70 71
71 // Create user 72 // Create user
@@ -76,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
76 77
77 AgentCircuitData acd = new AgentCircuitData(); 78 AgentCircuitData acd = new AgentCircuitData();
78 acd.AgentID = m_userId; 79 acd.AgentID = m_userId;
79 m_tc = new TestClient(acd, m_scene); 80 m_tc = new TestClient(acd, m_scene);
80 } 81 }
81 82
82 [Test] 83 [Test]
diff --git a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs
new file mode 100644
index 0000000..1526886
--- /dev/null
+++ b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs
@@ -0,0 +1,224 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Framework.Capabilities;
33using OpenSim.Framework.Servers.HttpServer;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39
40using Caps = OpenSim.Framework.Capabilities.Caps;
41
42
43namespace OpenSim.Region.CoreModules.World.LightShare
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")]
46
47 public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private Scene m_scene = null;
52 private UUID regionID = UUID.Zero;
53 private static bool Enabled = false;
54
55 private static readonly string capsName = "EnvironmentSettings";
56 private static readonly string capsBase = "/CAPS/0020/";
57
58 private LLSDEnvironmentSetResponse setResponse = null;
59
60 #region INonSharedRegionModule
61 public void Initialise(IConfigSource source)
62 {
63 IConfig config = source.Configs["ClientStack.LindenCaps"];
64
65 if (null == config)
66 return;
67
68 if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "localhost")
69 {
70 m_log.InfoFormat("[{0}]: Module is disabled.", Name);
71 return;
72 }
73
74 Enabled = true;
75
76 m_log.InfoFormat("[{0}]: Module is enabled.", Name);
77 }
78
79 public void Close()
80 {
81 }
82
83 public string Name
84 {
85 get { return "EnvironmentModule"; }
86 }
87
88 public Type ReplaceableInterface
89 {
90 get { return null; }
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 if (!Enabled)
96 return;
97
98 scene.RegisterModuleInterface<IEnvironmentModule>(this);
99 m_scene = scene;
100 regionID = scene.RegionInfo.RegionID;
101 }
102
103 public void RegionLoaded(Scene scene)
104 {
105 if (!Enabled)
106 return;
107
108 setResponse = new LLSDEnvironmentSetResponse();
109 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
110 }
111
112 public void RemoveRegion(Scene scene)
113 {
114 if (Enabled)
115 return;
116
117 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
118 m_scene = null;
119 }
120 #endregion
121
122 #region IEnvironmentModule
123 public void ResetEnvironmentSettings(UUID regionUUID)
124 {
125 if (!Enabled)
126 return;
127
128 m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID);
129 }
130 #endregion
131
132 #region Events
133 private void OnRegisterCaps(UUID agentID, Caps caps)
134 {
135// m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}",
136// Name, agentID, caps.RegionName);
137
138 string capsPath = capsBase + UUID.Random();
139
140 // Get handler
141 caps.RegisterHandler(
142 capsName,
143 new RestStreamHandler(
144 "GET",
145 capsPath,
146 (request, path, param, httpRequest, httpResponse)
147 => GetEnvironmentSettings(request, path, param, agentID, caps),
148 capsName,
149 agentID.ToString()));
150
151 // Set handler
152 caps.HttpListener.AddStreamHandler(
153 new RestStreamHandler(
154 "POST",
155 capsPath,
156 (request, path, param, httpRequest, httpResponse)
157 => SetEnvironmentSettings(request, path, param, agentID, caps),
158 capsName,
159 agentID.ToString()));
160 }
161 #endregion
162
163 private string GetEnvironmentSettings(string request, string path, string param,
164 UUID agentID, Caps caps)
165 {
166// m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}",
167// Name, agentID, caps.RegionName);
168
169 string env = String.Empty;
170
171 try
172 {
173 env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID);
174 }
175 catch (Exception e)
176 {
177 m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}",
178 Name, caps.RegionName, e.Message, e.StackTrace);
179 }
180
181 if (String.IsNullOrEmpty(env))
182 env = EnvironmentSettings.EmptySettings(UUID.Zero, regionID);
183
184 return env;
185 }
186
187 private string SetEnvironmentSettings(string request, string path, string param,
188 UUID agentID, Caps caps)
189 {
190
191// m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}",
192// Name, agentID, caps.RegionName);
193
194 setResponse.regionID = regionID;
195 setResponse.success = false;
196
197 if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false))
198 {
199 setResponse.fail_reason = "Insufficient estate permissions, settings has not been saved.";
200 return LLSDHelpers.SerialiseLLSDReply(setResponse);
201 }
202
203 try
204 {
205 m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request);
206 setResponse.success = true;
207
208 m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}",
209 Name, agentID, caps.RegionName);
210 }
211 catch (Exception e)
212 {
213 m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}",
214 Name, caps.RegionName, e.Message, e.StackTrace);
215
216 setResponse.success = false;
217 setResponse.fail_reason = String.Format("Environment Set for region {0} has failed, settings has not been saved.", caps.RegionName);
218 }
219
220 return LLSDHelpers.SerialiseLLSDReply(setResponse);
221 }
222 }
223}
224
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
index 9255791..e91e8b9 100644
--- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
@@ -64,6 +64,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
64 private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue 64 private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue
65 private string m_InterObjectHostname = "lsl.opensim.local"; 65 private string m_InterObjectHostname = "lsl.opensim.local";
66 66
67 private int m_MaxEmailSize = 4096; // largest email allowed by default, as per lsl docs.
68
67 // Scenes by Region Handle 69 // Scenes by Region Handle
68 private Dictionary<ulong, Scene> m_Scenes = 70 private Dictionary<ulong, Scene> m_Scenes =
69 new Dictionary<ulong, Scene>(); 71 new Dictionary<ulong, Scene>();
@@ -127,6 +129,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
127 SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); 129 SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT);
128 SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); 130 SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN);
129 SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); 131 SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD);
132 m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize);
130 } 133 }
131 catch (Exception e) 134 catch (Exception e)
132 { 135 {
@@ -176,18 +179,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
176 get { return true; } 179 get { return true; }
177 } 180 }
178 181
179 /// <summary>
180 /// Delay function using thread in seconds
181 /// </summary>
182 /// <param name="seconds"></param>
183 private void DelayInSeconds(int delay)
184 {
185 delay = (int)((float)delay * 1000);
186 if (delay == 0)
187 return;
188 System.Threading.Thread.Sleep(delay);
189 }
190
191 private bool IsLocal(UUID objectID) 182 private bool IsLocal(UUID objectID)
192 { 183 {
193 string unused; 184 string unused;
@@ -267,10 +258,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
267 m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); 258 m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address);
268 return; 259 return;
269 } 260 }
270 //FIXME:Check if subject + body = 4096 Byte 261 if ((subject.Length + body.Length) > m_MaxEmailSize)
271 if ((subject.Length + body.Length) > 1024)
272 { 262 {
273 m_log.Error("[EMAIL] subject + body > 1024 Byte"); 263 m_log.Error("[EMAIL] subject + body larger than limit of " + m_MaxEmailSize + " bytes");
274 return; 264 return;
275 } 265 }
276 266
@@ -345,10 +335,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
345 // TODO FIX 335 // TODO FIX
346 } 336 }
347 } 337 }
348
349 //DONE: Message as Second Life style
350 //20 second delay - AntiSpam System - for now only 10 seconds
351 DelayInSeconds(10);
352 } 338 }
353 339
354 /// <summary> 340 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index f4cf6b4..1865ab8 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -85,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
85 private IHttpServer m_HttpsServer = null; 85 private IHttpServer m_HttpsServer = null;
86 86
87 private string m_ExternalHostNameForLSL = ""; 87 private string m_ExternalHostNameForLSL = "";
88 public string ExternalHostNameForLSL
89 {
90 get { return m_ExternalHostNameForLSL; }
91 }
88 92
89 public Type ReplaceableInterface 93 public Type ReplaceableInterface
90 { 94 {
@@ -147,6 +151,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
147 public void Close() 151 public void Close()
148 { 152 {
149 } 153 }
154
150 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) 155 public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID)
151 { 156 {
152 UUID urlcode = UUID.Random(); 157 UUID urlcode = UUID.Random();
@@ -176,6 +181,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
176 uri, 181 uri,
177 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 182 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode));
178 183
184 m_log.DebugFormat(
185 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
186 uri, itemID, host.Name, host.LocalId);
187
179 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 188 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
180 } 189 }
181 190
@@ -218,6 +227,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
218 uri, 227 uri,
219 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 228 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode));
220 229
230 m_log.DebugFormat(
231 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
232 uri, itemID, host.Name, host.LocalId);
233
221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 234 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
222 } 235 }
223 236
@@ -241,6 +254,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
241 m_RequestMap.Remove(req); 254 m_RequestMap.Remove(req);
242 } 255 }
243 256
257// m_log.DebugFormat(
258// "[URL MODULE]: Releasing url {0} for {1} in {2}",
259// url, data.itemID, data.hostID);
260
244 RemoveUrl(data); 261 RemoveUrl(data);
245 m_UrlMap.Remove(url); 262 m_UrlMap.Remove(url);
246 } 263 }
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 176c86d..8358bc0 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -308,56 +308,56 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
308 /// <param name='msg'> 308 /// <param name='msg'>
309 /// Message. 309 /// Message.
310 /// </param> 310 /// </param>
311 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error) 311 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg)
312 { 312 {
313 error = null;
314 // Is id an avatar? 313 // Is id an avatar?
315 ScenePresence sp = m_scene.GetScenePresence(target); 314 ScenePresence sp = m_scene.GetScenePresence(target);
316 315
317 if (sp != null) 316 if (sp != null)
318 { 317 {
319 // Send message to avatar 318 // ignore if a child agent this is restricted to inside one region
319 if (sp.IsChildAgent)
320 return;
321
322 // Send message to the avatar.
323 // Channel zero only goes to the avatar
324 // non zero channel messages only go to the attachments
320 if (channel == 0) 325 if (channel == 0)
321 { 326 {
322 m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false); 327 m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false);
323 } 328 }
324 329 else
325 List<SceneObjectGroup> attachments = sp.GetAttachments();
326
327 if (attachments.Count == 0)
328 return true;
329
330 // Get uuid of attachments
331 List<UUID> targets = new List<UUID>();
332 foreach (SceneObjectGroup sog in attachments)
333 { 330 {
334 if (!sog.IsDeleted) 331 List<SceneObjectGroup> attachments = sp.GetAttachments();
335 targets.Add(sog.UUID); 332 if (attachments.Count == 0)
336 } 333 return;
337 334
338 // Need to check each attachment 335 // Get uuid of attachments
339 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 336 List<UUID> targets = new List<UUID>();
340 { 337 foreach (SceneObjectGroup sog in attachments)
341 if (li.GetHostID().Equals(id)) 338 {
342 continue; 339 if (!sog.IsDeleted)
340 targets.Add(sog.UUID);
341 }
343 342
344 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) 343 // Need to check each attachment
345 continue; 344 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
345 {
346 if (li.GetHostID().Equals(id))
347 continue;
346 348
347 if (targets.Contains(li.GetHostID())) 349 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
348 QueueMessage(new ListenerInfo(li, name, id, msg)); 350 continue;
349 }
350 351
351 return true; 352 if (targets.Contains(li.GetHostID()))
352 } 353 QueueMessage(new ListenerInfo(li, name, id, msg));
354 }
355 }
353 356
354 // Need to toss an error here 357 return;
355 if (channel == 0)
356 {
357 error = "Cannot use llRegionSayTo to message objects on channel 0";
358 return false;
359 } 358 }
360 359
360 // No avatar found so look for an object
361 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 361 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
362 { 362 {
363 // Dont process if this message is from yourself! 363 // Dont process if this message is from yourself!
@@ -375,7 +375,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
375 } 375 }
376 } 376 }
377 377
378 return true; 378 return;
379 } 379 }
380 380
381 protected void QueueMessage(ListenerInfo li) 381 protected void QueueMessage(ListenerInfo li)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index 8df1c7b..a7dd0dd 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -122,7 +122,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
122 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 122 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
123 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); 123 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
124 Object[] args = new Object[] { m_Config }; 124 Object[] args = new Object[] { m_Config };
125 IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args); 125// IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args)
126 ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
126 127
127 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 128 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
128 129
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
index 8395f83..008465f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
@@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
149 149
150 m_aScene = scene; 150 m_aScene = scene;
151 151
152 scene.RegisterModuleInterface<IAssetService>(this); 152 m_aScene.RegisterModuleInterface<IAssetService>(this);
153 } 153 }
154 154
155 public void RemoveRegion(Scene scene) 155 public void RemoveRegion(Scene scene)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs
index f0d21e6..4470799 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
55 MethodBase.GetCurrentMethod().DeclaringType); 55 MethodBase.GetCurrentMethod().DeclaringType);
56 56
57 private IUserManagement m_UserManagement; 57 private IUserManagement m_UserManagement;
58 private IGridService m_GridService; 58// private IGridService m_GridService;
59 59
60 private Scene m_Scene; 60 private Scene m_Scene;
61 AccessFlags m_accessValue = AccessFlags.None; 61 AccessFlags m_accessValue = AccessFlags.None;
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
65 { 65 {
66 m_Scene = scene; 66 m_Scene = scene;
67 m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); 67 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
68 m_GridService = scene.GridService; 68// m_GridService = scene.GridService;
69 69
70 if (config != null) 70 if (config != null)
71 { 71 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 3b862da..6cd077a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -149,9 +149,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
149 lock (m_scenes) 149 lock (m_scenes)
150 m_scenes[scene.RegionInfo.RegionID] = scene; 150 m_scenes[scene.RegionInfo.RegionID] = scene;
151 151
152 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); 152 scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
153 } 153 }
154 154
155
155 ///<summary> 156 ///<summary>
156 /// 157 ///
157 ///</summary> 158 ///</summary>
@@ -166,9 +167,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
166 167
167 #endregion ISharedRegionModule 168 #endregion ISharedRegionModule
168 169
169 void EventManager_OnPrimsLoaded(Scene s) 170 void OnLoginsEnabled(string regionName)
170 { 171 {
171 UploadMapTile(s); 172 Scene scene = null;
173 foreach (Scene s in m_scenes.Values)
174 if (s.RegionInfo.RegionName == regionName)
175 {
176 scene = s;
177 break;
178 }
179 if (scene != null)
180 UploadMapTile(scene);
172 } 181 }
173 182
174 183
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 6e75692..008992e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Linq;
29using System.Reflection; 30using System.Reflection;
30using log4net; 31using log4net;
31using Nini.Config; 32using Nini.Config;
@@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
41 public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService 42 public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService
42 { 43 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 // Version of this service
45 private const string m_Version = "SIMULATION/0.1";
46 45
47 private List<Scene> m_sceneList = new List<Scene>(); 46 /// <summary>
47 /// Version of this service
48 /// </summary>
49 private const string m_Version = "SIMULATION/0.1";
48 50
49 private IEntityTransferModule m_AgentTransferModule; 51 /// <summary>
50 protected IEntityTransferModule AgentTransferModule 52 /// Map region ID to scene.
51 { 53 /// </summary>
52 get 54 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
53 {
54 if (m_AgentTransferModule == null)
55 m_AgentTransferModule = m_sceneList[0].RequestModuleInterface<IEntityTransferModule>();
56 return m_AgentTransferModule;
57 }
58 }
59 55
56 /// <summary>
57 /// Is this module enabled?
58 /// </summary>
60 private bool m_ModuleEnabled = false; 59 private bool m_ModuleEnabled = false;
61 60
62 #region IRegionModule 61 #region IRegionModule
@@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
129 /// <param name="scene"></param> 128 /// <param name="scene"></param>
130 public void RemoveScene(Scene scene) 129 public void RemoveScene(Scene scene)
131 { 130 {
132 lock (m_sceneList) 131 lock (m_scenes)
133 { 132 {
134 if (m_sceneList.Contains(scene)) 133 if (m_scenes.ContainsKey(scene.RegionInfo.RegionID))
135 { 134 m_scenes.Remove(scene.RegionInfo.RegionID);
136 m_sceneList.Remove(scene); 135 else
137 } 136 m_log.WarnFormat(
137 "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present",
138 scene.RegionInfo.RegionName);
138 } 139 }
139 } 140 }
140 141
@@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
144 /// <param name="scene"></param> 145 /// <param name="scene"></param>
145 public void Init(Scene scene) 146 public void Init(Scene scene)
146 { 147 {
147 if (!m_sceneList.Contains(scene)) 148 lock (m_scenes)
148 { 149 {
149 lock (m_sceneList) 150 if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID))
150 { 151 m_scenes[scene.RegionInfo.RegionID] = scene;
151 m_sceneList.Add(scene); 152 else
152 } 153 m_log.WarnFormat(
153 154 "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present",
155 scene.RegionInfo.RegionName);
154 } 156 }
155 } 157 }
156 158
@@ -158,15 +160,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
158 160
159 #region ISimulation 161 #region ISimulation
160 162
161 public IScene GetScene(ulong regionhandle) 163 public IScene GetScene(UUID regionId)
162 { 164 {
163 foreach (Scene s in m_sceneList) 165 if (m_scenes.ContainsKey(regionId))
164 { 166 {
165 if (s.RegionInfo.RegionHandle == regionhandle) 167 return m_scenes[regionId];
166 return s; 168 }
169 else
170 {
171 // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather
172 // than making it obvious and fixable. Need to see if the error message comes up in practice.
173 Scene s = m_scenes.Values.ToArray()[0];
174
175 m_log.ErrorFormat(
176 "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead",
177 regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID);
178
179 return s;
167 } 180 }
168 // ? weird. should not happen
169 return m_sceneList[0];
170 } 181 }
171 182
172 public ISimulationService GetInnerService() 183 public ISimulationService GetInnerService()
@@ -187,13 +198,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
187 return false; 198 return false;
188 } 199 }
189 200
190 foreach (Scene s in m_sceneList) 201 if (m_scenes.ContainsKey(destination.RegionID))
191 { 202 {
192 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 203// m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName);
193 { 204 return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason);
194 m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName);
195 return s.NewUserConnection(aCircuit, teleportFlags, out reason);
196 }
197 } 205 }
198 206
199 reason = "Did not find region " + destination.RegionName; 207 reason = "Did not find region " + destination.RegionName;
@@ -205,17 +213,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
205 if (destination == null) 213 if (destination == null)
206 return false; 214 return false;
207 215
208 foreach (Scene s in m_sceneList) 216 if (m_scenes.ContainsKey(destination.RegionID))
209 { 217 {
210 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 218// m_log.DebugFormat(
211 { 219// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
212 m_log.DebugFormat( 220// s.RegionInfo.RegionName, destination.RegionHandle);
213 "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
214 s.RegionInfo.RegionName, destination.RegionHandle);
215 221
216 s.IncomingChildAgentDataUpdate(cAgentData); 222 return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData);
217 return true;
218 }
219 } 223 }
220 224
221// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); 225// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle);
@@ -231,11 +235,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
231 // simulator so when we receive the update we need to hand it to each of the 235 // simulator so when we receive the update we need to hand it to each of the
232 // scenes; scenes each check to see if the is a scene presence for the avatar 236 // scenes; scenes each check to see if the is a scene presence for the avatar
233 // note that we really don't need the GridRegion for this call 237 // note that we really don't need the GridRegion for this call
234 foreach (Scene s in m_sceneList) 238 foreach (Scene s in m_scenes.Values)
235 { 239 {
236 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); 240 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
237 s.IncomingChildAgentDataUpdate(cAgentData); 241 s.IncomingChildAgentDataUpdate(cAgentData);
238 } 242 }
243
239 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); 244 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
240 return true; 245 return true;
241 } 246 }
@@ -247,14 +252,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
247 if (destination == null) 252 if (destination == null)
248 return false; 253 return false;
249 254
250 foreach (Scene s in m_sceneList) 255 if (m_scenes.ContainsKey(destination.RegionID))
251 { 256 {
252 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 257// m_log.DebugFormat(
253 { 258// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
254 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); 259// s.RegionInfo.RegionName, destination.RegionHandle);
255 return s.IncomingRetrieveRootAgent(id, out agent); 260
256 } 261 return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent);
257 } 262 }
263
258 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); 264 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
259 return false; 265 return false;
260 } 266 }
@@ -266,59 +272,49 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
266 if (destination == null) 272 if (destination == null)
267 return false; 273 return false;
268 274
269 foreach (Scene s in m_sceneList) 275 if (m_scenes.ContainsKey(destination.RegionID))
270 { 276 {
271 if (s.RegionInfo.RegionID == destination.RegionID) 277// m_log.DebugFormat(
272 return s.QueryAccess(id, position, out reason); 278// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
279// s.RegionInfo.RegionName, destination.RegionHandle);
280
281 return m_scenes[destination.RegionID].QueryAccess(id, position, out reason);
273 } 282 }
283
284 //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess");
274 return false; 285 return false;
275 } 286 }
276 287
277 public bool ReleaseAgent(UUID origin, UUID id, string uri) 288 public bool ReleaseAgent(UUID originId, UUID agentId, string uri)
278 { 289 {
279 foreach (Scene s in m_sceneList) 290 if (m_scenes.ContainsKey(originId))
280 { 291 {
281 if (s.RegionInfo.RegionID == origin) 292// m_log.DebugFormat(
282 { 293// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
283 m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); 294// s.RegionInfo.RegionName, destination.RegionHandle);
284 AgentTransferModule.AgentArrivedAtDestination(id); 295
285 return true; 296 m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId);
286// return s.IncomingReleaseAgent(id); 297 return true;
287 }
288 } 298 }
299
289 //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); 300 //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin);
290 return false; 301 return false;
291 } 302 }
292 303
293 public bool CloseAgent(GridRegion destination, UUID id) 304 public bool CloseChildAgent(GridRegion destination, UUID id)
294 { 305 {
295 if (destination == null) 306 return CloseAgent(destination, id);
296 return false;
297
298 foreach (Scene s in m_sceneList)
299 {
300 if (s.RegionInfo.RegionID == destination.RegionID)
301 {
302 //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent");
303 return s.IncomingCloseAgent(id);
304 }
305 }
306 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
307 return false;
308 } 307 }
309 308
310 public bool CloseChildAgent(GridRegion destination, UUID id) 309 public bool CloseAgent(GridRegion destination, UUID id)
311 { 310 {
312 if (destination == null) 311 if (destination == null)
313 return false; 312 return false;
314 313
315 foreach (Scene s in m_sceneList) 314 if (m_scenes.ContainsKey(destination.RegionID))
316 { 315 {
317 if (s.RegionInfo.RegionID == destination.RegionID) 316 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); });
318 { 317 return true;
319 //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent");
320 return s.IncomingCloseChildAgent(id);
321 }
322 } 318 }
323 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
324 return false; 320 return false;
@@ -333,25 +329,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
333 if (destination == null) 329 if (destination == null)
334 return false; 330 return false;
335 331
336 foreach (Scene s in m_sceneList) 332 if (m_scenes.ContainsKey(destination.RegionID))
337 { 333 {
338 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 334// m_log.DebugFormat(
335// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
336// s.RegionInfo.RegionName, destination.RegionHandle);
337
338 Scene s = m_scenes[destination.RegionID];
339
340 if (isLocalCall)
341 {
342 // We need to make a local copy of the object
343 ISceneObject sogClone = sog.CloneForNewScene();
344 sogClone.SetState(sog.GetStateSnapshot(), s);
345 return s.IncomingCreateObject(newPosition, sogClone);
346 }
347 else
339 { 348 {
340 //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); 349 // Use the object as it came through the wire
341 if (isLocalCall) 350 return s.IncomingCreateObject(newPosition, sog);
342 {
343 // We need to make a local copy of the object
344 ISceneObject sogClone = sog.CloneForNewScene();
345 sogClone.SetState(sog.GetStateSnapshot(), s);
346 return s.IncomingCreateObject(newPosition, sogClone);
347 }
348 else
349 {
350 // Use the object as it came through the wire
351 return s.IncomingCreateObject(newPosition, sog);
352 }
353 } 351 }
354 } 352 }
353
355 return false; 354 return false;
356 } 355 }
357 356
@@ -360,13 +359,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
360 if (destination == null) 359 if (destination == null)
361 return false; 360 return false;
362 361
363 foreach (Scene s in m_sceneList) 362 if (m_scenes.ContainsKey(destination.RegionID))
364 { 363 {
365 if (s.RegionInfo.RegionHandle == destination.RegionHandle) 364// m_log.DebugFormat(
366 { 365// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
367 return s.IncomingCreateObject(userID, itemID); 366// s.RegionInfo.RegionName, destination.RegionHandle);
368 } 367
368 return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID);
369 } 369 }
370
370 return false; 371 return false;
371 } 372 }
372 373
@@ -377,18 +378,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
377 378
378 public bool IsLocalRegion(ulong regionhandle) 379 public bool IsLocalRegion(ulong regionhandle)
379 { 380 {
380 foreach (Scene s in m_sceneList) 381 foreach (Scene s in m_scenes.Values)
381 if (s.RegionInfo.RegionHandle == regionhandle) 382 if (s.RegionInfo.RegionHandle == regionhandle)
382 return true; 383 return true;
384
383 return false; 385 return false;
384 } 386 }
385 387
386 public bool IsLocalRegion(UUID id) 388 public bool IsLocalRegion(UUID id)
387 { 389 {
388 foreach (Scene s in m_sceneList) 390 return m_scenes.ContainsKey(id);
389 if (s.RegionInfo.RegionID == id)
390 return true;
391 return false;
392 } 391 }
393 392
394 #endregion 393 #endregion
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index 4b70692..d395413 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -151,9 +151,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
151 151
152 #region IInterregionComms 152 #region IInterregionComms
153 153
154 public IScene GetScene(ulong handle) 154 public IScene GetScene(UUID regionId)
155 { 155 {
156 return m_localBackend.GetScene(handle); 156 return m_localBackend.GetScene(regionId);
157 } 157 }
158 158
159 public ISimulationService GetInnerService() 159 public ISimulationService GetInnerService()
@@ -226,13 +226,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
226 return m_remoteConnector.RetrieveAgent(destination, id, out agent); 226 return m_remoteConnector.RetrieveAgent(destination, id, out agent);
227 227
228 return false; 228 return false;
229
230 } 229 }
231 230
232 public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) 231 public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
233 { 232 {
234 reason = "Communications failure"; 233 reason = "Communications failure";
235 version = "Unknown"; 234 version = "Unknown";
235
236 if (destination == null) 236 if (destination == null)
237 return false; 237 return false;
238 238
@@ -245,7 +245,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
245 return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); 245 return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason);
246 246
247 return false; 247 return false;
248
249 } 248 }
250 249
251 public bool ReleaseAgent(UUID origin, UUID id, string uri) 250 public bool ReleaseAgent(UUID origin, UUID id, string uri)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 38db239..619550c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization.External;
41using OpenSim.Region.CoreModules.World.Terrain; 41using OpenSim.Region.CoreModules.World.Terrain;
42using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
45 46
46namespace OpenSim.Region.CoreModules.World.Archiver 47namespace OpenSim.Region.CoreModules.World.Archiver
@@ -245,6 +246,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
245 // Reload serialized prims 246 // Reload serialized prims
246 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 247 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
247 248
249 UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject;
250
248 IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); 251 IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>();
249 int sceneObjectsLoadedCount = 0; 252 int sceneObjectsLoadedCount = 0;
250 253
@@ -266,11 +269,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
266 269
267 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 270 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
268 271
272 bool isTelehub = (sceneObject.UUID == oldTelehubUUID);
273
269 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned 274 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned
270 // on the same region server and multiple examples a single object archive to be imported 275 // on the same region server and multiple examples a single object archive to be imported
271 // to the same scene (when this is possible). 276 // to the same scene (when this is possible).
272 sceneObject.ResetIDs(); 277 sceneObject.ResetIDs();
273 278
279 if (isTelehub)
280 {
281 // Change the Telehub Object to the new UUID
282 m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID;
283 m_scene.RegionInfo.RegionSettings.Save();
284 oldTelehubUUID = UUID.Zero;
285 }
286
274 // Try to retain the original creator/owner/lastowner if their uuid is present on this grid 287 // Try to retain the original creator/owner/lastowner if their uuid is present on this grid
275 // or creator data is present. Otherwise, use the estate owner instead. 288 // or creator data is present. Otherwise, use the estate owner instead.
276 foreach (SceneObjectPart part in sceneObject.Parts) 289 foreach (SceneObjectPart part in sceneObject.Parts)
@@ -347,7 +360,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
347 int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; 360 int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount;
348 361
349 if (ignoredObjects > 0) 362 if (ignoredObjects > 0)
350 m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); 363 m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects);
364
365 if (oldTelehubUUID != UUID.Zero)
366 {
367 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID);
368 m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero;
369 m_scene.RegionInfo.RegionSettings.ClearSpawnPoints();
370 }
351 } 371 }
352 372
353 /// <summary> 373 /// <summary>
@@ -523,6 +543,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
523 currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; 543 currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4;
524 currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; 544 currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun;
525 currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; 545 currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
546 currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject;
547 currentRegionSettings.ClearSpawnPoints();
548 foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints())
549 currentRegionSettings.AddSpawnPoint(sp);
526 550
527 currentRegionSettings.Save(); 551 currentRegionSettings.Save();
528 552
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 4d459bf..4edaaca 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -40,6 +40,9 @@ using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain; 40using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode;
43 46
44namespace OpenSim.Region.CoreModules.World.Archiver 47namespace OpenSim.Region.CoreModules.World.Archiver
45{ 48{
@@ -64,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
64 /// Determine whether this archive will save assets. Default is true. 67 /// Determine whether this archive will save assets. Default is true.
65 /// </summary> 68 /// </summary>
66 public bool SaveAssets { get; set; } 69 public bool SaveAssets { get; set; }
67 70
71 protected ArchiverModule m_module;
68 protected Scene m_scene; 72 protected Scene m_scene;
69 protected Stream m_saveStream; 73 protected Stream m_saveStream;
70 protected Guid m_requestId; 74 protected Guid m_requestId;
@@ -72,17 +76,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
72 /// <summary> 76 /// <summary>
73 /// Constructor 77 /// Constructor
74 /// </summary> 78 /// </summary>
75 /// <param name="scene"></param> 79 /// <param name="module">Calling module</param>
76 /// <param name="savePath">The path to which to save data.</param> 80 /// <param name="savePath">The path to which to save data.</param>
77 /// <param name="requestId">The id associated with this request</param> 81 /// <param name="requestId">The id associated with this request</param>
78 /// <exception cref="System.IO.IOException"> 82 /// <exception cref="System.IO.IOException">
79 /// If there was a problem opening a stream for the file specified by the savePath 83 /// If there was a problem opening a stream for the file specified by the savePath
80 /// </exception> 84 /// </exception>
81 public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) 85 public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId)
82 { 86 {
83 try 87 try
84 { 88 {
85 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); 89 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression);
86 } 90 }
87 catch (EntryPointNotFoundException e) 91 catch (EntryPointNotFoundException e)
88 { 92 {
@@ -96,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
96 /// <summary> 100 /// <summary>
97 /// Constructor. 101 /// Constructor.
98 /// </summary> 102 /// </summary>
99 /// <param name="scene"></param> 103 /// <param name="module">Calling module</param>
100 /// <param name="saveStream">The stream to which to save data.</param> 104 /// <param name="saveStream">The stream to which to save data.</param>
101 /// <param name="requestId">The id associated with this request</param> 105 /// <param name="requestId">The id associated with this request</param>
102 public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) 106 public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId)
103 { 107 {
104 m_saveStream = saveStream; 108 m_saveStream = saveStream;
105 } 109 }
106 110
107 protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) 111 protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId)
108 { 112 {
109 m_scene = scene; 113 m_module = module;
114
115 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
116 // this.
117 if (m_module != null)
118 m_scene = m_module.Scene;
119
110 m_requestId = requestId; 120 m_requestId = requestId;
111 121
112 SaveAssets = true; 122 SaveAssets = true;
@@ -297,10 +307,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
297 if (checkPermissions.Contains("T") && !canTransfer) 307 if (checkPermissions.Contains("T") && !canTransfer)
298 partPermitted = false; 308 partPermitted = false;
299 309
310 // If the user is the Creator of the object then it can always be included in the OAR
311 bool creator = (obj.CreatorID.Guid == user.Guid);
312 if (creator)
313 partPermitted = true;
314
300 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); 315 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
301 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", 316 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}",
302 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, 317 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
303 // permissionClass, checkPermissions, canCopy, canTransfer, permitted); 318 // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted);
304 319
305 if (!partPermitted) 320 if (!partPermitted)
306 { 321 {
@@ -320,7 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
320 /// <returns></returns> 335 /// <returns></returns>
321 public string CreateControlFile(Dictionary<string, object> options) 336 public string CreateControlFile(Dictionary<string, object> options)
322 { 337 {
323 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; 338 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8;
324// 339//
325// if (options.ContainsKey("version")) 340// if (options.ContainsKey("version"))
326// { 341// {
@@ -356,32 +371,66 @@ namespace OpenSim.Region.CoreModules.World.Archiver
356 //if (majorVersion == 1) 371 //if (majorVersion == 1)
357 //{ 372 //{
358 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); 373 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
359 //} 374 //}
375
376 String s;
360 377
361 StringWriter sw = new StringWriter(); 378 using (StringWriter sw = new StringWriter())
362 XmlTextWriter xtw = new XmlTextWriter(sw); 379 {
363 xtw.Formatting = Formatting.Indented; 380 using (XmlTextWriter xtw = new XmlTextWriter(sw))
364 xtw.WriteStartDocument(); 381 {
365 xtw.WriteStartElement("archive"); 382 xtw.Formatting = Formatting.Indented;
366 xtw.WriteAttributeString("major_version", majorVersion.ToString()); 383 xtw.WriteStartDocument();
367 xtw.WriteAttributeString("minor_version", minorVersion.ToString()); 384 xtw.WriteStartElement("archive");
368 385 xtw.WriteAttributeString("major_version", majorVersion.ToString());
369 xtw.WriteStartElement("creation_info"); 386 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
370 DateTime now = DateTime.UtcNow; 387
371 TimeSpan t = now - new DateTime(1970, 1, 1); 388 xtw.WriteStartElement("creation_info");
372 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); 389 DateTime now = DateTime.UtcNow;
373 xtw.WriteElementString("id", UUID.Random().ToString()); 390 TimeSpan t = now - new DateTime(1970, 1, 1);
374 xtw.WriteEndElement(); 391 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
375 392 xtw.WriteElementString("id", UUID.Random().ToString());
376 xtw.WriteElementString("assets_included", SaveAssets.ToString()); 393 xtw.WriteEndElement();
377 394
378 xtw.WriteEndElement(); 395 xtw.WriteStartElement("region_info");
379 396
380 xtw.Flush(); 397 bool isMegaregion;
381 xtw.Close(); 398 Vector2 size;
382 399 IRegionCombinerModule rcMod = null;
383 String s = sw.ToString(); 400
384 sw.Close(); 401 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
402 // this, possibly by doing control file creation somewhere else.
403 if (m_module != null)
404 rcMod = m_module.RegionCombinerModule;
405
406 if (rcMod != null)
407 isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID);
408 else
409 isMegaregion = false;
410
411 if (isMegaregion)
412 size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
413 else
414 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize);
415
416 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
417 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
418
419 xtw.WriteEndElement();
420
421 xtw.WriteElementString("assets_included", SaveAssets.ToString());
422
423 xtw.WriteEndElement();
424
425 xtw.Flush();
426 }
427
428 s = sw.ToString();
429 }
430
431// if (m_scene != null)
432// Console.WriteLine(
433// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s);
385 434
386 return s; 435 return s;
387 } 436 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index f5a5a8d..bf3b124 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
45 private static readonly ILog m_log = 45 private static readonly ILog m_log =
46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private Scene m_scene; 48 public Scene Scene { get; private set; }
49 public IRegionCombinerModule RegionCombinerModule { get; private set; }
49 50
50 /// <value> 51 /// <value>
51 /// The file used to load and save an opensimulator archive if no filename has been specified 52 /// The file used to load and save an opensimulator archive if no filename has been specified
@@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
70 71
71 public void AddRegion(Scene scene) 72 public void AddRegion(Scene scene)
72 { 73 {
73 m_scene = scene; 74 Scene = scene;
74 m_scene.RegisterModuleInterface<IRegionArchiverModule>(this); 75 Scene.RegisterModuleInterface<IRegionArchiverModule>(this);
75 //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); 76 //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName);
76 } 77 }
77 78
78 public void RegionLoaded(Scene scene) 79 public void RegionLoaded(Scene scene)
79 { 80 {
81 RegionCombinerModule = scene.RequestModuleInterface<IRegionCombinerModule>();
80 } 82 }
81 83
82 public void RemoveRegion(Scene scene) 84 public void RemoveRegion(Scene scene)
@@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
165 public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options) 167 public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options)
166 { 168 {
167 m_log.InfoFormat( 169 m_log.InfoFormat(
168 "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); 170 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath);
169 171
170 new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); 172 new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options);
171 } 173 }
172 174
173 public void ArchiveRegion(Stream saveStream) 175 public void ArchiveRegion(Stream saveStream)
@@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
182 184
183 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) 185 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
184 { 186 {
185 new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); 187 new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options);
186 } 188 }
187 189
188 public void DearchiveRegion(string loadPath) 190 public void DearchiveRegion(string loadPath)
@@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
193 public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) 195 public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId)
194 { 196 {
195 m_log.InfoFormat( 197 m_log.InfoFormat(
196 "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); 198 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath);
197 199
198 new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); 200 new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion();
199 } 201 }
200 202
201 public void DearchiveRegion(Stream loadStream) 203 public void DearchiveRegion(Stream loadStream)
@@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
205 207
206 public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) 208 public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId)
207 { 209 {
208 new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); 210 new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion();
209 } 211 }
210 } 212 }
211} 213}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 63f1363..5deaf52 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
68 SerialiserModule serialiserModule = new SerialiserModule(); 68 SerialiserModule serialiserModule = new SerialiserModule();
69 TerrainModule terrainModule = new TerrainModule(); 69 TerrainModule terrainModule = new TerrainModule();
70 70
71 m_scene = SceneHelpers.SetupScene(); 71 m_scene = new SceneHelpers().SetupScene();
72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); 72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
73 } 73 }
74 74
@@ -102,9 +102,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
102 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); 102 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
103 Vector3 groupPosition = new Vector3(10, 20, 30); 103 Vector3 groupPosition = new Vector3(10, 20, 30);
104 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); 104 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
105 Vector3 offsetPosition = new Vector3(5, 10, 15); 105// Vector3 offsetPosition = new Vector3(5, 10, 15);
106 106
107 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; 107 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName };
108 } 108 }
109 109
110 protected SceneObjectPart CreateSceneObjectPart2() 110 protected SceneObjectPart CreateSceneObjectPart2()
@@ -292,6 +292,59 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
292 } 292 }
293 293
294 /// <summary> 294 /// <summary>
295 /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
296 /// 2 can come after 3).
297 /// </summary>
298 [Test]
299 public void TestLoadOarUnorderedParts()
300 {
301 TestHelpers.InMethod();
302
303 UUID ownerId = TestHelpers.ParseTail(0xaaaa);
304
305 MemoryStream archiveWriteStream = new MemoryStream();
306 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
307
308 tar.WriteFile(
309 ArchiveConstants.CONTROL_FILE_PATH,
310 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
311
312 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
313 SceneObjectPart sop2
314 = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
315 SceneObjectPart sop3
316 = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
317
318 // Add the parts so they will be written out in reverse order to the oar
319 sog1.AddPart(sop3);
320 sop3.LinkNum = 3;
321 sog1.AddPart(sop2);
322 sop2.LinkNum = 2;
323
324 tar.WriteFile(
325 ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
326 SceneObjectSerializer.ToXml2Format(sog1));
327
328 tar.Close();
329
330 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
331
332 lock (this)
333 {
334 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
335 m_archiverModule.DearchiveRegion(archiveReadStream);
336 }
337
338 Assert.That(m_lastErrorMessage, Is.Null);
339
340 SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
341 Assert.That(part2.LinkNum, Is.EqualTo(2));
342
343 SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
344 Assert.That(part3.LinkNum, Is.EqualTo(3));
345 }
346
347 /// <summary>
295 /// Test loading an OpenSim Region Archive. 348 /// Test loading an OpenSim Region Archive.
296 /// </summary> 349 /// </summary>
297 [Test] 350 [Test]
@@ -463,7 +516,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
463 SerialiserModule serialiserModule = new SerialiserModule(); 516 SerialiserModule serialiserModule = new SerialiserModule();
464 TerrainModule terrainModule = new TerrainModule(); 517 TerrainModule terrainModule = new TerrainModule();
465 518
466 TestScene scene2 = SceneHelpers.SetupScene(); 519 TestScene scene2 = new SceneHelpers().SetupScene();
467 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); 520 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
468 521
469 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is 522 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
@@ -534,6 +587,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
534 rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); 587 rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080");
535 rs.UseEstateSun = true; 588 rs.UseEstateSun = true;
536 rs.WaterHeight = 23; 589 rs.WaterHeight = 23;
590 rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111");
591 rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
537 592
538 tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); 593 tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs));
539 594
@@ -580,6 +635,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
580 Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); 635 Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080")));
581 Assert.That(loadedRs.UseEstateSun, Is.True); 636 Assert.That(loadedRs.UseEstateSun, Is.True);
582 Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); 637 Assert.That(loadedRs.WaterHeight, Is.EqualTo(23));
638 Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID
639 Assert.AreEqual(0, loadedRs.SpawnPoints().Count);
583 } 640 }
584 641
585 /// <summary> 642 /// <summary>
@@ -607,7 +664,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
607 SerialiserModule serialiserModule = new SerialiserModule(); 664 SerialiserModule serialiserModule = new SerialiserModule();
608 TerrainModule terrainModule = new TerrainModule(); 665 TerrainModule terrainModule = new TerrainModule();
609 666
610 Scene scene = SceneHelpers.SetupScene(); 667 Scene scene = new SceneHelpers().SetupScene();
611 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 668 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
612 669
613 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 670 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 1e743c3..ddc2a07 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -168,12 +168,18 @@ namespace OpenSim.Region.CoreModules.World.Estate
168 sendRegionInfoPacketToAll(); 168 sendRegionInfoPacketToAll();
169 } 169 }
170 170
171 public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture) 171 public void setEstateTerrainBaseTexture(int level, UUID texture)
172 {
173 setEstateTerrainBaseTexture(null, level, texture);
174 sendRegionHandshakeToAll();
175 }
176
177 public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int level, UUID texture)
172 { 178 {
173 if (texture == UUID.Zero) 179 if (texture == UUID.Zero)
174 return; 180 return;
175 181
176 switch (corner) 182 switch (level)
177 { 183 {
178 case 0: 184 case 0:
179 Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture; 185 Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture;
@@ -193,6 +199,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
193 sendRegionInfoPacketToAll(); 199 sendRegionInfoPacketToAll();
194 } 200 }
195 201
202 public void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue)
203 {
204 setEstateTerrainTextureHeights(null, corner, lowValue, highValue);
205 }
206
196 public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue) 207 public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue)
197 { 208 {
198 switch (corner) 209 switch (corner)
@@ -987,7 +998,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
987 { 998 {
988 RegionHandshakeArgs args = new RegionHandshakeArgs(); 999 RegionHandshakeArgs args = new RegionHandshakeArgs();
989 1000
990 args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManager(remoteClient.AgentId); 1001 args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(remoteClient.AgentId);
991 if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId) 1002 if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId)
992 args.isEstateManager = true; 1003 args.isEstateManager = true;
993 1004
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 02ac091..2fa0b3f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -1392,21 +1392,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1392 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) 1392 private void EventManagerOnRegisterCaps(UUID agentID, Caps caps)
1393 { 1393 {
1394 string capsBase = "/CAPS/" + caps.CapsObjectPath; 1394 string capsBase = "/CAPS/" + caps.CapsObjectPath;
1395 caps.RegisterHandler("RemoteParcelRequest", 1395 caps.RegisterHandler(
1396 new RestStreamHandler("POST", capsBase + remoteParcelRequestPath, 1396 "RemoteParcelRequest",
1397 delegate(string request, string path, string param, 1397 new RestStreamHandler(
1398 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 1398 "POST",
1399 { 1399 capsBase + remoteParcelRequestPath,
1400 return RemoteParcelRequest(request, path, param, agentID, caps); 1400 (request, path, param, httpRequest, httpResponse)
1401 })); 1401 => RemoteParcelRequest(request, path, param, agentID, caps),
1402 "RemoteParcelRequest",
1403 agentID.ToString()));
1404
1402 UUID parcelCapID = UUID.Random(); 1405 UUID parcelCapID = UUID.Random();
1403 caps.RegisterHandler("ParcelPropertiesUpdate", 1406 caps.RegisterHandler(
1404 new RestStreamHandler("POST", "/CAPS/" + parcelCapID, 1407 "ParcelPropertiesUpdate",
1405 delegate(string request, string path, string param, 1408 new RestStreamHandler(
1406 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 1409 "POST",
1407 { 1410 "/CAPS/" + parcelCapID,
1408 return ProcessPropertiesUpdate(request, path, param, agentID, caps); 1411 (request, path, param, httpRequest, httpResponse)
1409 })); 1412 => ProcessPropertiesUpdate(request, path, param, agentID, caps),
1413 "ParcelPropertiesUpdate",
1414 agentID.ToString()));
1410 } 1415 }
1411 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) 1416 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps)
1412 { 1417 {
@@ -1771,7 +1776,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1771 1776
1772 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 1777 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1773 1778
1774 targetAvatar.TeleportWithMomentum(pos); 1779 targetAvatar.TeleportWithMomentum(pos, null);
1775 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 1780 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1776 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 1781 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1777 1782
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 509c4d7..16792b3 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -447,7 +447,10 @@ namespace OpenSim.Region.CoreModules.World.Land
447 { 447 {
448 bool isMember; 448 bool isMember;
449 if (m_groupMemberCache.TryGetValue(avatar, out isMember)) 449 if (m_groupMemberCache.TryGetValue(avatar, out isMember))
450 {
451 m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
450 return isMember; 452 return isMember;
453 }
451 454
452 IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); 455 IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
453 if (groupsModule == null) 456 if (groupsModule == null)
@@ -484,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Land
484 if (m_scene.Permissions.IsAdministrator(avatar)) 487 if (m_scene.Permissions.IsAdministrator(avatar))
485 return false; 488 return false;
486 489
487 if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) 490 if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
488 return false; 491 return false;
489 492
490 if (avatar == LandData.OwnerID) 493 if (avatar == LandData.OwnerID)
@@ -514,7 +517,7 @@ namespace OpenSim.Region.CoreModules.World.Land
514 if (m_scene.Permissions.IsAdministrator(avatar)) 517 if (m_scene.Permissions.IsAdministrator(avatar))
515 return false; 518 return false;
516 519
517 if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) 520 if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar))
518 return false; 521 return false;
519 522
520 if (avatar == LandData.OwnerID) 523 if (avatar == LandData.OwnerID)
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 5122734..102b4d7 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -126,7 +126,6 @@ namespace OpenSim.Region.CoreModules.World.Land
126// m_log.DebugFormat( 126// m_log.DebugFormat(
127// "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", 127// "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted",
128// obj.Name, m_Scene.RegionInfo.RegionName); 128// obj.Name, m_Scene.RegionInfo.RegionName);
129
130 } 129 }
131 } 130 }
132 131
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
index e553ffa..b5ee4d2 100644
--- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
+++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests
64 { 64 {
65 m_pcm = new PrimCountModule(); 65 m_pcm = new PrimCountModule();
66 LandManagementModule lmm = new LandManagementModule(); 66 LandManagementModule lmm = new LandManagementModule();
67 m_scene = SceneHelpers.SetupScene(); 67 m_scene = new SceneHelpers().SetupScene();
68 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); 68 SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm);
69 69
70 int xParcelDivider = (int)Constants.RegionSize - 1; 70 int xParcelDivider = (int)Constants.RegionSize - 1;
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
index f86c790..aa306c7 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
@@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
225 int tc = 0; 225 int tc = 0;
226 double[,] hm = whichScene.Heightmap.GetDoubles(); 226 double[,] hm = whichScene.Heightmap.GetDoubles();
227 tc = Environment.TickCount; 227 tc = Environment.TickCount;
228 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); 228 m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
229 EntityBase[] objs = whichScene.GetEntities(); 229 EntityBase[] objs = whichScene.GetEntities();
230 Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); 230 Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>();
231 //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); 231 //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>();
@@ -541,7 +541,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
541 g.Dispose(); 541 g.Dispose();
542 } // lock entities objs 542 } // lock entities objs
543 543
544 m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); 544 m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms");
545 return mapbmp; 545 return mapbmp;
546 } 546 }
547 547
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs
index eb1a27f..992bff3 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
54 public void TerrainToBitmap(Bitmap mapbmp) 54 public void TerrainToBitmap(Bitmap mapbmp)
55 { 55 {
56 int tc = Environment.TickCount; 56 int tc = Environment.TickCount;
57 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); 57 m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain");
58 58
59 double[,] hm = m_scene.Heightmap.GetDoubles(); 59 double[,] hm = m_scene.Heightmap.GetDoubles();
60 bool ShadowDebugContinue = true; 60 bool ShadowDebugContinue = true;
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
238 } 238 }
239 } 239 }
240 } 240 }
241 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); 241 m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms");
242 } 242 }
243 } 243 }
244} 244}
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
index 1d2141e..d13c2ef 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs
@@ -278,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
278 public void TerrainToBitmap(Bitmap mapbmp) 278 public void TerrainToBitmap(Bitmap mapbmp)
279 { 279 {
280 int tc = Environment.TickCount; 280 int tc = Environment.TickCount;
281 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); 281 m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain");
282 282
283 // These textures should be in the AssetCache anyway, as every client conneting to this 283 // These textures should be in the AssetCache anyway, as every client conneting to this
284 // region needs them. Except on start, when the map is recreated (before anyone connected), 284 // region needs them. Except on start, when the map is recreated (before anyone connected),
@@ -412,7 +412,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
412 } 412 }
413 } 413 }
414 } 414 }
415 m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); 415 m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms");
416 } 416 }
417 } 417 }
418} 418}
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
index 5239f50..601e81e 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs
@@ -145,7 +145,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap
145 145
146 // Even though we're registering for POST we're going to get GETS and UPDATES too 146 // Even though we're registering for POST we're going to get GETS and UPDATES too
147 caps.RegisterHandler( 147 caps.RegisterHandler(
148 "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage)); 148 "ObjectMedia",
149 new RestStreamHandler(
150 "POST", omCapUrl, HandleObjectMediaMessage, "ObjectMedia", agentID.ToString()));
149 } 151 }
150 152
151 string omuCapUrl = "/CAPS/" + UUID.Random(); 153 string omuCapUrl = "/CAPS/" + UUID.Random();
@@ -157,7 +159,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap
157 159
158 // Even though we're registering for POST we're going to get GETS and UPDATES too 160 // Even though we're registering for POST we're going to get GETS and UPDATES too
159 caps.RegisterHandler( 161 caps.RegisterHandler(
160 "ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage)); 162 "ObjectMediaNavigate",
163 new RestStreamHandler(
164 "POST", omuCapUrl, HandleObjectMediaNavigateMessage, "ObjectMediaNavigate", agentID.ToString()));
161 } 165 }
162 } 166 }
163 167
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
index 4326606..0545250 100644
--- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
+++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
53 public void SetUp() 53 public void SetUp()
54 { 54 {
55 m_module = new MoapModule(); 55 m_module = new MoapModule();
56 m_scene = SceneHelpers.SetupScene(); 56 m_scene = new SceneHelpers().SetupScene();
57 SceneHelpers.SetupSceneModules(m_scene, m_module); 57 SceneHelpers.SetupSceneModules(m_scene, m_module);
58 } 58 }
59 59
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index f5a5c92..830d9cb 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -29,8 +29,10 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Text; 31using System.Text;
32using System.Text.RegularExpressions;
32using log4net; 33using log4net;
33using Mono.Addins; 34using Mono.Addins;
35using NDesk.Options;
34using Nini.Config; 36using Nini.Config;
35using OpenMetaverse; 37using OpenMetaverse;
36using OpenSim.Framework; 38using OpenSim.Framework;
@@ -78,49 +80,61 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
78 m_scene = scene; 80 m_scene = scene;
79 m_console = MainConsole.Instance; 81 m_console = MainConsole.Instance;
80 82
81 m_console.Commands.AddCommand("Regions", false, "delete object owner", 83 m_console.Commands.AddCommand(
82 "delete object owner <UUID>", 84 "Objects", false, "delete object owner",
83 "Delete a scene object by owner", HandleDeleteObject); 85 "delete object owner <UUID>",
84 m_console.Commands.AddCommand("Regions", false, "delete object creator", 86 "Delete a scene object by owner", HandleDeleteObject);
85 "delete object creator <UUID>", 87
86 "Delete a scene object by creator", HandleDeleteObject); 88 m_console.Commands.AddCommand(
87 m_console.Commands.AddCommand("Regions", false, "delete object uuid", 89 "Objects", false, "delete object creator",
88 "delete object uuid <UUID>", 90 "delete object creator <UUID>",
89 "Delete a scene object by uuid", HandleDeleteObject); 91 "Delete a scene object by creator", HandleDeleteObject);
90 m_console.Commands.AddCommand("Regions", false, "delete object name", 92
91 "delete object name <name>", 93 m_console.Commands.AddCommand(
92 "Delete a scene object by name", HandleDeleteObject); 94 "Objects", false, "delete object uuid",
93 m_console.Commands.AddCommand("Regions", false, "delete object outside", 95 "delete object uuid <UUID>",
94 "delete object outside", 96 "Delete a scene object by uuid", HandleDeleteObject);
95 "Delete all scene objects outside region boundaries", HandleDeleteObject); 97
98 m_console.Commands.AddCommand(
99 "Objects", false, "delete object name",
100 "delete object name [--regex] <name>",
101 "Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression",
102 HandleDeleteObject);
103
104 m_console.Commands.AddCommand(
105 "Objects", false, "delete object outside",
106 "delete object outside",
107 "Delete all scene objects outside region boundaries", HandleDeleteObject);
96 108
97 m_console.Commands.AddCommand( 109 m_console.Commands.AddCommand(
98 "Regions", 110 "Objects",
99 false, 111 false,
100 "show object uuid", 112 "show object uuid",
101 "show object uuid <UUID>", 113 "show object uuid <UUID>",
102 "Show details of a scene object with the given UUID", HandleShowObjectByUuid); 114 "Show details of a scene object with the given UUID", HandleShowObjectByUuid);
103 115
104 m_console.Commands.AddCommand( 116 m_console.Commands.AddCommand(
105 "Regions", 117 "Objects",
106 false, 118 false,
107 "show object name", 119 "show object name",
108 "show object name <name>", 120 "show object name [--regex] <name>",
109 "Show details of scene objects with the given name", HandleShowObjectByName); 121 "Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
122 HandleShowObjectByName);
110 123
111 m_console.Commands.AddCommand( 124 m_console.Commands.AddCommand(
112 "Regions", 125 "Objects",
113 false, 126 false,
114 "show part uuid", 127 "show part uuid",
115 "show part uuid <UUID>", 128 "show part uuid <UUID>",
116 "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); 129 "Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
117 130
118 m_console.Commands.AddCommand( 131 m_console.Commands.AddCommand(
119 "Regions", 132 "Objects",
120 false, 133 false,
121 "show part name", 134 "show part name",
122 "show part name <name>", 135 "show part name [--regex] <name>",
123 "Show details of scene object parts with the given name", HandleShowPartByName); 136 "Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
137 HandleShowPartByName);
124 } 138 }
125 139
126 public void RemoveRegion(Scene scene) 140 public void RemoveRegion(Scene scene)
@@ -165,22 +179,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
165 m_console.OutputFormat(sb.ToString()); 179 m_console.OutputFormat(sb.ToString());
166 } 180 }
167 181
168 private void HandleShowObjectByName(string module, string[] cmd) 182 private void HandleShowObjectByName(string module, string[] cmdparams)
169 { 183 {
170 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 184 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
171 return; 185 return;
172 186
173 if (cmd.Length < 4) 187 bool useRegex = false;
188 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
189
190 List<string> mainParams = options.Parse(cmdparams);
191
192 if (mainParams.Count < 4)
174 { 193 {
175 m_console.OutputFormat("Usage: show object name <name>"); 194 m_console.OutputFormat("Usage: show object name [--regex] <name>");
176 return; 195 return;
177 } 196 }
178 197
179 string name = cmd[3]; 198 string name = mainParams[3];
180 199
181 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 200 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
201 Action<SceneObjectGroup> searchAction;
182 202
183 m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }}); 203 if (useRegex)
204 {
205 Regex nameRegex = new Regex(name);
206 searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
207 }
208 else
209 {
210 searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
211 }
212
213 m_scene.ForEachSOG(searchAction);
184 214
185 if (sceneObjects.Count == 0) 215 if (sceneObjects.Count == 0)
186 { 216 {
@@ -231,22 +261,39 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
231 m_console.OutputFormat(sb.ToString()); 261 m_console.OutputFormat(sb.ToString());
232 } 262 }
233 263
234 private void HandleShowPartByName(string module, string[] cmd) 264 private void HandleShowPartByName(string module, string[] cmdparams)
235 { 265 {
236 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 266 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
237 return; 267 return;
238 268
239 if (cmd.Length < 4) 269 bool useRegex = false;
270 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
271
272 List<string> mainParams = options.Parse(cmdparams);
273
274 if (mainParams.Count < 4)
240 { 275 {
241 m_console.OutputFormat("Usage: show part name <name>"); 276 m_console.OutputFormat("Usage: show part name [--regex] <name>");
242 return; 277 return;
243 } 278 }
244 279
245 string name = cmd[3]; 280 string name = mainParams[3];
246 281
247 List<SceneObjectPart> parts = new List<SceneObjectPart>(); 282 List<SceneObjectPart> parts = new List<SceneObjectPart>();
248 283
249 m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } })); 284 Action<SceneObjectGroup> searchAction;
285
286 if (useRegex)
287 {
288 Regex nameRegex = new Regex(name);
289 searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } });
290 }
291 else
292 {
293 searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } });
294 }
295
296 m_scene.ForEachSOG(searchAction);
250 297
251 if (parts.Count == 0) 298 if (parts.Count == 0)
252 { 299 {
@@ -271,6 +318,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
271 sb.AppendFormat("Description: {0}\n", so.Description); 318 sb.AppendFormat("Description: {0}\n", so.Description);
272 sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); 319 sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName);
273 sb.AppendFormat("Parts: {0}\n", so.PrimCount); 320 sb.AppendFormat("Parts: {0}\n", so.PrimCount);
321 sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags);
274 322
275 return sb; 323 return sb;
276 } 324 }
@@ -282,7 +330,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
282 sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); 330 sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName);
283 sb.AppendFormat("Parent: {0}", 331 sb.AppendFormat("Parent: {0}",
284 sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); 332 sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID));
285 sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());; 333 sb.AppendFormat("Link number: {0}\n", sop.LinkNum);
334 sb.AppendFormat("Flags: {0}\n", sop.Flags);
286 335
287 return sb; 336 return sb;
288 } 337 }
@@ -306,105 +355,169 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
306 o = cmd[3]; 355 o = cmd[3];
307 } 356 }
308 357
309 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); 358 List<SceneObjectGroup> deletes = null;
310
311 UUID match; 359 UUID match;
360 bool requireConfirmation = true;
312 361
313 switch (mode) 362 switch (mode)
314 { 363 {
315 case "owner": 364 case "owner":
316 if (!UUID.TryParse(o, out match)) 365 if (!UUID.TryParse(o, out match))
317 return; 366 return;
318 367
319 m_scene.ForEachSOG(delegate (SceneObjectGroup g) 368 deletes = new List<SceneObjectGroup>();
320 {
321 if (g.OwnerID == match && !g.IsAttachment)
322 deletes.Add(g);
323 });
324 369
325// if (deletes.Count == 0) 370 m_scene.ForEachSOG(delegate (SceneObjectGroup g)
326// m_console.OutputFormat("No objects were found with owner {0}", match); 371 {
327 372 if (g.OwnerID == match && !g.IsAttachment)
328 break; 373 deletes.Add(g);
374 });
375
376 // if (deletes.Count == 0)
377 // m_console.OutputFormat("No objects were found with owner {0}", match);
378
379 break;
380
381 case "creator":
382 if (!UUID.TryParse(o, out match))
383 return;
329 384
330 case "creator": 385 deletes = new List<SceneObjectGroup>();
331 if (!UUID.TryParse(o, out match))
332 return;
333 386
334 m_scene.ForEachSOG(delegate (SceneObjectGroup g) 387 m_scene.ForEachSOG(delegate (SceneObjectGroup g)
335 { 388 {
336 if (g.RootPart.CreatorID == match && !g.IsAttachment) 389 if (g.RootPart.CreatorID == match && !g.IsAttachment)
337 deletes.Add(g); 390 deletes.Add(g);
338 }); 391 });
392
393 // if (deletes.Count == 0)
394 // m_console.OutputFormat("No objects were found with creator {0}", match);
395
396 break;
397
398 case "uuid":
399 if (!UUID.TryParse(o, out match))
400 return;
339 401
340// if (deletes.Count == 0) 402 requireConfirmation = false;
341// m_console.OutputFormat("No objects were found with creator {0}", match); 403 deletes = new List<SceneObjectGroup>();
404
405 m_scene.ForEachSOG(delegate (SceneObjectGroup g)
406 {
407 if (g.UUID == match && !g.IsAttachment)
408 deletes.Add(g);
409 });
410
411 // if (deletes.Count == 0)
412 // m_console.OutputFormat("No objects were found with uuid {0}", match);
413
414 break;
415
416 case "name":
417 deletes = GetDeleteCandidatesByName(module, cmd);
418 break;
419
420 case "outside":
421 deletes = new List<SceneObjectGroup>();
342 422
343 break; 423 m_scene.ForEachSOG(delegate (SceneObjectGroup g)
424 {
425 SceneObjectPart rootPart = g.RootPart;
426 bool delete = false;
427
428 if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
429 {
430 delete = true;
431 }
432 else
433 {
434 ILandObject parcel
435 = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
436
437 if (parcel == null || parcel.LandData.Name == "NO LAND")
438 delete = true;
439 }
440
441 if (delete && !g.IsAttachment && !deletes.Contains(g))
442 deletes.Add(g);
443 });
444
445 if (deletes.Count == 0)
446 m_console.OutputFormat("No objects were found outside region bounds");
447
448 break;
344 449
345 case "uuid": 450 default:
346 if (!UUID.TryParse(o, out match)) 451 m_console.OutputFormat("Unrecognized mode {0}", mode);
347 return; 452 return;
453 }
348 454
349 m_scene.ForEachSOG(delegate (SceneObjectGroup g) 455 if (deletes == null || deletes.Count <= 0)
350 { 456 return;
351 if (g.UUID == match && !g.IsAttachment)
352 deletes.Add(g);
353 });
354
355// if (deletes.Count == 0)
356// m_console.OutputFormat("No objects were found with uuid {0}", match);
357
358 break;
359 457
360 case "name": 458 if (requireConfirmation)
361 m_scene.ForEachSOG(delegate (SceneObjectGroup g) 459 {
460 string response = MainConsole.Instance.CmdPrompt(
461 string.Format(
462 "Are you sure that you want to delete {0} objects from {1}",
463 deletes.Count, m_scene.RegionInfo.RegionName),
464 "n");
465
466 if (response.ToLower() != "y")
362 { 467 {
363 if (g.RootPart.Name == o && !g.IsAttachment) 468 MainConsole.Instance.OutputFormat(
364 deletes.Add(g); 469 "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName);
365 });
366 470
367// if (deletes.Count == 0) 471 return;
368// m_console.OutputFormat("No objects were found with name {0}", o); 472 }
369 473 }
370 break;
371 474
372 case "outside": 475 m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName);
373 m_scene.ForEachSOG(delegate (SceneObjectGroup g)
374 {
375 SceneObjectPart rootPart = g.RootPart;
376 bool delete = false;
377 476
378 if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) 477 foreach (SceneObjectGroup g in deletes)
379 { 478 {
380 delete = true; 479 m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name);
381 } 480 m_scene.DeleteSceneObject(g, false);
382 else 481 }
383 { 482 }
384 ILandObject parcel
385 = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
386 483
387 if (parcel == null || parcel.LandData.Name == "NO LAND") 484 private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams)
388 delete = true; 485 {
389 } 486 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
487 return null;
390 488
391 if (delete && !g.IsAttachment && !deletes.Contains(g)) 489 bool useRegex = false;
392 deletes.Add(g); 490 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
393 });
394 491
395// if (deletes.Count == 0) 492 List<string> mainParams = options.Parse(cmdparams);
396// m_console.OutputFormat("No objects were found outside region bounds");
397 493
398 break; 494 if (mainParams.Count < 4)
495 {
496 m_console.OutputFormat("Usage: delete object name [--regex] <name>");
497 return null;
399 } 498 }
400 499
401 m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); 500 string name = mainParams[3];
402 501
403 foreach (SceneObjectGroup g in deletes) 502 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
503 Action<SceneObjectGroup> searchAction;
504
505 if (useRegex)
404 { 506 {
405 m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); 507 Regex nameRegex = new Regex(name);
406 m_scene.DeleteSceneObject(g, false); 508 searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
509 }
510 else
511 {
512 searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
407 } 513 }
514
515 m_scene.ForEachSOG(searchAction);
516
517 if (sceneObjects.Count == 0)
518 m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
519
520 return sceneObjects;
408 } 521 }
409 } 522 }
410} \ No newline at end of file 523} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 82ccaf8..8c97f58 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -166,6 +166,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
166 m_scene.Permissions.OnDeedParcel += CanDeedParcel; 166 m_scene.Permissions.OnDeedParcel += CanDeedParcel;
167 m_scene.Permissions.OnDeedObject += CanDeedObject; 167 m_scene.Permissions.OnDeedObject += CanDeedObject;
168 m_scene.Permissions.OnIsGod += IsGod; 168 m_scene.Permissions.OnIsGod += IsGod;
169 m_scene.Permissions.OnIsGridGod += IsGridGod;
169 m_scene.Permissions.OnIsAdministrator += IsAdministrator; 170 m_scene.Permissions.OnIsAdministrator += IsAdministrator;
170 m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; 171 m_scene.Permissions.OnDuplicateObject += CanDuplicateObject;
171 m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED 172 m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED
@@ -449,39 +450,49 @@ namespace OpenSim.Region.CoreModules.World.Permissions
449 } 450 }
450 451
451 /// <summary> 452 /// <summary>
452 /// Is the given user an administrator (in other words, a god)? 453 /// Is the user regarded as an administrator?
453 /// </summary> 454 /// </summary>
454 /// <param name="user"></param> 455 /// <param name="user"></param>
455 /// <returns></returns> 456 /// <returns></returns>
456 protected bool IsAdministrator(UUID user) 457 protected bool IsAdministrator(UUID user)
457 { 458 {
458 if (user == UUID.Zero) return false; 459 if (user == UUID.Zero)
459 460 return false;
460 if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) 461
461 { 462 if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod)
462 if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) 463 return true;
463 return true;
464 }
465 464
466 if (IsEstateManager(user) && m_RegionManagerIsGod) 465 if (IsEstateManager(user) && m_RegionManagerIsGod)
467 return true; 466 return true;
468 467
468 if (IsGridGod(user, null))
469 return true;
470
471 return false;
472 }
473
474 /// <summary>
475 /// Is the given user a God throughout the grid (not just in the current scene)?
476 /// </summary>
477 /// <param name="user">The user</param>
478 /// <param name="scene">Unused, can be null</param>
479 /// <returns></returns>
480 protected bool IsGridGod(UUID user, Scene scene)
481 {
482 DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name);
483 if (m_bypassPermissions) return m_bypassPermissionsValue;
484
485 if (user == UUID.Zero) return false;
486
469 if (m_allowGridGods) 487 if (m_allowGridGods)
470 { 488 {
471 ScenePresence sp = m_scene.GetScenePresence(user); 489 ScenePresence sp = m_scene.GetScenePresence(user);
472 if (sp != null) 490 if (sp != null)
473 { 491 return (sp.UserLevel >= 200);
474 if (sp.UserLevel >= 200)
475 return true;
476 return false;
477 }
478 492
479 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); 493 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user);
480 if (account != null) 494 if (account != null)
481 { 495 return (account.UserLevel >= 200);
482 if (account.UserLevel >= 200)
483 return true;
484 }
485 } 496 }
486 497
487 return false; 498 return false;
@@ -503,7 +514,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
503 { 514 {
504 if (user == UUID.Zero) return false; 515 if (user == UUID.Zero) return false;
505 516
506 return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); 517 return m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(user);
507 } 518 }
508 519
509#endregion 520#endregion
diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
new file mode 100644
index 0000000..2838e0c
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Text.RegularExpressions;
33using log4net;
34using Mono.Addins;
35using NDesk.Options;
36using Nini.Config;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Framework.Statistics;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.CoreModules.World.Objects.Commands
45{
46 /// <summary>
47 /// A module that holds commands for manipulating objects in the scene.
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCommandsModule")]
50 public class RegionCommandsModule : INonSharedRegionModule
51 {
52 private Scene m_scene;
53 private ICommandConsole m_console;
54
55 public string Name { get { return "Region Commands Module"; } }
56
57 public Type ReplaceableInterface { get { return null; } }
58
59 public void Initialise(IConfigSource source)
60 {
61// m_log.DebugFormat("[REGION COMMANDS MODULE]: INITIALIZED MODULE");
62 }
63
64 public void PostInitialise()
65 {
66// m_log.DebugFormat("[REGION COMMANDS MODULE]: POST INITIALIZED MODULE");
67 }
68
69 public void Close()
70 {
71// m_log.DebugFormat("[REGION COMMANDS MODULE]: CLOSED MODULE");
72 }
73
74 public void AddRegion(Scene scene)
75 {
76// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
77
78 m_scene = scene;
79 m_console = MainConsole.Instance;
80
81 m_console.Commands.AddCommand(
82 "Regions", false, "show scene",
83 "show scene",
84 "Show live scene information for the currently selected region.", HandleShowScene);
85 }
86
87 public void RemoveRegion(Scene scene)
88 {
89// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
90 }
91
92 public void RegionLoaded(Scene scene)
93 {
94// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
95 }
96
97 private void HandleShowScene(string module, string[] cmd)
98 {
99 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
100 return;
101
102 SimStatsReporter r = m_scene.StatsReporter;
103 float[] stats = r.LastReportedSimStats;
104
105 float timeDilation = stats[0];
106 float simFps = stats[1];
107 float physicsFps = stats[2];
108 float agentUpdates = stats[3];
109 float rootAgents = stats[4];
110 float childAgents = stats[5];
111 float totalPrims = stats[6];
112 float activePrims = stats[7];
113 float totalFrameTime = stats[8];
114// float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator
115 float physicsFrameTime = stats[10];
116 float otherFrameTime = stats[11];
117// float imageFrameTime = stats.StatsBlock[12].StatValue; // Ignored
118 float inPacketsPerSecond = stats[13];
119 float outPacketsPerSecond = stats[14];
120 float unackedBytes = stats[15];
121// float agentFrameTime = stats.StatsBlock[16].StatValue; // Not really used
122 float pendingDownloads = stats[17];
123 float pendingUploads = stats[18];
124 float activeScripts = stats[19];
125 float scriptLinesPerSecond = stats[20];
126
127 StringBuilder sb = new StringBuilder();
128 sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName);
129
130 ConsoleDisplayList dispList = new ConsoleDisplayList();
131 dispList.AddRow("Time Dilation", timeDilation);
132 dispList.AddRow("Sim FPS", simFps);
133 dispList.AddRow("Physics FPS", physicsFps);
134 dispList.AddRow("Avatars", rootAgents);
135 dispList.AddRow("Child agents", childAgents);
136 dispList.AddRow("Total prims", totalPrims);
137 dispList.AddRow("Scripts", activeScripts);
138 dispList.AddRow("Script lines processed per second", scriptLinesPerSecond);
139 dispList.AddRow("Physics enabled prims", activePrims);
140 dispList.AddRow("Total frame time", totalFrameTime);
141 dispList.AddRow("Physics frame time", physicsFrameTime);
142 dispList.AddRow("Other frame time", otherFrameTime);
143 dispList.AddRow("Agent Updates per second", agentUpdates);
144 dispList.AddRow("Packets processed from clients per second", inPacketsPerSecond);
145 dispList.AddRow("Packets sent to clients per second", outPacketsPerSecond);
146 dispList.AddRow("Bytes unacknowledged by clients", unackedBytes);
147 dispList.AddRow("Pending asset downloads to clients", pendingDownloads);
148 dispList.AddRow("Pending asset uploads from clients", pendingUploads);
149
150 dispList.AddToStringBuilder(sb);
151
152 MainConsole.Instance.Output(sb.ToString());
153 }
154 }
155} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
index d1d2020..7825e3e 100644
--- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
+++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs
@@ -343,7 +343,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
343 public void Init() 343 public void Init()
344 { 344 {
345 m_serialiserModule = new SerialiserModule(); 345 m_serialiserModule = new SerialiserModule();
346 m_scene = SceneHelpers.SetupScene(); 346 m_scene = new SceneHelpers().SetupScene();
347 SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule); 347 SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule);
348 } 348 }
349 349
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index da81dc1..d78ade5 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -59,28 +59,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
59 /// <returns>A terrain channel generated from the image.</returns> 59 /// <returns>A terrain channel generated from the image.</returns>
60 public virtual ITerrainChannel LoadFile(string filename) 60 public virtual ITerrainChannel LoadFile(string filename)
61 { 61 {
62 return LoadBitmap(new Bitmap(filename)); 62 using (Bitmap b = new Bitmap(filename))
63 return LoadBitmap(b);
63 } 64 }
64 65
65 public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h) 66 public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h)
66 { 67 {
67 Bitmap bitmap = new Bitmap(filename); 68 using (Bitmap bitmap = new Bitmap(filename))
68 ITerrainChannel retval = new TerrainChannel(true);
69
70 for (int x = 0; x < retval.Width; x++)
71 { 69 {
72 for (int y = 0; y < retval.Height; y++) 70 ITerrainChannel retval = new TerrainChannel(true);
71
72 for (int x = 0; x < retval.Width; x++)
73 { 73 {
74 retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; 74 for (int y = 0; y < retval.Height; y++)
75 {
76 retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128;
77 }
75 } 78 }
76 }
77 79
78 return retval; 80 return retval;
81 }
79 } 82 }
80 83
81 public virtual ITerrainChannel LoadStream(Stream stream) 84 public virtual ITerrainChannel LoadStream(Stream stream)
82 { 85 {
83 return LoadBitmap(new Bitmap(stream)); 86 using (Bitmap b = new Bitmap(stream))
87 return LoadBitmap(b);
84 } 88 }
85 89
86 protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap) 90 protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap)
@@ -134,35 +138,53 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
134 // "Saving the image to the same file it was constructed from is not allowed and throws an exception." 138 // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
135 string tempName = Path.GetTempFileName(); 139 string tempName = Path.GetTempFileName();
136 140
137 Bitmap entireBitmap = null; 141 Bitmap existingBitmap = null;
138 Bitmap thisBitmap = null; 142 Bitmap thisBitmap = null;
139 if (File.Exists(filename)) 143 Bitmap newBitmap = null;
144
145 try
140 { 146 {
141 File.Copy(filename, tempName, true); 147 if (File.Exists(filename))
142 entireBitmap = new Bitmap(tempName); 148 {
143 if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) 149 File.Copy(filename, tempName, true);
150 existingBitmap = new Bitmap(tempName);
151 if (existingBitmap.Width != fileWidth * regionSizeX || existingBitmap.Height != fileHeight * regionSizeY)
152 {
153 // old file, let's overwrite it
154 newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
155 }
156 else
157 {
158 newBitmap = existingBitmap;
159 }
160 }
161 else
144 { 162 {
145 // old file, let's overwrite it 163 newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
146 entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY);
147 } 164 }
165
166 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
167 // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
168 for (int x = 0; x < regionSizeX; x++)
169 for (int y = 0; y < regionSizeY; y++)
170 newBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
171
172 Save(newBitmap, filename);
148 } 173 }
149 else 174 finally
150 { 175 {
151 entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); 176 if (existingBitmap != null)
152 } 177 existingBitmap.Dispose();
153 178
154 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); 179 if (thisBitmap != null)
155// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); 180 thisBitmap.Dispose();
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 181
160 Save(entireBitmap, filename); 182 if (newBitmap != null)
161 thisBitmap.Dispose(); 183 newBitmap.Dispose();
162 entireBitmap.Dispose();
163 184
164 if (File.Exists(tempName)) 185 if (File.Exists(tempName))
165 File.Delete(tempName); 186 File.Delete(tempName);
187 }
166 } 188 }
167 189
168 protected virtual void Save(Bitmap bmp, string filename) 190 protected virtual void Save(Bitmap bmp, string filename)
@@ -226,16 +248,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
226 /// <returns>A System.Drawing.Bitmap containing a coloured image</returns> 248 /// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
227 protected static Bitmap CreateBitmapFromMap(ITerrainChannel map) 249 protected static Bitmap CreateBitmapFromMap(ITerrainChannel map)
228 { 250 {
229 Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); 251 int pallete;
230 252 Bitmap bmp;
231 int pallete = gradientmapLd.Height; 253 Color[] colours;
232 254
233 Bitmap bmp = new Bitmap(map.Width, map.Height); 255 using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png"))
234 Color[] colours = new Color[pallete];
235
236 for (int i = 0; i < pallete; i++)
237 { 256 {
238 colours[i] = gradientmapLd.GetPixel(0, i); 257 pallete = gradientmapLd.Height;
258
259 bmp = new Bitmap(map.Width, map.Height);
260 colours = new Color[pallete];
261
262 for (int i = 0; i < pallete; i++)
263 {
264 colours[i] = gradientmapLd.GetPixel(0, i);
265 }
239 } 266 }
240 267
241 for (int y = 0; y < map.Height; y++) 268 for (int y = 0; y < map.Height; y++)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
index 699d67a..9cc767a 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs
@@ -99,16 +99,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
99 99
100 private static Bitmap CreateBitmapFromMap(ITerrainChannel map) 100 private static Bitmap CreateBitmapFromMap(ITerrainChannel map)
101 { 101 {
102 Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); 102 int pallete;
103 Bitmap bmp;
104 Color[] colours;
103 105
104 int pallete = gradientmapLd.Height; 106 using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png"))
105
106 Bitmap bmp = new Bitmap(map.Width, map.Height);
107 Color[] colours = new Color[pallete];
108
109 for (int i = 0; i < pallete; i++)
110 { 107 {
111 colours[i] = gradientmapLd.GetPixel(0, i); 108 pallete = gradientmapLd.Height;
109
110 bmp = new Bitmap(map.Width, map.Height);
111 colours = new Color[pallete];
112
113 for (int i = 0; i < pallete; i++)
114 {
115 colours[i] = gradientmapLd.GetPixel(0, i);
116 }
112 } 117 }
113 118
114 for (int y = 0; y < map.Height; y++) 119 for (int y = 0; y < map.Height; y++)
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
index 5d2f893..b416b82 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
59 } 59 }
60 60
61 //Returns true if this extension is supported for terrain save-tile 61 //Returns true if this extension is supported for terrain save-tile
62 public bool SupportsTileSave() 62 public override bool SupportsTileSave()
63 { 63 {
64 return false; 64 return false;
65 } 65 }
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
index 1ebf916..71c71e6 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
65 bool eof = false; 65 bool eof = false;
66 66
67 int fileXPoints = 0; 67 int fileXPoints = 0;
68 int fileYPoints = 0; 68// int fileYPoints = 0;
69 69
70 // Terragen file 70 // Terragen file
71 while (eof == false) 71 while (eof == false)
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
75 { 75 {
76 case "SIZE": 76 case "SIZE":
77 fileXPoints = bs.ReadInt16() + 1; 77 fileXPoints = bs.ReadInt16() + 1;
78 fileYPoints = fileXPoints; 78// fileYPoints = fileXPoints;
79 bs.ReadInt16(); 79 bs.ReadInt16();
80 break; 80 break;
81 case "XPTS": 81 case "XPTS":
@@ -83,7 +83,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
83 bs.ReadInt16(); 83 bs.ReadInt16();
84 break; 84 break;
85 case "YPTS": 85 case "YPTS":
86 fileYPoints = bs.ReadInt16(); 86// fileYPoints = bs.ReadInt16();
87 bs.ReadInt16();
87 bs.ReadInt16(); 88 bs.ReadInt16();
88 break; 89 break;
89 case "ALTW": 90 case "ALTW":
@@ -164,10 +165,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
164 bool eof = false; 165 bool eof = false;
165 if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") 166 if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
166 { 167 {
167 168// int fileWidth = w;
168 int fileWidth = w; 169// int fileHeight = h;
169 int fileHeight = h;
170
171 170
172 // Terragen file 171 // Terragen file
173 while (eof == false) 172 while (eof == false)
@@ -176,17 +175,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
176 switch (tmp) 175 switch (tmp)
177 { 176 {
178 case "SIZE": 177 case "SIZE":
179 int sztmp = bs.ReadInt16() + 1; 178// int sztmp = bs.ReadInt16() + 1;
180 fileWidth = sztmp; 179// fileWidth = sztmp;
181 fileHeight = sztmp; 180// fileHeight = sztmp;
181 bs.ReadInt16();
182 bs.ReadInt16();
183 bs.ReadInt16();
182 bs.ReadInt16(); 184 bs.ReadInt16();
183 break; 185 break;
184 case "XPTS": 186 case "XPTS":
185 fileWidth = bs.ReadInt16(); 187// fileWidth = bs.ReadInt16();
188 bs.ReadInt16();
186 bs.ReadInt16(); 189 bs.ReadInt16();
187 break; 190 break;
188 case "YPTS": 191 case "YPTS":
189 fileHeight = bs.ReadInt16(); 192// fileHeight = bs.ReadInt16();
193 bs.ReadInt16();
190 bs.ReadInt16(); 194 bs.ReadInt16();
191 break; 195 break;
192 case "ALTW": 196 case "ALTW":
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index e2bd769..5b03ac7 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -724,6 +724,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
724 } 724 }
725 if (shouldTaint) 725 if (shouldTaint)
726 { 726 {
727 m_scene.EventManager.TriggerTerrainTainted();
727 m_tainted = true; 728 m_tainted = true;
728 } 729 }
729 } 730 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 899e5ea..be6b240 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -190,14 +190,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
190 { 190 {
191 //m_log.DebugFormat("[WORLD MAP]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); 191 //m_log.DebugFormat("[WORLD MAP]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
192 string capsBase = "/CAPS/" + caps.CapsObjectPath; 192 string capsBase = "/CAPS/" + caps.CapsObjectPath;
193 caps.RegisterHandler("MapLayer", 193 caps.RegisterHandler(
194 new RestStreamHandler("POST", capsBase + m_mapLayerPath, 194 "MapLayer",
195 delegate(string request, string path, string param, 195 new RestStreamHandler(
196 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 196 "POST",
197 { 197 capsBase + m_mapLayerPath,
198 return MapLayerRequest(request, path, param, 198 (request, path, param, httpRequest, httpResponse)
199 agentID, caps); 199 => MapLayerRequest(request, path, param, agentID, caps),
200 })); 200 "MapLayer",
201 agentID.ToString()));
201 } 202 }
202 203
203 /// <summary> 204 /// <summary>
diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
index 2f2b3e6..32e93b4 100644
--- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
+++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
@@ -42,13 +42,13 @@ namespace OpenSim.Region.DataSnapshot
42{ 42{
43 public class DataRequestHandler 43 public class DataRequestHandler
44 { 44 {
45 private Scene m_scene = null; 45// private Scene m_scene = null;
46 private DataSnapshotManager m_externalData = null; 46 private DataSnapshotManager m_externalData = null;
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 public DataRequestHandler(Scene scene, DataSnapshotManager externalData) 49 public DataRequestHandler(Scene scene, DataSnapshotManager externalData)
50 { 50 {
51 m_scene = scene; 51// m_scene = scene;
52 m_externalData = externalData; 52 m_externalData = externalData;
53 53
54 //Register HTTP handler 54 //Register HTTP handler
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 32f4eea..c605fc1 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -166,6 +166,19 @@ namespace OpenSim.Region.Framework.Interfaces
166 List<TaskInventoryItem> GetInventoryItems(); 166 List<TaskInventoryItem> GetInventoryItems();
167 167
168 /// <summary> 168 /// <summary>
169 /// Gets an inventory item by name
170 /// </summary>
171 /// <remarks>
172 /// This method returns the first inventory item that matches the given name. In SL this is all you need
173 /// since each item in a prim inventory must have a unique name.
174 /// </remarks>
175 /// <param name='name'></param>
176 /// <returns>
177 /// The inventory item. Null if no such item was found.
178 /// </returns>
179 TaskInventoryItem GetInventoryItem(string name);
180
181 /// <summary>
169 /// Get inventory items by name. 182 /// Get inventory items by name.
170 /// </summary> 183 /// </summary>
171 /// <param name="name"></param> 184 /// <param name="name"></param>
@@ -174,7 +187,17 @@ namespace OpenSim.Region.Framework.Interfaces
174 /// If no inventory item has that name then an empty list is returned. 187 /// If no inventory item has that name then an empty list is returned.
175 /// </returns> 188 /// </returns>
176 List<TaskInventoryItem> GetInventoryItems(string name); 189 List<TaskInventoryItem> GetInventoryItems(string name);
177 190
191 /// <summary>
192 /// Get inventory items by type.
193 /// </summary>
194 /// <param type="name"></param>
195 /// <returns>
196 /// A list of inventory items of that type.
197 /// If no inventory items of that type then an empty list is returned.
198 /// </returns>
199 List<TaskInventoryItem> GetInventoryItems(InventoryType type);
200
178 /// <summary> 201 /// <summary>
179 /// Get the scene object referenced by an inventory item. 202 /// Get the scene object referenced by an inventory item.
180 /// </summary> 203 /// </summary>
@@ -228,6 +251,16 @@ namespace OpenSim.Region.Framework.Interfaces
228 bool ContainsScripts(); 251 bool ContainsScripts();
229 252
230 /// <summary> 253 /// <summary>
254 /// Returns the count of scripts contained
255 /// </summary></returns>
256 int ScriptCount();
257
258 /// <summary>
259 /// Returns the count of running scripts contained
260 /// </summary></returns>
261 int RunningScriptCount();
262
263 /// <summary>
231 /// Get the uuids of all items in this inventory 264 /// Get the uuids of all items in this inventory
232 /// </summary> 265 /// </summary>
233 /// <returns></returns> 266 /// <returns></returns>
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 76f1641..5bc8e51 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -39,13 +39,30 @@ namespace OpenSim.Region.Framework.Interfaces
39 39
40 public interface IEntityTransferModule 40 public interface IEntityTransferModule
41 { 41 {
42 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, 42 /// <summary>
43 Vector3 lookAt, uint teleportFlags); 43 /// Teleport an agent within the same or to a different region.
44 /// </summary>
45 /// <param name='agent'></param>
46 /// <param name='regionHandle'>
47 /// The handle of the destination region. If it's the same as the region currently
48 /// occupied by the agent then the teleport will be within that region.
49 /// </param>
50 /// <param name='position'></param>
51 /// <param name='lookAt'></param>
52 /// <param name='teleportFlags'></param>
53 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags);
44 54
45 bool TeleportHome(UUID id, IClientAPI client); 55 bool TeleportHome(UUID id, IClientAPI client);
46 56
47 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, 57 void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination,
48 Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq); 58 Vector3 position, Vector3 lookAt, uint teleportFlags);
59
60 /// <summary>
61 /// Show whether the given agent is being teleported.
62 /// </summary>
63 /// <param name='id'>The agent ID</para></param>
64 /// <returns>true if the agent is in the process of being teleported, false otherwise.</returns>
65 bool IsInTransit(UUID id);
49 66
50 bool Cross(ScenePresence agent, bool isFlying); 67 bool Cross(ScenePresence agent, bool isFlying);
51 68
diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs
new file mode 100644
index 0000000..7a7b782
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Region.Framework.Interfaces
31{
32 public interface IEnvironmentModule
33 {
34 void ResetEnvironmentSettings(UUID regionUUID);
35 }
36}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index 72e79ed..ca2ad94 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -47,5 +47,8 @@ namespace OpenSim.Region.Framework.Interfaces
47 void sendRegionHandshakeToAll(); 47 void sendRegionHandshakeToAll();
48 void TriggerEstateInfoChange(); 48 void TriggerEstateInfoChange();
49 void TriggerRegionInfoChange(); 49 void TriggerRegionInfoChange();
50
51 void setEstateTerrainBaseTexture(int level, UUID texture);
52 void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue);
50 } 53 }
51} 54}
diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
index 1904011..3576e35 100644
--- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs
@@ -49,11 +49,15 @@ namespace OpenSim.Region.Framework.Interfaces
49 /// <param name="folderID"></param> 49 /// <param name="folderID"></param>
50 /// <param name="objectGroups"></param> 50 /// <param name="objectGroups"></param>
51 /// <param name="remoteClient"></param> 51 /// <param name="remoteClient"></param>
52 /// <param name="asAttachment">
53 /// Should be true if the object(s) are begin taken as attachments. False otherwise.
54 /// </param>
52 /// <returns> 55 /// <returns>
53 /// Returns the UUID of the newly created item asset (not the item itself). 56 /// A list of the items created. If there was more than one object and objects are not being coaleseced in
54 /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. 57 /// inventory, then the order of items is in the same order as the input objects.
55 /// </returns> 58 /// </returns>
56 UUID CopyToInventory(DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient); 59 List<InventoryItemBase> CopyToInventory(
60 DeRezAction action, UUID folderID, List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment);
57 61
58 /// <summary> 62 /// <summary>
59 /// Rez an object into the scene from the user's inventory 63 /// Rez an object into the scene from the user's inventory
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
new file mode 100644
index 0000000..baac6e8
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) Contributors
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 OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Framework.Interfaces
33{
34 public delegate void TakeValueCallback(string s);
35
36 public interface IJsonStoreModule
37 {
38 bool CreateStore(string value, out UUID result);
39 bool DestroyStore(UUID storeID);
40 bool TestPath(UUID storeID, string path, bool useJson);
41 bool SetValue(UUID storeID, string path, string value, bool useJson);
42 bool RemoveValue(UUID storeID, string path);
43 bool GetValue(UUID storeID, string path, bool useJson, out string value);
44
45 void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
46 void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
47 }
48}
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index dc3ff89..860483d 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -113,9 +113,11 @@ namespace OpenSim.Region.Framework.Interfaces
113 /// </param> 113 /// </param>
114 /// <param name="landAtTarget"> 114 /// <param name="landAtTarget">
115 /// If true and the avatar is flying when it reaches the target, land. 115 /// If true and the avatar is flying when it reaches the target, land.
116 /// </param> 116 /// </param> name="running">
117 /// If true, NPC moves with running speed.
117 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns> 118 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
118 bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget); 119 ///
120 bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running);
119 121
120 /// <summary> 122 /// <summary>
121 /// Stop the NPC's current movement. 123 /// Stop the NPC's current movement.
@@ -135,6 +137,36 @@ namespace OpenSim.Region.Framework.Interfaces
135 bool Say(UUID agentID, Scene scene, string text); 137 bool Say(UUID agentID, Scene scene, string text);
136 138
137 /// <summary> 139 /// <summary>
140 /// Get the NPC to say something.
141 /// </summary>
142 /// <param name="agentID">The UUID of the NPC</param>
143 /// <param name="scene"></param>
144 /// <param name="text"></param>
145 /// <param name="channel"></param>
146 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
147 bool Say(UUID agentID, Scene scene, string text, int channel);
148
149 /// <summary>
150 /// Get the NPC to shout something.
151 /// </summary>
152 /// <param name="agentID">The UUID of the NPC</param>
153 /// <param name="scene"></param>
154 /// <param name="text"></param>
155 /// <param name="channel"></param>
156 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
157 bool Shout(UUID agentID, Scene scene, string text, int channel);
158
159 /// <summary>
160 /// Get the NPC to whisper something.
161 /// </summary>
162 /// <param name="agentID">The UUID of the NPC</param>
163 /// <param name="scene"></param>
164 /// <param name="text"></param>
165 /// <param name="channel"></param>
166 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
167 bool Whisper(UUID agentID, Scene scene, string text, int channel);
168
169 /// <summary>
138 /// Sit the NPC. 170 /// Sit the NPC.
139 /// </summary> 171 /// </summary>
140 /// <param name="agentID"></param> 172 /// <param name="agentID"></param>
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs
new file mode 100644
index 0000000..e03ac5a
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32using OpenSim.Region.Framework.Scenes;
33using System.IO;
34using OpenMetaverse;
35
36namespace OpenSim.Region.Framework.Interfaces
37{
38 public interface IRegionCombinerModule
39 {
40 /// <summary>
41 /// Does the given id belong to the root region of a megaregion?
42 /// </summary>
43 bool IsRootForMegaregion(UUID regionId);
44
45 /// <summary>
46 /// Gets the size of megaregion.
47 /// </summary>
48 /// <remarks>
49 /// Returns size in meters.
50 /// Do not rely on this method remaining the same - this area is actively under development.
51 /// </remarks>
52 /// <param name="sceneId">
53 /// The id of the root region for a megaregion.
54 /// This may change in the future to allow any region id that makes up a megaregion.
55 /// Currently, will throw an exception if this does not match a root region.
56 /// </param>
57 Vector2 GetSizeOfMegaregion(UUID regionId);
58 }
59} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index ce66100..143af48 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -71,6 +71,12 @@ namespace OpenSim.Region.Framework.Interfaces
71 71
72 bool HasScript(UUID itemID, out bool running); 72 bool HasScript(UUID itemID, out bool running);
73 73
74 /// <summary>
75 /// Returns true if a script is running.
76 /// </summary>
77 /// <param name="itemID">The item ID of the script.</param>
78 bool GetScriptState(UUID itemID);
79
74 void SaveAllState(); 80 void SaveAllState();
75 81
76 /// <summary> 82 /// <summary>
@@ -79,6 +85,14 @@ namespace OpenSim.Region.Framework.Interfaces
79 void StartProcessing(); 85 void StartProcessing();
80 86
81 /// <summary> 87 /// <summary>
88 /// Get the execution times of all scripts in the given array if they are currently running.
89 /// </summary>
90 /// <returns>
91 /// A float the value is a representative execution time in milliseconds of all scripts in that Array.
92 /// </returns>
93 float GetScriptExecutionTime(List<UUID> itemIDs);
94
95 /// <summary>
82 /// Get the execution times of all scripts in each object. 96 /// Get the execution times of all scripts in each object.
83 /// </summary> 97 /// </summary>
84 /// <returns> 98 /// <returns>
@@ -87,4 +101,4 @@ namespace OpenSim.Region.Framework.Interfaces
87 /// </returns> 101 /// </returns>
88 Dictionary<uint, float> GetObjectScriptsExecutionTimes(); 102 Dictionary<uint, float> GetObjectScriptsExecutionTimes();
89 } 103 }
90} \ No newline at end of file 104}
diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
index 5295a72..0fcafcc 100644
--- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs
@@ -95,5 +95,26 @@ namespace OpenSim.Region.Framework.Interfaces
95 RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); 95 RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID);
96 void StoreRegionWindlightSettings(RegionLightShareData wl); 96 void StoreRegionWindlightSettings(RegionLightShareData wl);
97 void RemoveRegionWindlightSettings(UUID regionID); 97 void RemoveRegionWindlightSettings(UUID regionID);
98
99 /// <summary>
100 /// Load Environment settings from region storage
101 /// </summary>
102 /// <param name="regionUUID">the region UUID</param>
103 /// <returns>LLSD string for viewer</returns>
104 string LoadRegionEnvironmentSettings(UUID regionUUID);
105
106 /// <summary>
107 /// Store Environment settings into region storage
108 /// </summary>
109 /// <param name="regionUUID">the region UUID</param>
110 /// <param name="settings">LLSD string from viewer</param>
111 void StoreRegionEnvironmentSettings(UUID regionUUID, string settings);
112
113 /// <summary>
114 /// Delete Environment settings from region storage
115 /// </summary>
116 /// <param name="regionUUID">the region UUID</param>
117 void RemoveRegionEnvironmentSettings(UUID regionUUID);
118
98 } 119 }
99} 120}
diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
index 615f377..e424976 100644
--- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs
@@ -107,6 +107,26 @@ namespace OpenSim.Region.Framework.Interfaces
107 void StoreRegionWindlightSettings(RegionLightShareData wl); 107 void StoreRegionWindlightSettings(RegionLightShareData wl);
108 void RemoveRegionWindlightSettings(UUID regionID); 108 void RemoveRegionWindlightSettings(UUID regionID);
109 109
110 /// <summary>
111 /// Load Environment settings from region storage
112 /// </summary>
113 /// <param name="regionUUID">the region UUID</param>
114 /// <returns>LLSD string for viewer</returns>
115 string LoadRegionEnvironmentSettings(UUID regionUUID);
116
117 /// <summary>
118 /// Store Environment settings into region storage
119 /// </summary>
120 /// <param name="regionUUID">the region UUID</param>
121 /// <param name="settings">LLSD string from viewer</param>
122 void StoreRegionEnvironmentSettings(UUID regionUUID, string settings);
123
124 /// <summary>
125 /// Delete Environment settings from region storage
126 /// </summary>
127 /// <param name="regionUUID">the region UUID</param>
128 void RemoveRegionEnvironmentSettings(UUID regionUUID);
129
110 void Shutdown(); 130 void Shutdown();
111 } 131 }
112} 132}
diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
index 1b91166..457444c 100644
--- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
@@ -34,6 +34,7 @@ namespace OpenSim.Region.Framework.Interfaces
34{ 34{
35 public interface IUrlModule 35 public interface IUrlModule
36 { 36 {
37 string ExternalHostNameForLSL { get; }
37 UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID); 38 UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
38 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); 39 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
39 void ReleaseURL(string url); 40 void ReleaseURL(string url);
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index e8e375e..4e74781 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -103,7 +103,7 @@ namespace OpenSim.Region.Framework.Interfaces
103 /// <param name='msg'> 103 /// <param name='msg'>
104 /// Message. 104 /// Message.
105 /// </param> 105 /// </param>
106 bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error); 106 void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg);
107 107
108 /// <summary> 108 /// <summary>
109 /// Are there any listen events ready to be dispatched? 109 /// Are there any listen events ready to be dispatched?
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index e577958..9ddac19 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -294,6 +294,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation
294 return "FALLDOWN"; 294 return "FALLDOWN";
295 } 295 }
296 296
297 // Check if the user has stopped walking just now
298 if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero))
299 return "STAND";
300
297 return CurrentMovementAnimation; 301 return CurrentMovementAnimation;
298 } 302 }
299 303
@@ -418,13 +422,16 @@ namespace OpenSim.Region.Framework.Scenes.Animation
418 /// </summary> 422 /// </summary>
419 public void UpdateMovementAnimations() 423 public void UpdateMovementAnimations()
420 { 424 {
421 CurrentMovementAnimation = DetermineMovementAnimation(); 425 lock (m_animations)
426 {
427 CurrentMovementAnimation = DetermineMovementAnimation();
422 428
423// m_log.DebugFormat( 429// m_log.DebugFormat(
424// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", 430// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
425// CurrentMovementAnimation, m_scenePresence.Name); 431// CurrentMovementAnimation, m_scenePresence.Name);
426 432
427 TrySetMovementAnimation(CurrentMovementAnimation); 433 TrySetMovementAnimation(CurrentMovementAnimation);
434 }
428 } 435 }
429 436
430 public UUID[] GetAnimationArray() 437 public UUID[] GetAnimationArray()
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
index f678d07..f555b49 100644
--- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -117,7 +117,7 @@ namespace OpenSim.Region.Framework.Scenes
117 117
118 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) 118 private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
119 { 119 {
120 m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop"); 120// m_log.Debug("[ASYNC DELETER]: Starting send to inventory loop");
121 121
122 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved 122 // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
123 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as 123 // in a culture where decimal points are commas and then reloaded in a culture which just treats them as
@@ -147,15 +147,15 @@ namespace OpenSim.Region.Framework.Scenes
147 { 147 {
148 x = m_inventoryDeletes.Dequeue(); 148 x = m_inventoryDeletes.Dequeue();
149 149
150 m_log.DebugFormat( 150// m_log.DebugFormat(
151 "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", 151// "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
152 left, x.action, x.objectGroups.Count); 152// left, x.action, x.objectGroups.Count);
153 153
154 try 154 try
155 { 155 {
156 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 156 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
157 if (invAccess != null) 157 if (invAccess != null)
158 invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); 158 invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient, false);
159 159
160 if (x.permissionToDelete) 160 if (x.permissionToDelete)
161 { 161 {
@@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes
185 e.StackTrace); 185 e.StackTrace);
186 } 186 }
187 187
188 m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue."); 188// m_log.Debug("[ASYNC DELETER]: No objects left in inventory send queue.");
189 189
190 return false; 190 return false;
191 } 191 }
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 2365cfe..7688cf8 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -53,6 +53,10 @@ namespace OpenSim.Region.Framework.Scenes
53 53
54 public event ClientMovement OnClientMovement; 54 public event ClientMovement OnClientMovement;
55 55
56 public delegate void OnTerrainTaintedDelegate();
57
58 public event OnTerrainTaintedDelegate OnTerrainTainted;
59
56 public delegate void OnTerrainTickDelegate(); 60 public delegate void OnTerrainTickDelegate();
57 61
58 public delegate void OnTerrainUpdateDelegate(); 62 public delegate void OnTerrainUpdateDelegate();
@@ -484,6 +488,9 @@ namespace OpenSim.Region.Framework.Scenes
484 public delegate void SceneObjectPartUpdated(SceneObjectPart sop); 488 public delegate void SceneObjectPartUpdated(SceneObjectPart sop);
485 public event SceneObjectPartUpdated OnSceneObjectPartUpdated; 489 public event SceneObjectPartUpdated OnSceneObjectPartUpdated;
486 490
491 public delegate void ScenePresenceUpdated(ScenePresence sp);
492 public event ScenePresenceUpdated OnScenePresenceUpdated;
493
487 public delegate void RegionUp(GridRegion region); 494 public delegate void RegionUp(GridRegion region);
488 public event RegionUp OnRegionUp; 495 public event RegionUp OnRegionUp;
489 496
@@ -935,6 +942,27 @@ namespace OpenSim.Region.Framework.Scenes
935 } 942 }
936 } 943 }
937 944
945 public void TriggerTerrainTainted()
946 {
947 OnTerrainTaintedDelegate handlerTerrainTainted = OnTerrainTainted;
948 if (handlerTerrainTainted != null)
949 {
950 foreach (OnTerrainTickDelegate d in handlerTerrainTainted.GetInvocationList())
951 {
952 try
953 {
954 d();
955 }
956 catch (Exception e)
957 {
958 m_log.ErrorFormat(
959 "[EVENT MANAGER]: Delegate for TriggerTerrainTainted failed - continuing. {0} {1}",
960 e.Message, e.StackTrace);
961 }
962 }
963 }
964 }
965
938 public void TriggerParcelPrimCountAdd(SceneObjectGroup obj) 966 public void TriggerParcelPrimCountAdd(SceneObjectGroup obj)
939 { 967 {
940 OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = OnParcelPrimCountAdd; 968 OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = OnParcelPrimCountAdd;
@@ -2367,6 +2395,27 @@ namespace OpenSim.Region.Framework.Scenes
2367 } 2395 }
2368 } 2396 }
2369 2397
2398 public void TriggerScenePresenceUpdated(ScenePresence sp)
2399 {
2400 ScenePresenceUpdated handler = OnScenePresenceUpdated;
2401 if (handler != null)
2402 {
2403 foreach (ScenePresenceUpdated d in handler.GetInvocationList())
2404 {
2405 try
2406 {
2407 d(sp);
2408 }
2409 catch (Exception e)
2410 {
2411 m_log.ErrorFormat(
2412 "[EVENT MANAGER]: Delegate for TriggerScenePresenceUpdated failed - continuing. {0} {1}",
2413 e.Message, e.StackTrace);
2414 }
2415 }
2416 }
2417 }
2418
2370 public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args, 2419 public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args,
2371 int local_id, IClientAPI remote_client) 2420 int local_id, IClientAPI remote_client)
2372 { 2421 {
diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
index 6c5685c..1365831 100644
--- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
+++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
@@ -48,16 +48,19 @@ namespace OpenSim.Region.Framework.Scenes
48{ 48{
49 public class RegionStatsHandler : IStreamedRequestHandler 49 public class RegionStatsHandler : IStreamedRequestHandler
50 { 50 {
51 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
51 private string osRXStatsURI = String.Empty; 53 private string osRXStatsURI = String.Empty;
52 private string osXStatsURI = String.Empty; 54 private string osXStatsURI = String.Empty;
53 //private string osSecret = String.Empty; 55 //private string osSecret = String.Empty;
54 private OpenSim.Framework.RegionInfo regionInfo; 56 private OpenSim.Framework.RegionInfo regionInfo;
55 public string localZone = TimeZone.CurrentTimeZone.StandardName; 57 public string localZone = TimeZone.CurrentTimeZone.StandardName;
56 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); 58 public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
57
58 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
60 public RegionStatsHandler(OpenSim.Framework.RegionInfo region_info) 60 public string Name { get { return "RegionStats"; } }
61 public string Description { get { return "Region Statistics"; } }
62
63 public RegionStatsHandler(RegionInfo region_info)
61 { 64 {
62 regionInfo = region_info; 65 regionInfo = region_info;
63 osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret); 66 osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 29465c0..270b01b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -300,6 +300,10 @@ namespace OpenSim.Region.Framework.Scenes
300 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId); 300 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
301 AssetService.Store(asset); 301 AssetService.Store(asset);
302 302
303// m_log.DebugFormat(
304// "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}",
305// asset.ID, item.Name, part.Name, remoteClient.Name);
306
303 if (isScriptRunning) 307 if (isScriptRunning)
304 { 308 {
305 part.Inventory.RemoveScriptInstance(item.ItemID, false); 309 part.Inventory.RemoveScriptInstance(item.ItemID, false);
@@ -950,8 +954,8 @@ namespace OpenSim.Region.Framework.Scenes
950 sbyte invType, sbyte type, UUID olditemID) 954 sbyte invType, sbyte type, UUID olditemID)
951 { 955 {
952// m_log.DebugFormat( 956// m_log.DebugFormat(
953// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", 957// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}",
954// remoteClient.Name, name, folderID, olditemID); 958// remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType);
955 959
956 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 960 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
957 return; 961 return;
@@ -984,10 +988,10 @@ namespace OpenSim.Region.Framework.Scenes
984 asset.Type = type; 988 asset.Type = type;
985 asset.Name = name; 989 asset.Name = name;
986 asset.Description = description; 990 asset.Description = description;
987 991
988 CreateNewInventoryItem( 992 CreateNewInventoryItem(
989 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, 993 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
990 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, 994 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
991 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); 995 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
992 } 996 }
993 else 997 else
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 3ef1e29..cf68ff4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -38,8 +38,9 @@ namespace OpenSim.Region.Framework.Scenes
38{ 38{
39 public partial class Scene 39 public partial class Scene
40 { 40 {
41
41 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, 42 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
42 UUID fromID, bool fromAgent, bool broadcast) 43 UUID fromID, UUID targetID, bool fromAgent, bool broadcast)
43 { 44 {
44 OSChatMessage args = new OSChatMessage(); 45 OSChatMessage args = new OSChatMessage();
45 46
@@ -63,14 +64,20 @@ namespace OpenSim.Region.Framework.Scenes
63 } 64 }
64 65
65 args.From = fromName; 66 args.From = fromName;
66 //args. 67 args.TargetUUID = targetID;
67 68
68 if (broadcast) 69 if (broadcast)
69 EventManager.TriggerOnChatBroadcast(this, args); 70 EventManager.TriggerOnChatBroadcast(this, args);
70 else 71 else
71 EventManager.TriggerOnChatFromWorld(this, args); 72 EventManager.TriggerOnChatFromWorld(this, args);
72 } 73 }
73 74
75 protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
76 UUID fromID, bool fromAgent, bool broadcast)
77 {
78 SimChat(message, type, channel, fromPos, fromName, fromID, UUID.Zero, fromAgent, broadcast);
79 }
80
74 /// <summary> 81 /// <summary>
75 /// 82 ///
76 /// </summary> 83 /// </summary>
@@ -108,6 +115,19 @@ namespace OpenSim.Region.Framework.Scenes
108 { 115 {
109 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); 116 SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
110 } 117 }
118 /// <summary>
119 ///
120 /// </summary>
121 /// <param name="message"></param>
122 /// <param name="type"></param>
123 /// <param name="fromPos"></param>
124 /// <param name="fromName"></param>
125 /// <param name="fromAgentID"></param>
126 /// <param name="targetID"></param>
127 public void SimChatToAgent(UUID targetID, byte[] message, Vector3 fromPos, string fromName, UUID fromID, bool fromAgent)
128 {
129 SimChat(message, ChatTypeEnum.Say, 0, fromPos, fromName, fromID, targetID, fromAgent, false);
130 }
111 131
112 /// <summary> 132 /// <summary>
113 /// Invoked when the client requests a prim. 133 /// Invoked when the client requests a prim.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index e1fedf4..535d87a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -67,6 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene); 67 public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene);
68 public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand); 68 public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand);
69 public delegate bool IsGodHandler(UUID user, Scene requestFromScene); 69 public delegate bool IsGodHandler(UUID user, Scene requestFromScene);
70 public delegate bool IsGridGodHandler(UUID user, Scene requestFromScene);
70 public delegate bool IsAdministratorHandler(UUID user); 71 public delegate bool IsAdministratorHandler(UUID user);
71 public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); 72 public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene);
72 public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene); 73 public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene);
@@ -134,6 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
134 public event RunConsoleCommandHandler OnRunConsoleCommand; 135 public event RunConsoleCommandHandler OnRunConsoleCommand;
135 public event IssueEstateCommandHandler OnIssueEstateCommand; 136 public event IssueEstateCommandHandler OnIssueEstateCommand;
136 public event IsGodHandler OnIsGod; 137 public event IsGodHandler OnIsGod;
138 public event IsGridGodHandler OnIsGridGod;
137 public event IsAdministratorHandler OnIsAdministrator; 139 public event IsAdministratorHandler OnIsAdministrator;
138// public event EditParcelHandler OnEditParcel; 140// public event EditParcelHandler OnEditParcel;
139 public event EditParcelPropertiesHandler OnEditParcelProperties; 141 public event EditParcelPropertiesHandler OnEditParcelProperties;
@@ -728,6 +730,21 @@ namespace OpenSim.Region.Framework.Scenes
728 return true; 730 return true;
729 } 731 }
730 732
733 public bool IsGridGod(UUID user)
734 {
735 IsGridGodHandler handler = OnIsGridGod;
736 if (handler != null)
737 {
738 Delegate[] list = handler.GetInvocationList();
739 foreach (IsGridGodHandler h in list)
740 {
741 if (h(user, m_scene) == false)
742 return false;
743 }
744 }
745 return true;
746 }
747
731 public bool IsAdministrator(UUID user) 748 public bool IsAdministrator(UUID user)
732 { 749 {
733 IsAdministratorHandler handler = OnIsAdministrator; 750 IsAdministratorHandler handler = OnIsAdministrator;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a9a4cda..32c7262 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -77,7 +77,12 @@ namespace OpenSim.Region.Framework.Scenes
77 public bool DebugUpdates { get; private set; } 77 public bool DebugUpdates { get; private set; }
78 78
79 public SynchronizeSceneHandler SynchronizeScene; 79 public SynchronizeSceneHandler SynchronizeScene;
80 public SimStatsReporter StatsReporter; 80
81 /// <summary>
82 /// Statistical information for this scene.
83 /// </summary>
84 public SimStatsReporter StatsReporter { get; private set; }
85
81 public List<Border> NorthBorders = new List<Border>(); 86 public List<Border> NorthBorders = new List<Border>();
82 public List<Border> EastBorders = new List<Border>(); 87 public List<Border> EastBorders = new List<Border>();
83 public List<Border> SouthBorders = new List<Border>(); 88 public List<Border> SouthBorders = new List<Border>();
@@ -103,6 +108,7 @@ namespace OpenSim.Region.Framework.Scenes
103 public bool m_trustBinaries; 108 public bool m_trustBinaries;
104 public bool m_allowScriptCrossings; 109 public bool m_allowScriptCrossings;
105 public bool m_useFlySlow; 110 public bool m_useFlySlow;
111 public bool m_useTrashOnDelete = true;
106 112
107 /// <summary> 113 /// <summary>
108 /// Temporarily setting to trigger appearance resends at 60 second intervals. 114 /// Temporarily setting to trigger appearance resends at 60 second intervals.
@@ -163,7 +169,6 @@ namespace OpenSim.Region.Framework.Scenes
163 protected IConfigSource m_config; 169 protected IConfigSource m_config;
164 protected IRegionSerialiserModule m_serialiser; 170 protected IRegionSerialiserModule m_serialiser;
165 protected IDialogModule m_dialogModule; 171 protected IDialogModule m_dialogModule;
166 protected IEntityTransferModule m_teleportModule;
167 protected ICapabilitiesModule m_capsModule; 172 protected ICapabilitiesModule m_capsModule;
168 protected IGroupsModule m_groupsModule; 173 protected IGroupsModule m_groupsModule;
169 174
@@ -458,6 +463,7 @@ namespace OpenSim.Region.Framework.Scenes
458 { 463 {
459 if (m_simulationService == null) 464 if (m_simulationService == null)
460 m_simulationService = RequestModuleInterface<ISimulationService>(); 465 m_simulationService = RequestModuleInterface<ISimulationService>();
466
461 return m_simulationService; 467 return m_simulationService;
462 } 468 }
463 } 469 }
@@ -513,6 +519,7 @@ namespace OpenSim.Region.Framework.Scenes
513 } 519 }
514 520
515 public IAttachmentsModule AttachmentsModule { get; set; } 521 public IAttachmentsModule AttachmentsModule { get; set; }
522 public IEntityTransferModule EntityTransferModule { get; private set; }
516 523
517 public IAvatarFactoryModule AvatarFactory 524 public IAvatarFactoryModule AvatarFactory
518 { 525 {
@@ -589,6 +596,20 @@ namespace OpenSim.Region.Framework.Scenes
589 get { return m_sceneGraph.Entities; } 596 get { return m_sceneGraph.Entities; }
590 } 597 }
591 598
599
600 // used in sequence see: SpawnPoint()
601 private int m_SpawnPoint;
602 // can be closest/random/sequence
603 public string SpawnPointRouting
604 {
605 get; private set;
606 }
607 // allow landmarks to pass
608 public bool TelehubAllowLandmarks
609 {
610 get; private set;
611 }
612
592 #endregion Properties 613 #endregion Properties
593 614
594 #region Constructors 615 #region Constructors
@@ -606,7 +627,7 @@ namespace OpenSim.Region.Framework.Scenes
606 627
607 Random random = new Random(); 628 Random random = new Random();
608 629
609 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); 630 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
610 m_moduleLoader = moduleLoader; 631 m_moduleLoader = moduleLoader;
611 m_authenticateHandler = authen; 632 m_authenticateHandler = authen;
612 m_sceneGridService = sceneGridService; 633 m_sceneGridService = sceneGridService;
@@ -726,6 +747,9 @@ namespace OpenSim.Region.Framework.Scenes
726 m_maxPhys = RegionInfo.PhysPrimMax; 747 m_maxPhys = RegionInfo.PhysPrimMax;
727 } 748 }
728 749
750 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
751 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
752
729 // Here, if clamping is requested in either global or 753 // Here, if clamping is requested in either global or
730 // local config, it will be used 754 // local config, it will be used
731 // 755 //
@@ -735,6 +759,7 @@ namespace OpenSim.Region.Framework.Scenes
735 m_clampPrimSize = true; 759 m_clampPrimSize = true;
736 } 760 }
737 761
762 m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
738 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); 763 m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
739 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); 764 m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
740 m_dontPersistBefore = 765 m_dontPersistBefore =
@@ -833,13 +858,11 @@ namespace OpenSim.Region.Framework.Scenes
833 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 858 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
834 } 859 }
835 860
836 /// <summary>
837 /// Mock constructor for scene group persistency unit tests.
838 /// SceneObjectGroup RegionId property is delegated to Scene.
839 /// </summary>
840 /// <param name="regInfo"></param>
841 public Scene(RegionInfo regInfo) 861 public Scene(RegionInfo regInfo)
842 { 862 {
863 PhysicalPrims = true;
864 CollidablePrims = true;
865
843 BordersLocked = true; 866 BordersLocked = true;
844 Border northBorder = new Border(); 867 Border northBorder = new Border();
845 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<--- 868 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
@@ -866,8 +889,6 @@ namespace OpenSim.Region.Framework.Scenes
866 m_eventManager = new EventManager(); 889 m_eventManager = new EventManager();
867 890
868 m_permissions = new ScenePermissions(this); 891 m_permissions = new ScenePermissions(this);
869
870// m_lastUpdate = Util.EnvironmentTickCount();
871 } 892 }
872 893
873 #endregion 894 #endregion
@@ -936,8 +957,8 @@ namespace OpenSim.Region.Framework.Scenes
936 List<ulong> old = new List<ulong>(); 957 List<ulong> old = new List<ulong>();
937 old.Add(otherRegion.RegionHandle); 958 old.Add(otherRegion.RegionHandle);
938 agent.DropOldNeighbours(old); 959 agent.DropOldNeighbours(old);
939 if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) 960 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
940 m_teleportModule.EnableChildAgent(agent, otherRegion); 961 EntityTransferModule.EnableChildAgent(agent, otherRegion);
941 }); 962 });
942 } 963 }
943 catch (NullReferenceException) 964 catch (NullReferenceException)
@@ -1044,13 +1065,13 @@ namespace OpenSim.Region.Framework.Scenes
1044 } 1065 }
1045 } 1066 }
1046 1067
1068 m_log.Error("[REGION]: Closing");
1069 Close();
1070
1047 if (PhysicsScene != null) 1071 if (PhysicsScene != null)
1048 { 1072 {
1049 PhysicsScene.Dispose(); 1073 PhysicsScene.Dispose();
1050 } 1074 }
1051
1052 m_log.Error("[REGION]: Closing");
1053 Close();
1054 1075
1055 m_log.Error("[REGION]: Firing Region Restart Message"); 1076 m_log.Error("[REGION]: Firing Region Restart Message");
1056 1077
@@ -1074,8 +1095,8 @@ namespace OpenSim.Region.Framework.Scenes
1074 { 1095 {
1075 ForEachRootScenePresence(delegate(ScenePresence agent) 1096 ForEachRootScenePresence(delegate(ScenePresence agent)
1076 { 1097 {
1077 if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) 1098 if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1078 m_teleportModule.EnableChildAgent(agent, r); 1099 EntityTransferModule.EnableChildAgent(agent, r);
1079 }); 1100 });
1080 } 1101 }
1081 catch (NullReferenceException) 1102 catch (NullReferenceException)
@@ -1265,7 +1286,7 @@ namespace OpenSim.Region.Framework.Scenes
1265 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); 1286 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
1266 m_dialogModule = RequestModuleInterface<IDialogModule>(); 1287 m_dialogModule = RequestModuleInterface<IDialogModule>();
1267 m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); 1288 m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1268 m_teleportModule = RequestModuleInterface<IEntityTransferModule>(); 1289 EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
1269 m_groupsModule = RequestModuleInterface<IGroupsModule>(); 1290 m_groupsModule = RequestModuleInterface<IGroupsModule>();
1270 } 1291 }
1271 1292
@@ -1404,6 +1425,14 @@ namespace OpenSim.Region.Framework.Scenes
1404 1425
1405 try 1426 try
1406 { 1427 {
1428 // Apply taints in terrain module to terrain in physics scene
1429 if (Frame % m_update_terrain == 0)
1430 {
1431 terMS = Util.EnvironmentTickCount();
1432 UpdateTerrain();
1433 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1434 }
1435
1407 tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1436 tmpPhysicsMS2 = Util.EnvironmentTickCount();
1408 if ((Frame % m_update_physics == 0) && m_physics_enabled) 1437 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1409 m_sceneGraph.UpdatePreparePhysics(); 1438 m_sceneGraph.UpdatePreparePhysics();
@@ -1468,13 +1497,6 @@ namespace OpenSim.Region.Framework.Scenes
1468 backupMS = Util.EnvironmentTickCountSubtract(backMS); 1497 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1469 } 1498 }
1470 1499
1471 if (Frame % m_update_terrain == 0)
1472 {
1473 terMS = Util.EnvironmentTickCount();
1474 UpdateTerrain();
1475 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1476 }
1477
1478 //if (Frame % m_update_land == 0) 1500 //if (Frame % m_update_land == 0)
1479 //{ 1501 //{
1480 // int ldMS = Util.EnvironmentTickCount(); 1502 // int ldMS = Util.EnvironmentTickCount();
@@ -2363,8 +2385,8 @@ namespace OpenSim.Region.Framework.Scenes
2363 return; 2385 return;
2364 } 2386 }
2365 2387
2366 if (m_teleportModule != null) 2388 if (EntityTransferModule != null)
2367 m_teleportModule.Cross(grp, attemptedPosition, silent); 2389 EntityTransferModule.Cross(grp, attemptedPosition, silent);
2368 } 2390 }
2369 2391
2370 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2392 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
@@ -2684,10 +2706,10 @@ namespace OpenSim.Region.Framework.Scenes
2684 { 2706 {
2685 SceneObjectGroup grp = sceneObject; 2707 SceneObjectGroup grp = sceneObject;
2686 2708
2687 m_log.DebugFormat( 2709// m_log.DebugFormat(
2688 "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); 2710// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID);
2689 m_log.DebugFormat( 2711// m_log.DebugFormat(
2690 "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); 2712// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
2691 2713
2692 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2714 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2693 2715
@@ -2783,7 +2805,8 @@ namespace OpenSim.Region.Framework.Scenes
2783 if (sp == null) 2805 if (sp == null)
2784 { 2806 {
2785 m_log.DebugFormat( 2807 m_log.DebugFormat(
2786 "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); 2808 "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
2809 client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
2787 2810
2788 m_clientManager.Add(client); 2811 m_clientManager.Add(client);
2789 SubscribeToClientEvents(client); 2812 SubscribeToClientEvents(client);
@@ -3207,8 +3230,10 @@ namespace OpenSim.Region.Framework.Scenes
3207 /// <param name="client">The IClientAPI for the client</param> 3230 /// <param name="client">The IClientAPI for the client</param>
3208 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client) 3231 public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
3209 { 3232 {
3210 if (m_teleportModule != null) 3233 if (EntityTransferModule != null)
3211 return m_teleportModule.TeleportHome(agentId, client); 3234 {
3235 EntityTransferModule.TeleportHome(agentId, client);
3236 }
3212 else 3237 else
3213 { 3238 {
3214 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); 3239 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
@@ -3382,8 +3407,8 @@ namespace OpenSim.Region.Framework.Scenes
3382 try 3407 try
3383 { 3408 {
3384 m_log.DebugFormat( 3409 m_log.DebugFormat(
3385 "[SCENE]: Removing {0} agent {1} from region {2}", 3410 "[SCENE]: Removing {0} agent {1} {2} from region {3}",
3386 (isChildAgent ? "child" : "root"), agentID, RegionInfo.RegionName); 3411 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
3387 3412
3388 m_sceneGraph.removeUserCount(!isChildAgent); 3413 m_sceneGraph.removeUserCount(!isChildAgent);
3389 3414
@@ -3554,7 +3579,7 @@ namespace OpenSim.Region.Framework.Scenes
3554 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) 3579 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
3555 { 3580 {
3556 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3581 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3557 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); 3582 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
3558 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); 3583 bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
3559 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); 3584 bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
3560 3585
@@ -3570,8 +3595,17 @@ namespace OpenSim.Region.Framework.Scenes
3570 // Don't disable this log message - it's too helpful 3595 // Don't disable this log message - it's too helpful
3571 m_log.DebugFormat( 3596 m_log.DebugFormat(
3572 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", 3597 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
3573 RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname, 3598 RegionInfo.RegionName,
3574 agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos); 3599 (agent.child ? "child" : "root"),
3600 agent.firstname,
3601 agent.lastname,
3602 agent.AgentID,
3603 agent.circuitcode,
3604 agent.IPAddress,
3605 agent.Viewer,
3606 ((TPFlags)teleportFlags).ToString(),
3607 agent.startpos
3608 );
3575 3609
3576 if (LoginsDisabled) 3610 if (LoginsDisabled)
3577 { 3611 {
@@ -3586,7 +3620,11 @@ namespace OpenSim.Region.Framework.Scenes
3586 // We have a zombie from a crashed session. 3620 // We have a zombie from a crashed session.
3587 // Or the same user is trying to be root twice here, won't work. 3621 // Or the same user is trying to be root twice here, won't work.
3588 // Kill it. 3622 // Kill it.
3589 m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName); 3623 m_log.DebugFormat(
3624 "[SCENE]: Zombie scene presence detected for {0} in {1}",
3625 agent.AgentID,
3626 RegionInfo.RegionName
3627 );
3590 sp.ControllingClient.Close(); 3628 sp.ControllingClient.Close();
3591 sp = null; 3629 sp = null;
3592 } 3630 }
@@ -3613,8 +3651,7 @@ namespace OpenSim.Region.Framework.Scenes
3613 { 3651 {
3614 if (!VerifyUserPresence(agent, out reason)) 3652 if (!VerifyUserPresence(agent, out reason))
3615 return false; 3653 return false;
3616 } 3654 } catch (Exception e)
3617 catch (Exception e)
3618 { 3655 {
3619 m_log.ErrorFormat( 3656 m_log.ErrorFormat(
3620 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3657 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
@@ -3649,8 +3686,7 @@ namespace OpenSim.Region.Framework.Scenes
3649 CapsModule.SetAgentCapsSeeds(agent); 3686 CapsModule.SetAgentCapsSeeds(agent);
3650 CapsModule.CreateCaps(agent.AgentID); 3687 CapsModule.CreateCaps(agent.AgentID);
3651 } 3688 }
3652 } 3689 } else
3653 else
3654 { 3690 {
3655 // Let the SP know how we got here. This has a lot of interesting 3691 // Let the SP know how we got here. This has a lot of interesting
3656 // uses down the line. 3692 // uses down the line.
@@ -3673,7 +3709,7 @@ namespace OpenSim.Region.Framework.Scenes
3673 agent.teleportFlags = teleportFlags; 3709 agent.teleportFlags = teleportFlags;
3674 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3710 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
3675 3711
3676 if (vialogin) 3712 if (vialogin)
3677 { 3713 {
3678// CleanDroppedAttachments(); 3714// CleanDroppedAttachments();
3679 3715
@@ -3714,8 +3750,7 @@ namespace OpenSim.Region.Framework.Scenes
3714 agent.startpos.Z = 720; 3750 agent.startpos.Z = 720;
3715 } 3751 }
3716 } 3752 }
3717 } 3753 } else
3718 else
3719 { 3754 {
3720 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 3755 if (agent.startpos.X > EastBorders[0].BorderLine.Z)
3721 { 3756 {
@@ -3741,10 +3776,19 @@ namespace OpenSim.Region.Framework.Scenes
3741 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); 3776 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
3742 // Can have multiple SpawnPoints 3777 // Can have multiple SpawnPoints
3743 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); 3778 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
3744 if ( spawnpoints.Count > 1) 3779 if (spawnpoints.Count > 1)
3745 { 3780 {
3746 // We have multiple SpawnPoints, Route the agent to a random one 3781 // We have multiple SpawnPoints, Route the agent to a random or sequential one
3747 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 3782 if (SpawnPointRouting == "random")
3783 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
3784 telehub.AbsolutePosition,
3785 telehub.GroupRotation
3786 );
3787 else
3788 agent.startpos = spawnpoints[SpawnPoint()].GetLocation(
3789 telehub.AbsolutePosition,
3790 telehub.GroupRotation
3791 );
3748 } 3792 }
3749 else 3793 else
3750 { 3794 {
@@ -3981,41 +4025,41 @@ namespace OpenSim.Region.Framework.Scenes
3981 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc); 4025 return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
3982 } 4026 }
3983 4027
3984 /// <summary> 4028// /// <summary>
3985 /// The Grid has requested that we log-off a user. Log them off. 4029// /// The Grid has requested that we log-off a user. Log them off.
3986 /// </summary> 4030// /// </summary>
3987 /// <param name="AvatarID">Unique ID of the avatar to log-off</param> 4031// /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
3988 /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param> 4032// /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
3989 /// <param name="message">message to display to the user. Reason for being logged off</param> 4033// /// <param name="message">message to display to the user. Reason for being logged off</param>
3990 public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message) 4034// public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
3991 { 4035// {
3992 ScenePresence loggingOffUser = GetScenePresence(AvatarID); 4036// ScenePresence loggingOffUser = GetScenePresence(AvatarID);
3993 if (loggingOffUser != null) 4037// if (loggingOffUser != null)
3994 { 4038// {
3995 UUID localRegionSecret = UUID.Zero; 4039// UUID localRegionSecret = UUID.Zero;
3996 bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret); 4040// bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret);
3997 4041//
3998 // Region Secret is used here in case a new sessionid overwrites an old one on the user server. 4042// // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
3999 // Will update the user server in a few revisions to use it. 4043// // Will update the user server in a few revisions to use it.
4000 4044//
4001 if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret)) 4045// if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
4002 { 4046// {
4003 m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles); 4047// m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles);
4004 loggingOffUser.ControllingClient.Kick(message); 4048// loggingOffUser.ControllingClient.Kick(message);
4005 // Give them a second to receive the message! 4049// // Give them a second to receive the message!
4006 Thread.Sleep(1000); 4050// Thread.Sleep(1000);
4007 loggingOffUser.ControllingClient.Close(); 4051// loggingOffUser.ControllingClient.Close();
4008 } 4052// }
4009 else 4053// else
4010 { 4054// {
4011 m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate"); 4055// m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
4012 } 4056// }
4013 } 4057// }
4014 else 4058// else
4015 { 4059// {
4016 m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString()); 4060// m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString());
4017 } 4061// }
4018 } 4062// }
4019 4063
4020 /// <summary> 4064 /// <summary>
4021 /// Triggered when an agent crosses into this sim. Also happens on initial login. 4065 /// Triggered when an agent crosses into this sim. Also happens on initial login.
@@ -4068,21 +4112,19 @@ namespace OpenSim.Region.Framework.Scenes
4068 return false; 4112 return false;
4069 } 4113 }
4070 4114
4115 // TODO: This check should probably be in QueryAccess().
4071 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4116 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
4072 if (nearestParcel == null) 4117 if (nearestParcel == null)
4073 { 4118 {
4074 m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: no allowed parcel", cAgentData.AgentID); 4119 m_log.DebugFormat(
4075 return false; 4120 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4076 } 4121 cAgentData.AgentID, RegionInfo.RegionName);
4077
4078 int num = m_sceneGraph.GetNumberOfScenePresences();
4079 4122
4080 if (num >= RegionInfo.RegionSettings.AgentLimit) 4123 return false;
4081 {
4082 if (!Permissions.IsAdministrator(cAgentData.AgentID))
4083 return false;
4084 } 4124 }
4085 4125
4126 // We have to wait until the viewer contacts this region after receiving EAC.
4127 // That calls AddNewClient, which finally creates the ScenePresence
4086 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4128 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
4087 4129
4088 if (childAgentUpdate != null) 4130 if (childAgentUpdate != null)
@@ -4126,14 +4168,28 @@ namespace OpenSim.Region.Framework.Scenes
4126 return false; 4168 return false;
4127 } 4169 }
4128 4170
4171 /// <summary>
4172 /// Poll until the requested ScenePresence appears or we timeout.
4173 /// </summary>
4174 /// <returns>The scene presence is found, else null.</returns>
4175 /// <param name='agentID'></param>
4129 protected virtual ScenePresence WaitGetScenePresence(UUID agentID) 4176 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4130 { 4177 {
4131 int ntimes = 10; 4178 int ntimes = 10;
4132 ScenePresence childAgentUpdate = null; 4179 ScenePresence sp = null;
4133 while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4180 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4134 Thread.Sleep(1000); 4181 Thread.Sleep(1000);
4135 return childAgentUpdate;
4136 4182
4183 if (sp == null)
4184 m_log.WarnFormat(
4185 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4186 agentID, RegionInfo.RegionName);
4187// else
4188// m_log.DebugFormat(
4189// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4190// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4191
4192 return sp;
4137 } 4193 }
4138 4194
4139 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) 4195 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
@@ -4283,8 +4339,10 @@ namespace OpenSim.Region.Framework.Scenes
4283 position.Y -= shifty; 4339 position.Y -= shifty;
4284 } 4340 }
4285 4341
4286 if (m_teleportModule != null) 4342 if (EntityTransferModule != null)
4287 m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); 4343 {
4344 EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
4345 }
4288 else 4346 else
4289 { 4347 {
4290 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); 4348 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
@@ -4295,8 +4353,10 @@ namespace OpenSim.Region.Framework.Scenes
4295 4353
4296 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 4354 public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4297 { 4355 {
4298 if (m_teleportModule != null) 4356 if (EntityTransferModule != null)
4299 return m_teleportModule.Cross(agent, isFlying); 4357 {
4358 return EntityTransferModule.Cross(agent, isFlying);
4359 }
4300 else 4360 else
4301 { 4361 {
4302 m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); 4362 m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule");
@@ -5444,29 +5504,58 @@ Environment.Exit(1);
5444 throw new Exception(error); 5504 throw new Exception(error);
5445 } 5505 }
5446 5506
5447 // This method is called across the simulation connector to 5507 /// <summary>
5448 // determine if a given agent is allowed in this region 5508 /// This method is called across the simulation connector to
5449 // AS A ROOT AGENT. Returning false here will prevent them 5509 /// determine if a given agent is allowed in this region
5450 // from logging into the region, teleporting into the region 5510 /// AS A ROOT AGENT
5451 // or corssing the broder walking, but will NOT prevent 5511 /// </summary>
5452 // child agent creation, thereby emulating the SL behavior. 5512 /// <remarks>
5513 /// Returning false here will prevent them
5514 /// from logging into the region, teleporting into the region
5515 /// or corssing the broder walking, but will NOT prevent
5516 /// child agent creation, thereby emulating the SL behavior.
5517 /// </remarks>
5518 /// <param name='agentID'></param>
5519 /// <param name='position'></param>
5520 /// <param name='reason'></param>
5521 /// <returns></returns>
5453 public bool QueryAccess(UUID agentID, Vector3 position, out string reason) 5522 public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
5454 { 5523 {
5455 reason = "You are banned from the region"; 5524 reason = "You are banned from the region";
5456 5525
5526 if (EntityTransferModule.IsInTransit(agentID))
5527 {
5528 reason = "Agent is still in transit from this region";
5529
5530 m_log.WarnFormat(
5531 "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
5532 agentID, RegionInfo.RegionName);
5533
5534 return false;
5535 }
5536
5457 if (Permissions.IsGod(agentID)) 5537 if (Permissions.IsGod(agentID))
5458 { 5538 {
5459 reason = String.Empty; 5539 reason = String.Empty;
5460 return true; 5540 return true;
5461 } 5541 }
5462 5542
5463 int num = m_sceneGraph.GetNumberOfScenePresences(); 5543 // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
5544 // However, the long term fix is to make sure root agent count is always accurate.
5545 m_sceneGraph.RecalculateStats();
5546
5547 int num = m_sceneGraph.GetRootAgentCount();
5464 5548
5465 if (num >= RegionInfo.RegionSettings.AgentLimit) 5549 if (num >= RegionInfo.RegionSettings.AgentLimit)
5466 { 5550 {
5467 if (!Permissions.IsAdministrator(agentID)) 5551 if (!Permissions.IsAdministrator(agentID))
5468 { 5552 {
5469 reason = "The region is full"; 5553 reason = "The region is full";
5554
5555 m_log.DebugFormat(
5556 "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
5557 agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
5558
5470 return false; 5559 return false;
5471 } 5560 }
5472 } 5561 }
@@ -5637,5 +5726,19 @@ Environment.Exit(1);
5637 } 5726 }
5638 } 5727 }
5639 } 5728 }
5729
5730 // manage and select spawn points in sequence
5731 public int SpawnPoint()
5732 {
5733 int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count;
5734
5735 if (spawnpoints == 0)
5736 return 0;
5737
5738 m_SpawnPoint++;
5739 if (m_SpawnPoint > spawnpoints)
5740 m_SpawnPoint = 1;
5741 return m_SpawnPoint - 1;
5742 }
5640 } 5743 }
5641} 5744}
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index b806d91..77e808e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -156,7 +156,9 @@ namespace OpenSim.Region.Framework.Scenes
156 // that the region position is cached or performance will degrade 156 // that the region position is cached or performance will degrade
157 Utils.LongToUInts(regionHandle, out x, out y); 157 Utils.LongToUInts(regionHandle, out x, out y);
158 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); 158 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
159// bool v = true; 159 if (dest == null)
160 continue;
161
160 if (!simulatorList.Contains(dest.ServerURI)) 162 if (!simulatorList.Contains(dest.ServerURI))
161 { 163 {
162 // we havent seen this simulator before, add it to the list 164 // we havent seen this simulator before, add it to the list
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 0d178c3..23a0550 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -101,6 +101,13 @@ namespace OpenSim.Region.Framework.Scenes
101 /// </summary> 101 /// </summary>
102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>(); 102 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalPartID = new Dictionary<uint, SceneObjectGroup>();
103 103
104 /// <summary>
105 /// Lock to prevent object group update, linking, delinking and duplication operations from running concurrently.
106 /// </summary>
107 /// <remarks>
108 /// These operations rely on the parts composition of the object. If allowed to run concurrently then race
109 /// conditions can occur.
110 /// </remarks>
104 private Object m_updateLock = new Object(); 111 private Object m_updateLock = new Object();
105 112
106 #endregion 113 #endregion
@@ -853,11 +860,6 @@ namespace OpenSim.Region.Framework.Scenes
853 return m_scenePresenceArray; 860 return m_scenePresenceArray;
854 } 861 }
855 862
856 public int GetNumberOfScenePresences()
857 {
858 return m_scenePresenceArray.Count;
859 }
860
861 /// <summary> 863 /// <summary>
862 /// Request a scene presence by UUID. Fast, indexed lookup. 864 /// Request a scene presence by UUID. Fast, indexed lookup.
863 /// </summary> 865 /// </summary>
@@ -2064,12 +2066,14 @@ namespace OpenSim.Region.Framework.Scenes
2064 /// <param name="AgentID"></param> 2066 /// <param name="AgentID"></param>
2065 /// <param name="GroupID"></param> 2067 /// <param name="GroupID"></param>
2066 /// <param name="rot"></param> 2068 /// <param name="rot"></param>
2069 /// <returns>null if duplication fails, otherwise the duplicated object</returns>
2070 /// <summary>
2067 public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot) 2071 public SceneObjectGroup DuplicateObject(uint originalPrimID, Vector3 offset, uint flags, UUID AgentID, UUID GroupID, Quaternion rot)
2068 { 2072 {
2069// m_log.DebugFormat( 2073// m_log.DebugFormat(
2070// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}", 2074// "[SCENE]: Duplication of object {0} at offset {1} requested by agent {2}",
2071// originalPrimID, offset, AgentID); 2075// originalPrimID, offset, AgentID);
2072 2076
2073 SceneObjectGroup original = GetGroupByPrim(originalPrimID); 2077 SceneObjectGroup original = GetGroupByPrim(originalPrimID);
2074 if (original != null) 2078 if (original != null)
2075 { 2079 {
@@ -2099,25 +2103,25 @@ namespace OpenSim.Region.Framework.Scenes
2099 2103
2100 // FIXME: This section needs to be refactored so that it just calls AddSceneObject() 2104 // FIXME: This section needs to be refactored so that it just calls AddSceneObject()
2101 Entities.Add(copy); 2105 Entities.Add(copy);
2102 2106
2103 lock (SceneObjectGroupsByFullID) 2107 lock (SceneObjectGroupsByFullID)
2104 SceneObjectGroupsByFullID[copy.UUID] = copy; 2108 SceneObjectGroupsByFullID[copy.UUID] = copy;
2105 2109
2106 SceneObjectPart[] children = copy.Parts; 2110 SceneObjectPart[] children = copy.Parts;
2107 2111
2108 lock (SceneObjectGroupsByFullPartID) 2112 lock (SceneObjectGroupsByFullPartID)
2109 { 2113 {
2110 SceneObjectGroupsByFullPartID[copy.UUID] = copy; 2114 SceneObjectGroupsByFullPartID[copy.UUID] = copy;
2111 foreach (SceneObjectPart part in children) 2115 foreach (SceneObjectPart part in children)
2112 SceneObjectGroupsByFullPartID[part.UUID] = copy; 2116 SceneObjectGroupsByFullPartID[part.UUID] = copy;
2113 } 2117 }
2114 2118
2115 lock (SceneObjectGroupsByLocalPartID) 2119 lock (SceneObjectGroupsByLocalPartID)
2116 { 2120 {
2117 SceneObjectGroupsByLocalPartID[copy.LocalId] = copy; 2121 SceneObjectGroupsByLocalPartID[copy.LocalId] = copy;
2118 foreach (SceneObjectPart part in children) 2122 foreach (SceneObjectPart part in children)
2119 SceneObjectGroupsByLocalPartID[part.LocalId] = copy; 2123 SceneObjectGroupsByLocalPartID[part.LocalId] = copy;
2120 } 2124 }
2121 // PROBABLE END OF FIXME 2125 // PROBABLE END OF FIXME
2122 2126
2123 // Since we copy from a source group that is in selected 2127 // Since we copy from a source group that is in selected
@@ -2149,11 +2153,10 @@ namespace OpenSim.Region.Framework.Scenes
2149 { 2153 {
2150 m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID); 2154 m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
2151 } 2155 }
2152 2156
2153 return null; 2157 return null;
2154 } 2158 }
2155 2159
2156 /// <summary>
2157 /// Calculates the distance between two Vector3s 2160 /// Calculates the distance between two Vector3s
2158 /// </summary> 2161 /// </summary>
2159 /// <param name="v1"></param> 2162 /// <param name="v1"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 7568888..46a7e3d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2670,6 +2670,10 @@ namespace OpenSim.Region.Framework.Scenes
2670 /// <summary> 2670 /// <summary>
2671 /// Link the prims in a given group to this group 2671 /// Link the prims in a given group to this group
2672 /// </summary> 2672 /// </summary>
2673 /// <remarks>
2674 /// Do not call this method directly - use Scene.LinkObjects() instead to avoid races between threads.
2675 /// FIXME: There are places where scripts call these methods directly without locking. This is a potential race condition.
2676 /// </remarks>
2673 /// <param name="objectGroup">The group of prims which should be linked to this group</param> 2677 /// <param name="objectGroup">The group of prims which should be linked to this group</param>
2674 public void LinkToGroup(SceneObjectGroup objectGroup) 2678 public void LinkToGroup(SceneObjectGroup objectGroup)
2675 { 2679 {
@@ -2751,6 +2755,7 @@ namespace OpenSim.Region.Framework.Scenes
2751 } 2755 }
2752 2756
2753 linkPart.LinkNum = linkNum++; 2757 linkPart.LinkNum = linkNum++;
2758 linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2754 2759
2755 SceneObjectPart[] ogParts = objectGroup.Parts; 2760 SceneObjectPart[] ogParts = objectGroup.Parts;
2756 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) 2761 Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
@@ -2802,6 +2807,11 @@ namespace OpenSim.Region.Framework.Scenes
2802 /// Delink the given prim from this group. The delinked prim is established as 2807 /// Delink the given prim from this group. The delinked prim is established as
2803 /// an independent SceneObjectGroup. 2808 /// an independent SceneObjectGroup.
2804 /// </summary> 2809 /// </summary>
2810 /// <remarks>
2811 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2812 /// condition. But currently there is no
2813 /// alternative method that does take a lonk to delink a single prim.
2814 /// </remarks>
2805 /// <param name="partID"></param> 2815 /// <param name="partID"></param>
2806 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2816 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
2807 public SceneObjectGroup DelinkFromGroup(uint partID) 2817 public SceneObjectGroup DelinkFromGroup(uint partID)
@@ -2813,6 +2823,11 @@ namespace OpenSim.Region.Framework.Scenes
2813 /// Delink the given prim from this group. The delinked prim is established as 2823 /// Delink the given prim from this group. The delinked prim is established as
2814 /// an independent SceneObjectGroup. 2824 /// an independent SceneObjectGroup.
2815 /// </summary> 2825 /// </summary>
2826 /// <remarks>
2827 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2828 /// condition. But currently there is no
2829 /// alternative method that does take a lonk to delink a single prim.
2830 /// </remarks>
2816 /// <param name="partID"></param> 2831 /// <param name="partID"></param>
2817 /// <param name="sendEvents"></param> 2832 /// <param name="sendEvents"></param>
2818 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> 2833 /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
@@ -2838,6 +2853,11 @@ namespace OpenSim.Region.Framework.Scenes
2838 /// Delink the given prim from this group. The delinked prim is established as 2853 /// Delink the given prim from this group. The delinked prim is established as
2839 /// an independent SceneObjectGroup. 2854 /// an independent SceneObjectGroup.
2840 /// </summary> 2855 /// </summary>
2856 /// <remarks>
2857 /// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
2858 /// condition. But currently there is no
2859 /// alternative method that does take a lonk to delink a single prim.
2860 /// </remarks>
2841 /// <param name="partID"></param> 2861 /// <param name="partID"></param>
2842 /// <param name="sendEvents"></param> 2862 /// <param name="sendEvents"></param>
2843 /// <returns>The object group of the newly delinked prim.</returns> 2863 /// <returns>The object group of the newly delinked prim.</returns>
@@ -2971,6 +2991,8 @@ namespace OpenSim.Region.Framework.Scenes
2971 oldRot = part.RotationOffset; 2991 oldRot = part.RotationOffset;
2972 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot; 2992 Quaternion newRot = Quaternion.Conjugate(parentRot) * worldRot;
2973 part.RotationOffset = newRot; 2993 part.RotationOffset = newRot;
2994
2995 part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
2974 } 2996 }
2975 2997
2976 /// <summary> 2998 /// <summary>
@@ -3482,7 +3504,7 @@ namespace OpenSim.Region.Framework.Scenes
3482 3504
3483 //we need to do a terse update even if the move wasn't allowed 3505 //we need to do a terse update even if the move wasn't allowed
3484 // so that the position is reset in the client (the object snaps back) 3506 // so that the position is reset in the client (the object snaps back)
3485 ScheduleGroupForTerseUpdate(); 3507 RootPart.ScheduleTerseUpdate();
3486 } 3508 }
3487 3509
3488 /// <summary> 3510 /// <summary>
@@ -4182,7 +4204,72 @@ namespace OpenSim.Region.Framework.Scenes
4182 for (int i = 0; i < parts.Length; i++) 4204 for (int i = 0; i < parts.Length; i++)
4183 parts[i].TriggerScriptChangedEvent(val); 4205 parts[i].TriggerScriptChangedEvent(val);
4184 } 4206 }
4185 4207
4208 /// <summary>
4209 /// Returns a count of the number of scripts in this groups parts.
4210 /// </summary>
4211 public int ScriptCount()
4212 {
4213 int count = 0;
4214 SceneObjectPart[] parts = m_parts.GetArray();
4215 for (int i = 0; i < parts.Length; i++)
4216 count += parts[i].Inventory.ScriptCount();
4217
4218 return count;
4219 }
4220
4221 /// <summary>
4222 /// A float the value is a representative execution time in milliseconds of all scripts in the link set.
4223 /// </summary>
4224 public float ScriptExecutionTime()
4225 {
4226 IScriptModule[] engines = Scene.RequestModuleInterfaces<IScriptModule>();
4227
4228 if (engines.Length == 0) // No engine at all
4229 return 0.0f;
4230
4231 float time = 0.0f;
4232
4233 // get all the scripts in all parts
4234 SceneObjectPart[] parts = m_parts.GetArray();
4235 List<TaskInventoryItem> scripts = new List<TaskInventoryItem>();
4236 for (int i = 0; i < parts.Length; i++)
4237 {
4238 scripts.AddRange(parts[i].Inventory.GetInventoryItems(InventoryType.LSL));
4239 }
4240 // extract the UUIDs
4241 List<UUID> ids = new List<UUID>(scripts.Count);
4242 foreach (TaskInventoryItem script in scripts)
4243 {
4244 if (!ids.Contains(script.ItemID))
4245 {
4246 ids.Add(script.ItemID);
4247 }
4248 }
4249 // Offer the list of script UUIDs to each engine found and accumulate the time
4250 foreach (IScriptModule e in engines)
4251 {
4252 if (e != null)
4253 {
4254 time += e.GetScriptExecutionTime(ids);
4255 }
4256 }
4257 return time;
4258 }
4259
4260 /// <summary>
4261 /// Returns a count of the number of running scripts in this groups parts.
4262 /// </summary>
4263 public int RunningScriptCount()
4264 {
4265 int count = 0;
4266 SceneObjectPart[] parts = m_parts.GetArray();
4267 for (int i = 0; i < parts.Length; i++)
4268 count += parts[i].Inventory.RunningScriptCount();
4269
4270 return count;
4271 }
4272
4186 public override string ToString() 4273 public override string ToString()
4187 { 4274 {
4188 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); 4275 return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 2852c4b..749b281 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1016,7 +1016,18 @@ namespace OpenSim.Region.Framework.Scenes
1016 public int LinkNum 1016 public int LinkNum
1017 { 1017 {
1018 get { return m_linkNum; } 1018 get { return m_linkNum; }
1019 set { m_linkNum = value; } 1019 set
1020 {
1021// if (ParentGroup != null)
1022// {
1023// m_log.DebugFormat(
1024// "[SCENE OBJECT PART]: Setting linknum of {0}@{1} to {2} from {3}",
1025// Name, AbsolutePosition, value, m_linkNum);
1026// Util.PrintCallStack();
1027// }
1028
1029 m_linkNum = value;
1030 }
1020 } 1031 }
1021 1032
1022 public byte ClickAction 1033 public byte ClickAction
@@ -2153,6 +2164,9 @@ namespace OpenSim.Region.Framework.Scenes
2153 /// <param name="isNew"></param> 2164 /// <param name="isNew"></param>
2154 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew) 2165 public void DoPhysicsPropertyUpdate(bool UsePhysics, bool isNew)
2155 { 2166 {
2167 if (ParentGroup.Scene == null)
2168 return;
2169
2156 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics) 2170 if (!ParentGroup.Scene.PhysicalPrims && UsePhysics)
2157 return; 2171 return;
2158 2172
@@ -3621,7 +3635,6 @@ namespace OpenSim.Region.Framework.Scenes
3621 hasProfileCut = hasDimple; // is it the same thing? 3635 hasProfileCut = hasDimple; // is it the same thing?
3622 } 3636 }
3623 3637
3624
3625 public void SetGroup(UUID groupID, IClientAPI client) 3638 public void SetGroup(UUID groupID, IClientAPI client)
3626 { 3639 {
3627 // Scene.AddNewPrims() calls with client == null so can't use this. 3640 // Scene.AddNewPrims() calls with client == null so can't use this.
@@ -3651,10 +3664,12 @@ namespace OpenSim.Region.Framework.Scenes
3651 3664
3652 public void SetPhysicsAxisRotation() 3665 public void SetPhysicsAxisRotation()
3653 { 3666 {
3654 if (PhysActor != null) 3667 PhysicsActor pa = PhysActor;
3668
3669 if (pa != null)
3655 { 3670 {
3656 PhysActor.LockAngularMotion(RotationAxis); 3671 pa.LockAngularMotion(RotationAxis);
3657 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor); 3672 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
3658 } 3673 }
3659 } 3674 }
3660 3675
@@ -4371,7 +4386,7 @@ namespace OpenSim.Region.Framework.Scenes
4371 // For now, we use the NINJA naming scheme for identifying joints. 4386 // For now, we use the NINJA naming scheme for identifying joints.
4372 // In the future, we can support other joint specification schemes such as a 4387 // In the future, we can support other joint specification schemes such as a
4373 // custom checkbox in the viewer GUI. 4388 // custom checkbox in the viewer GUI.
4374 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4389 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4375 { 4390 {
4376 string hingeString = "hingejoint"; 4391 string hingeString = "hingejoint";
4377 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString); 4392 return (Name.Length >= hingeString.Length && Name.Substring(0, hingeString.Length) == hingeString);
@@ -4387,7 +4402,7 @@ namespace OpenSim.Region.Framework.Scenes
4387 // For now, we use the NINJA naming scheme for identifying joints. 4402 // For now, we use the NINJA naming scheme for identifying joints.
4388 // In the future, we can support other joint specification schemes such as a 4403 // In the future, we can support other joint specification schemes such as a
4389 // custom checkbox in the viewer GUI. 4404 // custom checkbox in the viewer GUI.
4390 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4405 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4391 { 4406 {
4392 string ballString = "balljoint"; 4407 string ballString = "balljoint";
4393 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString); 4408 return (Name.Length >= ballString.Length && Name.Substring(0, ballString.Length) == ballString);
@@ -4403,7 +4418,7 @@ namespace OpenSim.Region.Framework.Scenes
4403 // For now, we use the NINJA naming scheme for identifying joints. 4418 // For now, we use the NINJA naming scheme for identifying joints.
4404 // In the future, we can support other joint specification schemes such as a 4419 // In the future, we can support other joint specification schemes such as a
4405 // custom checkbox in the viewer GUI. 4420 // custom checkbox in the viewer GUI.
4406 if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints) 4421 if (ParentGroup.Scene != null && ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
4407 { 4422 {
4408 return IsHingeJoint() || IsBallJoint(); 4423 return IsHingeJoint() || IsBallJoint();
4409 } 4424 }
@@ -4524,7 +4539,6 @@ namespace OpenSim.Region.Framework.Scenes
4524 } 4539 }
4525 */ 4540 */
4526 } 4541 }
4527
4528 else // it already has a physical representation 4542 else // it already has a physical representation
4529 { 4543 {
4530 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. 4544 DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 959046a..f5b9825 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -267,14 +267,9 @@ namespace OpenSim.Region.Framework.Scenes
267 /// </summary> 267 /// </summary>
268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 268 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
269 { 269 {
270 Items.LockItemsForRead(true); 270 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
271 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 271 foreach (TaskInventoryItem item in scripts)
272 Items.LockItemsForRead(false); 272 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
273 foreach (TaskInventoryItem item in items)
274 {
275 if ((int)InventoryType.LSL == item.InvType)
276 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
277 }
278 } 273 }
279 274
280 public ArrayList GetScriptErrors(UUID itemID) 275 public ArrayList GetScriptErrors(UUID itemID)
@@ -305,17 +300,11 @@ namespace OpenSim.Region.Framework.Scenes
305 /// </param> 300 /// </param>
306 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 301 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
307 { 302 {
308 Items.LockItemsForRead(true); 303 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
309 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 304 foreach (TaskInventoryItem item in scripts)
310 Items.LockItemsForRead(false);
311
312 foreach (TaskInventoryItem item in items)
313 { 305 {
314 if ((int)InventoryType.LSL == item.InvType) 306 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
315 { 307 m_part.RemoveScriptEvents(item.ItemID);
316 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
317 m_part.RemoveScriptEvents(item.ItemID);
318 }
319 } 308 }
320 } 309 }
321 310
@@ -770,14 +759,22 @@ namespace OpenSim.Region.Framework.Scenes
770 return item; 759 return item;
771 } 760 }
772 761
773 /// <summary> 762 public TaskInventoryItem GetInventoryItem(string name)
774 /// Get inventory items by name. 763 {
775 /// </summary> 764 m_items.LockItemsForRead(true);
776 /// <param name="name"></param> 765 foreach (TaskInventoryItem item in m_items.Values)
777 /// <returns> 766 {
778 /// A list of inventory items with that name. 767 if (item.Name == name)
779 /// If no inventory item has that name then an empty list is returned. 768 {
780 /// </returns> 769 return item;
770 m_items.LockItemsForRead(false);
771 }
772 }
773 m_items.LockItemsForRead(false);
774
775 return null;
776 }
777
781 public List<TaskInventoryItem> GetInventoryItems(string name) 778 public List<TaskInventoryItem> GetInventoryItems(string name)
782 { 779 {
783 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 780 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
@@ -1247,10 +1244,10 @@ namespace OpenSim.Region.Framework.Scenes
1247 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 1244 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1248 item.CurrentPermissions &= ~(uint)PermissionMask.Modify; 1245 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1249 } 1246 }
1250 item.OwnerChanged = true;
1251 item.CurrentPermissions &= item.NextPermissions; 1247 item.CurrentPermissions &= item.NextPermissions;
1252 item.BasePermissions &= item.NextPermissions; 1248 item.BasePermissions &= item.NextPermissions;
1253 item.EveryonePermissions &= item.NextPermissions; 1249 item.EveryonePermissions &= item.NextPermissions;
1250 item.OwnerChanged = true;
1254 item.PermsMask = 0; 1251 item.PermsMask = 0;
1255 item.PermsGranter = UUID.Zero; 1252 item.PermsGranter = UUID.Zero;
1256 } 1253 }
@@ -1281,9 +1278,57 @@ namespace OpenSim.Region.Framework.Scenes
1281 return true; 1278 return true;
1282 } 1279 }
1283 } 1280 }
1281
1284 return false; 1282 return false;
1285 } 1283 }
1286 1284
1285 /// <summary>
1286 /// Returns the count of scripts in this parts inventory.
1287 /// </summary>
1288 /// <returns></returns>
1289 public int ScriptCount()
1290 {
1291 int count = 0;
1292 Items.LockItemsForRead(true);
1293 foreach (TaskInventoryItem item in m_items.Values)
1294 {
1295 if (item.InvType == (int)InventoryType.LSL)
1296 {
1297 count++;
1298 }
1299 }
1300 Items.LockItemsForRead(false);
1301 return count;
1302 }
1303 /// <summary>
1304 /// Returns the count of running scripts in this parts inventory.
1305 /// </summary>
1306 /// <returns></returns>
1307 public int RunningScriptCount()
1308 {
1309 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1310 if (engines.Length == 0)
1311 return 0;
1312
1313 int count = 0;
1314 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1315
1316 foreach (TaskInventoryItem item in scripts)
1317 {
1318 foreach (IScriptModule engine in engines)
1319 {
1320 if (engine != null)
1321 {
1322 if (engine.GetScriptState(item.ItemID))
1323 {
1324 count++;
1325 }
1326 }
1327 }
1328 }
1329 return count;
1330 }
1331
1287 public List<UUID> GetInventoryList() 1332 public List<UUID> GetInventoryList()
1288 { 1333 {
1289 List<UUID> ret = new List<UUID>(); 1334 List<UUID> ret = new List<UUID>();
@@ -1298,22 +1343,24 @@ namespace OpenSim.Region.Framework.Scenes
1298 { 1343 {
1299 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1344 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1300 1345
1301 lock (m_items) 1346 Items.LockItemsForRead(true);
1302 ret = new List<TaskInventoryItem>(m_items.Values); 1347 ret = new List<TaskInventoryItem>(m_items.Values);
1348 Items.LockItemsForRead(false);
1303 1349
1304 return ret; 1350 return ret;
1305 } 1351 }
1306 1352
1307 public List<TaskInventoryItem> GetInventoryScripts() 1353 public List<TaskInventoryItem> GetInventoryItems(InventoryType type)
1308 { 1354 {
1309 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1355 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1310 1356
1311 lock (m_items) 1357 Items.LockItemsForRead(true);
1312 { 1358
1313 foreach (TaskInventoryItem item in m_items.Values) 1359 foreach (TaskInventoryItem item in m_items.Values)
1314 if (item.InvType == (int)InventoryType.LSL) 1360 if (item.InvType == (int)type)
1315 ret.Add(item); 1361 ret.Add(item);
1316 } 1362
1363 Items.LockItemsForRead(false);
1317 1364
1318 return ret; 1365 return ret;
1319 } 1366 }
@@ -1335,35 +1382,32 @@ namespace OpenSim.Region.Framework.Scenes
1335 if (engines.Length == 0) // No engine at all 1382 if (engines.Length == 0) // No engine at all
1336 return ret; 1383 return ret;
1337 1384
1338 Items.LockItemsForRead(true); 1385 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1339 foreach (TaskInventoryItem item in m_items.Values) 1386
1387 foreach (TaskInventoryItem item in scripts)
1340 { 1388 {
1341 if (item.InvType == (int)InventoryType.LSL) 1389 foreach (IScriptModule e in engines)
1342 { 1390 {
1343 foreach (IScriptModule e in engines) 1391 if (e != null)
1344 { 1392 {
1345 if (e != null) 1393 string n = e.GetXMLState(item.ItemID);
1394 if (n != String.Empty)
1346 { 1395 {
1347 string n = e.GetXMLState(item.ItemID); 1396 if (oldIDs)
1348 if (n != String.Empty) 1397 {
1398 if (!ret.ContainsKey(item.OldItemID))
1399 ret[item.OldItemID] = n;
1400 }
1401 else
1349 { 1402 {
1350 if (oldIDs) 1403 if (!ret.ContainsKey(item.ItemID))
1351 { 1404 ret[item.ItemID] = n;
1352 if (!ret.ContainsKey(item.OldItemID))
1353 ret[item.OldItemID] = n;
1354 }
1355 else
1356 {
1357 if (!ret.ContainsKey(item.ItemID))
1358 ret[item.ItemID] = n;
1359 }
1360 break;
1361 } 1405 }
1406 break;
1362 } 1407 }
1363 } 1408 }
1364 } 1409 }
1365 } 1410 }
1366 Items.LockItemsForRead(false);
1367 return ret; 1411 return ret;
1368 } 1412 }
1369 1413
@@ -1373,27 +1417,27 @@ namespace OpenSim.Region.Framework.Scenes
1373 if (engines.Length == 0) 1417 if (engines.Length == 0)
1374 return; 1418 return;
1375 1419
1420 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
1376 1421
1377 Items.LockItemsForRead(true); 1422 foreach (TaskInventoryItem item in scripts)
1378
1379 foreach (TaskInventoryItem item in m_items.Values)
1380 { 1423 {
1381 if (item.InvType == (int)InventoryType.LSL) 1424 foreach (IScriptModule engine in engines)
1382 { 1425 {
1383 foreach (IScriptModule engine in engines) 1426 if (engine != null)
1384 { 1427 {
1385 if (engine != null) 1428// m_log.DebugFormat(
1386 { 1429// "[PRIM INVENTORY]: Resuming script {0} {1} for {2}, OwnerChanged {3}",
1387 if (item.OwnerChanged) 1430// item.Name, item.ItemID, item.OwnerID, item.OwnerChanged);
1388 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1431
1389 item.OwnerChanged = false; 1432 engine.ResumeScript(item.ItemID);
1390 engine.ResumeScript(item.ItemID); 1433
1391 } 1434 if (item.OwnerChanged)
1435 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1436
1437 item.OwnerChanged = false;
1392 } 1438 }
1393 } 1439 }
1394 } 1440 }
1395
1396 Items.LockItemsForRead(false);
1397 } 1441 }
1398 } 1442 }
1399} 1443}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5a3b518..225d4c9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -45,6 +45,7 @@ using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
45 45
46namespace OpenSim.Region.Framework.Scenes 46namespace OpenSim.Region.Framework.Scenes
47{ 47{
48 [Flags]
48 enum ScriptControlled : uint 49 enum ScriptControlled : uint
49 { 50 {
50 CONTROL_ZERO = 0, 51 CONTROL_ZERO = 0,
@@ -76,6 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
76// { 77// {
77// m_log.Debug("[SCENE PRESENCE] Destructor called"); 78// m_log.Debug("[SCENE PRESENCE] Destructor called");
78// } 79// }
80 private void TriggerScenePresenceUpdated()
81 {
82 if (m_scene != null)
83 m_scene.EventManager.TriggerScenePresenceUpdated(this);
84 }
79 85
80 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 86 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
81 87
@@ -497,6 +503,7 @@ namespace OpenSim.Region.Framework.Scenes
497 //m_log.DebugFormat( 503 //m_log.DebugFormat(
498 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 504 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
499 // Scene.RegionInfo.RegionName, Name, m_pos); 505 // Scene.RegionInfo.RegionName, Name, m_pos);
506 TriggerScenePresenceUpdated();
500 } 507 }
501 } 508 }
502 509
@@ -516,6 +523,7 @@ namespace OpenSim.Region.Framework.Scenes
516 return; 523 return;
517 524
518 m_pos = value; 525 m_pos = value;
526 TriggerScenePresenceUpdated();
519 } 527 }
520 } 528 }
521 529
@@ -1085,23 +1093,13 @@ namespace OpenSim.Region.Framework.Scenes
1085 /// <param name="pos"></param> 1093 /// <param name="pos"></param>
1086 public void Teleport(Vector3 pos) 1094 public void Teleport(Vector3 pos)
1087 { 1095 {
1088 bool isFlying = Flying; 1096 TeleportWithMomentum(pos, Vector3.Zero);
1089 RemoveFromPhysicalScene();
1090 Velocity = Vector3.Zero;
1091 CheckLandingPoint(ref pos);
1092 AbsolutePosition = pos;
1093 AddToPhysicalScene(isFlying);
1094
1095 SendTerseUpdateToAllClients();
1096 }
1097
1098 public void TeleportWithMomentum(Vector3 pos)
1099 {
1100 TeleportWithMomentum(pos, null);
1101 } 1097 }
1102 1098
1103 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1099 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
1104 { 1100 {
1101 if (ParentID != (uint)0)
1102 StandUp();
1105 bool isFlying = Flying; 1103 bool isFlying = Flying;
1106 Vector3 vel = Velocity; 1104 Vector3 vel = Velocity;
1107 RemoveFromPhysicalScene(); 1105 RemoveFromPhysicalScene();
@@ -1281,17 +1279,33 @@ namespace OpenSim.Region.Framework.Scenes
1281 1279
1282 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1280 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1283 MakeRootAgent(AbsolutePosition, flying); 1281 MakeRootAgent(AbsolutePosition, flying);
1282 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1283
1284// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1284 1285
1285 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1286 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
1286 { 1287 {
1287 m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); 1288 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1289 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1290 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1291 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1292 // region as the current region, meaning that a close sent before then will fail the teleport.
1293// System.Threading.Thread.Sleep(2000);
1294
1295 m_log.DebugFormat(
1296 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1297 client.Name, client.AgentId, m_callbackURI);
1298
1288 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1299 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
1289 m_callbackURI = null; 1300 m_callbackURI = null;
1290 } 1301 }
1302// else
1303// {
1304// m_log.DebugFormat(
1305// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1306// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1307// }
1291 1308
1292// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1293
1294 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1295 ValidateAndSendAppearanceAndAgentData(); 1309 ValidateAndSendAppearanceAndAgentData();
1296 1310
1297 // Create child agents in neighbouring regions 1311 // Create child agents in neighbouring regions
@@ -1306,7 +1320,6 @@ namespace OpenSim.Region.Framework.Scenes
1306 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1320 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1307 } 1321 }
1308 1322
1309
1310// m_log.DebugFormat( 1323// m_log.DebugFormat(
1311// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1324// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1312// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1325// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -1359,7 +1372,7 @@ namespace OpenSim.Region.Framework.Scenes
1359 { 1372 {
1360// m_log.DebugFormat( 1373// m_log.DebugFormat(
1361// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1374// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1362// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); 1375// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1363 1376
1364 if (IsChildAgent) 1377 if (IsChildAgent)
1365 { 1378 {
@@ -1469,14 +1482,8 @@ namespace OpenSim.Region.Framework.Scenes
1469 } 1482 }
1470 } 1483 }
1471 1484
1472 lock (scriptedcontrols) 1485 uint flagsForScripts = (uint)flags;
1473 { 1486 flags = RemoveIgnoredControls(flags, IgnoredControls);
1474 if (scriptedcontrols.Count > 0)
1475 {
1476 SendControlToScripts((uint)flags);
1477 flags = RemoveIgnoredControls(flags, IgnoredControls);
1478 }
1479 }
1480 1487
1481 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1488 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1482 HandleAgentSitOnGround(); 1489 HandleAgentSitOnGround();
@@ -1490,6 +1497,7 @@ namespace OpenSim.Region.Framework.Scenes
1490 PhysicsActor actor = PhysicsActor; 1497 PhysicsActor actor = PhysicsActor;
1491 if (actor == null) 1498 if (actor == null)
1492 { 1499 {
1500 SendControlsToScripts(flagsForScripts);
1493 return; 1501 return;
1494 } 1502 }
1495 1503
@@ -1569,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes
1569 MovementFlag |= (byte)nudgehack; 1577 MovementFlag |= (byte)nudgehack;
1570 } 1578 }
1571 1579
1572// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1580 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1573 MovementFlag += (byte)(uint)DCF; 1581 MovementFlag += (byte)(uint)DCF;
1574 update_movementflag = true; 1582 update_movementflag = true;
1575 } 1583 }
@@ -1582,7 +1590,7 @@ namespace OpenSim.Region.Framework.Scenes
1582 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1590 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1583 ) // This or is for Nudge forward 1591 ) // This or is for Nudge forward
1584 { 1592 {
1585// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1593 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1586 MovementFlag -= ((byte)(uint)DCF); 1594 MovementFlag -= ((byte)(uint)DCF);
1587 update_movementflag = true; 1595 update_movementflag = true;
1588 1596
@@ -1663,11 +1671,14 @@ namespace OpenSim.Region.Framework.Scenes
1663// } 1671// }
1664// } 1672// }
1665 1673
1666// if (update_movementflag && ParentID == 0) 1674 if (update_movementflag && ParentID == 0)
1667// Animator.UpdateMovementAnimations(); 1675 Animator.UpdateMovementAnimations();
1676
1677 SendControlsToScripts(flagsForScripts);
1668 } 1678 }
1669 1679
1670 m_scene.EventManager.TriggerOnClientMovement(this); 1680 m_scene.EventManager.TriggerOnClientMovement(this);
1681 TriggerScenePresenceUpdated();
1671 } 1682 }
1672 1683
1673 /// <summary> 1684 /// <summary>
@@ -2607,6 +2618,7 @@ namespace OpenSim.Region.Framework.Scenes
2607 2618
2608 m_scene.ForEachClient(SendTerseUpdateToClient); 2619 m_scene.ForEachClient(SendTerseUpdateToClient);
2609 } 2620 }
2621 TriggerScenePresenceUpdated();
2610 } 2622 }
2611 2623
2612 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2624 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2685,7 +2697,7 @@ namespace OpenSim.Region.Framework.Scenes
2685 // If we are using the the cached appearance then send it out to everyone 2697 // If we are using the the cached appearance then send it out to everyone
2686 if (cachedappearance) 2698 if (cachedappearance)
2687 { 2699 {
2688 m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2700 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
2689 2701
2690 // If the avatars baked textures are all in the cache, then we have a 2702 // If the avatars baked textures are all in the cache, then we have a
2691 // complete appearance... send it out, if not, then we'll send it when 2703 // complete appearance... send it out, if not, then we'll send it when
@@ -3089,8 +3101,8 @@ namespace OpenSim.Region.Framework.Scenes
3089 x = x / Constants.RegionSize; 3101 x = x / Constants.RegionSize;
3090 y = y / Constants.RegionSize; 3102 y = y / Constants.RegionSize;
3091 3103
3092 //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3104// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3093 //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3105// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3094 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) 3106 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
3095 { 3107 {
3096 byebyeRegions.Add(handle); 3108 byebyeRegions.Add(handle);
@@ -3147,7 +3159,7 @@ namespace OpenSim.Region.Framework.Scenes
3147 3159
3148 public void ChildAgentDataUpdate(AgentData cAgentData) 3160 public void ChildAgentDataUpdate(AgentData cAgentData)
3149 { 3161 {
3150 //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3162// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3151 if (!IsChildAgent) 3163 if (!IsChildAgent)
3152 return; 3164 return;
3153 3165
@@ -3291,6 +3303,9 @@ namespace OpenSim.Region.Framework.Scenes
3291 m_originRegionID = cAgent.RegionID; 3303 m_originRegionID = cAgent.RegionID;
3292 3304
3293 m_callbackURI = cAgent.CallbackURI; 3305 m_callbackURI = cAgent.CallbackURI;
3306// m_log.DebugFormat(
3307// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
3308// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
3294 3309
3295 m_pos = cAgent.Position; 3310 m_pos = cAgent.Position;
3296 m_velocity = cAgent.Velocity; 3311 m_velocity = cAgent.Velocity;
@@ -3392,6 +3407,7 @@ namespace OpenSim.Region.Framework.Scenes
3392 Velocity = force; 3407 Velocity = force;
3393 3408
3394 m_forceToApply = null; 3409 m_forceToApply = null;
3410 TriggerScenePresenceUpdated();
3395 } 3411 }
3396 } 3412 }
3397 3413
@@ -3497,25 +3513,53 @@ namespace OpenSim.Region.Framework.Scenes
3497 } 3513 }
3498 } 3514 }
3499 3515
3500 RaiseCollisionScriptEvents(coldata); 3516 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3501 3517 if (Invulnerable || GodLevel > 0)
3502 if (Invulnerable)
3503 return; 3518 return;
3504 3519
3520 // The following may be better in the ICombatModule
3521 // probably tweaking of the values for ground and normal prim collisions will be needed
3505 float starthealth = Health; 3522 float starthealth = Health;
3506 uint killerObj = 0; 3523 uint killerObj = 0;
3524 SceneObjectPart part = null;
3507 foreach (uint localid in coldata.Keys) 3525 foreach (uint localid in coldata.Keys)
3508 { 3526 {
3509 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3527 if (localid == 0)
3510 3528 {
3511 if (part != null && part.ParentGroup.Damage != -1.0f) 3529 part = null;
3512 Health -= part.ParentGroup.Damage; 3530 }
3531 else
3532 {
3533 part = Scene.GetSceneObjectPart(localid);
3534 }
3535 if (part != null)
3536 {
3537 // Ignore if it has been deleted or volume detect
3538 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3539 {
3540 if (part.ParentGroup.Damage > 0.0f)
3541 {
3542 // Something with damage...
3543 Health -= part.ParentGroup.Damage;
3544 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3545 }
3546 else
3547 {
3548 // An ordinary prim
3549 if (coldata[localid].PenetrationDepth >= 0.10f)
3550 Health -= coldata[localid].PenetrationDepth * 5.0f;
3551 }
3552 }
3553 }
3513 else 3554 else
3514 { 3555 {
3515 if (coldata[localid].PenetrationDepth >= 0.10f) 3556 // 0 is the ground
3557 // what about collisions with other avatars?
3558 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3516 Health -= coldata[localid].PenetrationDepth * 5.0f; 3559 Health -= coldata[localid].PenetrationDepth * 5.0f;
3517 } 3560 }
3518 3561
3562
3519 if (Health <= 0.0f) 3563 if (Health <= 0.0f)
3520 { 3564 {
3521 if (localid != 0) 3565 if (localid != 0)
@@ -3531,7 +3575,16 @@ namespace OpenSim.Region.Framework.Scenes
3531 ControllingClient.SendHealth(Health); 3575 ControllingClient.SendHealth(Health);
3532 } 3576 }
3533 if (Health <= 0) 3577 if (Health <= 0)
3578 {
3534 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3579 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3580 }
3581 if (starthealth == Health && Health < 100.0f)
3582 {
3583 Health += 0.03f;
3584 if (Health > 100.0f)
3585 Health = 100.0f;
3586 ControllingClient.SendHealth(Health);
3587 }
3535 } 3588 }
3536 } 3589 }
3537 3590
@@ -3613,6 +3666,63 @@ namespace OpenSim.Region.Framework.Scenes
3613 return m_attachments.Count > 0; 3666 return m_attachments.Count > 0;
3614 } 3667 }
3615 3668
3669 /// <summary>
3670 /// Returns the total count of scripts in all parts inventories.
3671 /// </summary>
3672 public int ScriptCount()
3673 {
3674 int count = 0;
3675 lock (m_attachments)
3676 {
3677 foreach (SceneObjectGroup gobj in m_attachments)
3678 {
3679 if (gobj != null)
3680 {
3681 count += gobj.ScriptCount();
3682 }
3683 }
3684 }
3685 return count;
3686 }
3687
3688 /// <summary>
3689 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3690 /// </summary>
3691 public float ScriptExecutionTime()
3692 {
3693 float time = 0.0f;
3694 lock (m_attachments)
3695 {
3696 foreach (SceneObjectGroup gobj in m_attachments)
3697 {
3698 if (gobj != null)
3699 {
3700 time += gobj.ScriptExecutionTime();
3701 }
3702 }
3703 }
3704 return time;
3705 }
3706
3707 /// <summary>
3708 /// Returns the total count of running scripts in all parts.
3709 /// </summary>
3710 public int RunningScriptCount()
3711 {
3712 int count = 0;
3713 lock (m_attachments)
3714 {
3715 foreach (SceneObjectGroup gobj in m_attachments)
3716 {
3717 if (gobj != null)
3718 {
3719 count += gobj.RunningScriptCount();
3720 }
3721 }
3722 }
3723 return count;
3724 }
3725
3616 public bool HasScriptedAttachments() 3726 public bool HasScriptedAttachments()
3617 { 3727 {
3618 lock (m_attachments) 3728 lock (m_attachments)
@@ -3830,77 +3940,92 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 3940 }
3831 } 3941 }
3832 3942
3833 internal void SendControlToScripts(uint flags) 3943 private void SendControlsToScripts(uint flags)
3834 { 3944 {
3835 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3945 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3836 3946 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3837 if (MouseDown) 3947 lock (scriptedcontrols)
3838 { 3948 {
3839 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3949 if (scriptedcontrols.Count <= 0)
3840 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) 3950 return;
3951
3952 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3953
3954 if (MouseDown)
3841 { 3955 {
3842 allflags = ScriptControlled.CONTROL_ZERO; 3956 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3957 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3958 {
3959 allflags = ScriptControlled.CONTROL_ZERO;
3960 MouseDown = true;
3961 }
3962 }
3963
3964 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3965 {
3966 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3843 MouseDown = true; 3967 MouseDown = true;
3844 } 3968 }
3845 } 3969
3970 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3971 {
3972 allflags |= ScriptControlled.CONTROL_LBUTTON;
3973 MouseDown = true;
3974 }
3975
3976 // find all activated controls, whether the scripts are interested in them or not
3977 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3978 {
3979 allflags |= ScriptControlled.CONTROL_FWD;
3980 }
3981
3982 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3983 {
3984 allflags |= ScriptControlled.CONTROL_BACK;
3985 }
3986
3987 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3988 {
3989 allflags |= ScriptControlled.CONTROL_UP;
3990 }
3991
3992 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3993 {
3994 allflags |= ScriptControlled.CONTROL_DOWN;
3995 }
3846 3996
3847 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3997 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3848 { 3998 {
3849 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 3999 allflags |= ScriptControlled.CONTROL_LEFT;
3850 MouseDown = true; 4000 }
3851 } 4001
3852 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 4002 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3853 { 4003 {
3854 allflags |= ScriptControlled.CONTROL_LBUTTON; 4004 allflags |= ScriptControlled.CONTROL_RIGHT;
3855 MouseDown = true; 4005 }
3856 } 4006
4007 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
4008 {
4009 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
4010 }
4011
4012 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
4013 {
4014 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
4015 }
3857 4016
3858 // find all activated controls, whether the scripts are interested in them or not 4017 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3859 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) 4018 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3860 {
3861 allflags |= ScriptControlled.CONTROL_FWD;
3862 }
3863 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3864 {
3865 allflags |= ScriptControlled.CONTROL_BACK;
3866 }
3867 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3868 {
3869 allflags |= ScriptControlled.CONTROL_UP;
3870 }
3871 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3872 {
3873 allflags |= ScriptControlled.CONTROL_DOWN;
3874 }
3875 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3876 {
3877 allflags |= ScriptControlled.CONTROL_LEFT;
3878 }
3879 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3880 {
3881 allflags |= ScriptControlled.CONTROL_RIGHT;
3882 }
3883 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3884 {
3885 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3886 }
3887 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3888 {
3889 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3890 }
3891 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3892 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3893 {
3894 lock (scriptedcontrols)
3895 { 4019 {
3896 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 4020 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3897 { 4021 {
3898 UUID scriptUUID = kvp.Key; 4022 UUID scriptUUID = kvp.Key;
3899 ScriptControllers scriptControlData = kvp.Value; 4023 ScriptControllers scriptControlData = kvp.Value;
3900 4024
3901 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 4025 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3902 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 4026 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3903 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 4027 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
4028
3904 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 4029 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3905 { 4030 {
3906 // only send if still pressed or just changed 4031 // only send if still pressed or just changed
@@ -3908,9 +4033,9 @@ namespace OpenSim.Region.Framework.Scenes
3908 } 4033 }
3909 } 4034 }
3910 } 4035 }
4036
4037 LastCommands = allflags;
3911 } 4038 }
3912
3913 LastCommands = allflags;
3914 } 4039 }
3915 4040
3916 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4041 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -3990,7 +4115,7 @@ namespace OpenSim.Region.Framework.Scenes
3990 land.LandData.UserLocation != Vector3.Zero && 4115 land.LandData.UserLocation != Vector3.Zero &&
3991 land.LandData.OwnerID != m_uuid && 4116 land.LandData.OwnerID != m_uuid &&
3992 (!m_scene.Permissions.IsGod(m_uuid)) && 4117 (!m_scene.Permissions.IsGod(m_uuid)) &&
3993 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4118 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
3994 { 4119 {
3995 float curr = Vector3.Distance(AbsolutePosition, pos); 4120 float curr = Vector3.Distance(AbsolutePosition, pos);
3996 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4121 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4004,13 +4129,13 @@ namespace OpenSim.Region.Framework.Scenes
4004 { 4129 {
4005 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 4130 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4006 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 4131 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4007 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 4132 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) ||
4008 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4133 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4009 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) 4134 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4010 { 4135 {
4011 if (GodLevel < 200 && 4136 if (GodLevel < 200 &&
4012 ((!m_scene.Permissions.IsGod(m_uuid) && 4137 ((!m_scene.Permissions.IsGod(m_uuid) &&
4013 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4138 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4014 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4139 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4015 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4140 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4016 { 4141 {
@@ -4018,28 +4143,92 @@ namespace OpenSim.Region.Framework.Scenes
4018 if (spawnPoints.Length == 0) 4143 if (spawnPoints.Length == 0)
4019 return; 4144 return;
4020 4145
4021 float distance = 9999; 4146 int index;
4022 int closest = -1; 4147 bool selected = false;
4023 4148
4024 for (int i = 0 ; i < spawnPoints.Length ; i++) 4149 switch (m_scene.SpawnPointRouting)
4025 { 4150 {
4026 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4151 case "random":
4027 Vector3 offset = spawnPosition - pos;
4028 float d = Vector3.Mag(offset);
4029 if (d >= distance)
4030 continue;
4031 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4032 if (land == null)
4033 continue;
4034 if (land.IsEitherBannedOrRestricted(UUID))
4035 continue;
4036 distance = d;
4037 closest = i;
4038 }
4039 if (closest == -1)
4040 return;
4041 4152
4042 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4153 do
4154 {
4155 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4156
4157 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4158 telehub.AbsolutePosition,
4159 telehub.GroupRotation
4160 );
4161 // SpawnPoint sp = spawnPoints[index];
4162
4163 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4164 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4165 selected = false;
4166 else
4167 selected = true;
4168
4169 } while ( selected == false);
4170
4171 pos = spawnPoints[index].GetLocation(
4172 telehub.AbsolutePosition,
4173 telehub.GroupRotation
4174 );
4175 return;
4176
4177 case "sequence":
4178
4179 do
4180 {
4181 index = m_scene.SpawnPoint();
4182
4183 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4184 telehub.AbsolutePosition,
4185 telehub.GroupRotation
4186 );
4187 // SpawnPoint sp = spawnPoints[index];
4188
4189 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4190 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4191 selected = false;
4192 else
4193 selected = true;
4194
4195 } while (selected == false);
4196
4197 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4198 ;
4199 return;
4200
4201 default:
4202 case "closest":
4203
4204 float distance = 9999;
4205 int closest = -1;
4206
4207 for (int i = 0; i < spawnPoints.Length; i++)
4208 {
4209 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4210 telehub.AbsolutePosition,
4211 telehub.GroupRotation
4212 );
4213 Vector3 offset = spawnPosition - pos;
4214 float d = Vector3.Mag(offset);
4215 if (d >= distance)
4216 continue;
4217 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4218 if (land == null)
4219 continue;
4220 if (land.IsEitherBannedOrRestricted(UUID))
4221 continue;
4222 distance = d;
4223 closest = i;
4224 }
4225 if (closest == -1)
4226 return;
4227
4228 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4229 return;
4230
4231 }
4043 } 4232 }
4044 } 4233 }
4045 } 4234 }
@@ -4084,7 +4273,7 @@ namespace OpenSim.Region.Framework.Scenes
4084 GodLevel < 200 && 4273 GodLevel < 200 &&
4085 ((land.LandData.OwnerID != m_uuid && 4274 ((land.LandData.OwnerID != m_uuid &&
4086 !m_scene.Permissions.IsGod(m_uuid) && 4275 !m_scene.Permissions.IsGod(m_uuid) &&
4087 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4276 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4088 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4277 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4089 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4278 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4090 { 4279 {
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
index 55455cc..a4f730d 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
@@ -47,14 +47,30 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
47 /// </remarks> 47 /// </remarks>
48 public class CoalescedSceneObjectsSerializer 48 public class CoalescedSceneObjectsSerializer
49 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 /// <summary> 52 /// <summary>
53 /// Serialize coalesced objects to Xml 53 /// Serialize coalesced objects to Xml
54 /// </summary> 54 /// </summary>
55 /// <param name="coa"></param> 55 /// <param name="coa"></param>
56 /// <param name="doScriptStates">
57 /// If true then serialize script states. This will halt any running scripts
58 /// </param>
56 /// <returns></returns> 59 /// <returns></returns>
57 public static string ToXml(CoalescedSceneObjects coa) 60 public static string ToXml(CoalescedSceneObjects coa)
61 {
62 return ToXml(coa, true);
63 }
64
65 /// <summary>
66 /// Serialize coalesced objects to Xml
67 /// </summary>
68 /// <param name="coa"></param>
69 /// <param name="doScriptStates">
70 /// If true then serialize script states. This will halt any running scripts
71 /// </param>
72 /// <returns></returns>
73 public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates)
58 { 74 {
59 using (StringWriter sw = new StringWriter()) 75 using (StringWriter sw = new StringWriter())
60 { 76 {
@@ -91,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
91 writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); 107 writer.WriteAttributeString("offsety", offsets[i].Y.ToString());
92 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); 108 writer.WriteAttributeString("offsetz", offsets[i].Z.ToString());
93 109
94 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, true); 110 SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates);
95 111
96 writer.WriteEndElement(); // SceneObjectGroup 112 writer.WriteEndElement(); // SceneObjectGroup
97 } 113 }
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 151eba2..e223f47 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1538,51 +1538,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1538 } 1538 }
1539 } 1539 }
1540 1540
1541 //////// Read /////////
1542 public static bool Xml2ToSOG(XmlTextReader reader, SceneObjectGroup sog)
1543 {
1544 reader.Read();
1545 reader.ReadStartElement("SceneObjectGroup");
1546 SceneObjectPart root = Xml2ToSOP(reader);
1547 if (root != null)
1548 sog.SetRootPart(root);
1549 else
1550 {
1551 return false;
1552 }
1553
1554 if (sog.UUID == UUID.Zero)
1555 sog.UUID = sog.RootPart.UUID;
1556
1557 reader.Read(); // OtherParts
1558
1559 while (!reader.EOF)
1560 {
1561 switch (reader.NodeType)
1562 {
1563 case XmlNodeType.Element:
1564 if (reader.Name == "SceneObjectPart")
1565 {
1566 SceneObjectPart child = Xml2ToSOP(reader);
1567 if (child != null)
1568 sog.AddPart(child);
1569 }
1570 else
1571 {
1572 //Logger.Log("Found unexpected prim XML element " + reader.Name, Helpers.LogLevel.Debug);
1573 reader.Read();
1574 }
1575 break;
1576 case XmlNodeType.EndElement:
1577 default:
1578 reader.Read();
1579 break;
1580 }
1581
1582 }
1583 return true;
1584 }
1585
1586 public static SceneObjectPart Xml2ToSOP(XmlTextReader reader) 1541 public static SceneObjectPart Xml2ToSOP(XmlTextReader reader)
1587 { 1542 {
1588 SceneObjectPart obj = new SceneObjectPart(); 1543 SceneObjectPart obj = new SceneObjectPart();
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
index d214eba..a3485d2 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
@@ -223,50 +223,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
223 223
224 public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString) 224 public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString)
225 { 225 {
226 XmlDocument doc = new XmlDocument(); 226 return SceneObjectSerializer.FromXml2Format(xmlString);
227 XmlNode rootNode;
228
229 XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
230 reader.WhitespaceHandling = WhitespaceHandling.None;
231 doc.Load(reader);
232 reader.Close();
233 rootNode = doc.FirstChild;
234
235 // This is to deal with neighbouring regions that are still surrounding the group xml with the <scene>
236 // tag. It should be possible to remove the first part of this if statement once we go past 0.5.9 (or
237 // when some other changes forces all regions to upgrade).
238 // This might seem rather pointless since prim crossing from this revision to an earlier revision remains
239 // broken. But it isn't much work to accomodate the old format here.
240 if (rootNode.LocalName.Equals("scene"))
241 {
242 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
243 {
244 // There is only ever one prim. This oddity should be removeable post 0.5.9
245 //return SceneObjectSerializer.FromXml2Format(aPrimNode.OuterXml);
246 using (reader = new XmlTextReader(new StringReader(aPrimNode.OuterXml)))
247 {
248 SceneObjectGroup obj = new SceneObjectGroup();
249 if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
250 return obj;
251
252 return null;
253 }
254 }
255
256 return null;
257 }
258 else
259 {
260 //return SceneObjectSerializer.FromXml2Format(rootNode.OuterXml);
261 using (reader = new XmlTextReader(new StringReader(rootNode.OuterXml)))
262 {
263 SceneObjectGroup obj = new SceneObjectGroup();
264 if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
265 return obj;
266
267 return null;
268 }
269 }
270 } 227 }
271 228
272 /// <summary> 229 /// <summary>
@@ -307,8 +264,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
307 ICollection<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 264 ICollection<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
308 foreach (XmlNode aPrimNode in rootNode.ChildNodes) 265 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
309 { 266 {
310 SceneObjectGroup obj = CreatePrimFromXml2(scene, aPrimNode.OuterXml); 267 SceneObjectGroup obj = DeserializeGroupFromXml2(aPrimNode.OuterXml);
311 if (obj != null && startScripts) 268 if (startScripts)
312 sceneObjects.Add(obj); 269 sceneObjects.Add(obj);
313 } 270 }
314 271
@@ -319,27 +276,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
319 } 276 }
320 } 277 }
321 278
322 /// <summary>
323 /// Create a prim from the xml2 representation.
324 /// </summary>
325 /// <param name="scene"></param>
326 /// <param name="xmlData"></param>
327 /// <returns>The scene object created. null if the scene object already existed</returns>
328 protected static SceneObjectGroup CreatePrimFromXml2(Scene scene, string xmlData)
329 {
330 //SceneObjectGroup obj = SceneObjectSerializer.FromXml2Format(xmlData);
331 using (XmlTextReader reader = new XmlTextReader(new StringReader(xmlData)))
332 {
333 SceneObjectGroup obj = new SceneObjectGroup();
334 SceneObjectSerializer.Xml2ToSOG(reader, obj);
335
336 if (scene.AddRestoredSceneObject(obj, true, false))
337 return obj;
338 else
339 return null;
340 }
341 }
342
343 #endregion 279 #endregion
344 } 280 }
345} 281} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
index ab6311b..4a21dc9 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Text; 31using System.Text;
31using NUnit.Framework; 32using NUnit.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
@@ -68,11 +69,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
68 Vector3 position = new Vector3(200,200,21); 69 Vector3 position = new Vector3(200,200,21);
69 70
70 foreach (Border b in testborders) 71 foreach (Border b in testborders)
71 {
72 Assert.That(!b.TestCross(position)); 72 Assert.That(!b.TestCross(position));
73 73
74 }
75
76 position = new Vector3(200,280,21); 74 position = new Vector3(200,280,21);
77 Assert.That(NorthBorder.TestCross(position)); 75 Assert.That(NorthBorder.TestCross(position));
78 76
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index a5d2b23..ea9fc93 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
45 { 45 {
46 static public Random random; 46 static public Random random;
47 SceneObjectGroup found; 47 SceneObjectGroup found;
48 Scene scene = SceneHelpers.SetupScene(); 48 Scene scene = new SceneHelpers().SetupScene();
49 49
50 [Test] 50 [Test]
51 public void T010_AddObjects() 51 public void T010_AddObjects()
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
index 9a60e50..d23c965 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneGraphTests.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.IO;
29using System.Reflection; 30using System.Reflection;
31using System.Text;
30using NUnit.Framework; 32using NUnit.Framework;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenSim.Framework; 34using OpenSim.Framework;
@@ -44,7 +46,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
44 public void TestDuplicateObject() 46 public void TestDuplicateObject()
45 { 47 {
46 TestHelpers.InMethod(); 48 TestHelpers.InMethod();
47 Scene scene = SceneHelpers.SetupScene(); 49// TestHelpers.EnableLogging();
50
51 Scene scene = new SceneHelpers().SetupScene();
48 52
49 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010"); 53 UUID ownerId = new UUID("00000000-0000-0000-0000-000000000010");
50 string part1Name = "part1"; 54 string part1Name = "part1";
@@ -82,6 +86,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
82 Assert.That(dupePart1.PhysActor, Is.Not.Null); 86 Assert.That(dupePart1.PhysActor, Is.Not.Null);
83 Assert.That(dupePart2.PhysActor, Is.Not.Null); 87 Assert.That(dupePart2.PhysActor, Is.Not.Null);
84 */ 88 */
89
90// TestHelpers.DisableLogging();
85 } 91 }
86 } 92 }
87} \ No newline at end of file 93} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 7737d8e..453e077 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -88,7 +88,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
88 { 88 {
89 TestHelpers.InMethod(); 89 TestHelpers.InMethod();
90 90
91 Scene scene = SceneHelpers.SetupScene(); 91 Scene scene = new SceneHelpers().SetupScene();
92 int partsToTestCount = 3; 92 int partsToTestCount = 3;
93 93
94 SceneObjectGroup so 94 SceneObjectGroup so
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
118 { 118 {
119 TestHelpers.InMethod(); 119 TestHelpers.InMethod();
120 120
121 Scene scene = SceneHelpers.SetupScene(); 121 Scene scene = new SceneHelpers().SetupScene();
122 122
123 string obj1Name = "Alfred"; 123 string obj1Name = "Alfred";
124 string obj2Name = "Betty"; 124 string obj2Name = "Betty";
@@ -152,7 +152,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
152 { 152 {
153 TestHelpers.InMethod(); 153 TestHelpers.InMethod();
154 154
155 Scene scene = SceneHelpers.SetupScene(); 155 Scene scene = new SceneHelpers().SetupScene();
156 int partsToTestCount = 3; 156 int partsToTestCount = 3;
157 157
158 SceneObjectGroup so 158 SceneObjectGroup so
@@ -185,7 +185,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
185 { 185 {
186 TestHelpers.InMethod(); 186 TestHelpers.InMethod();
187 187
188 TestScene scene = SceneHelpers.SetupScene(); 188 TestScene scene = new SceneHelpers().SetupScene();
189 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 189 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
190 scene.DeleteSceneObject(part.ParentGroup, false); 190 scene.DeleteSceneObject(part.ParentGroup, false);
191 191
@@ -204,7 +204,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
204 204
205 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); 205 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
206 206
207 TestScene scene = SceneHelpers.SetupScene(); 207 TestScene scene = new SceneHelpers().SetupScene();
208 208
209 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test. 209 // Turn off the timer on the async sog deleter - we'll crank it by hand for this test.
210 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; 210 AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
index 654b1a2..0076f41 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 61
62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 62 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
63 63
64 TestScene scene = SceneHelpers.SetupScene(); 64 TestScene scene = new SceneHelpers().SetupScene();
65 IConfigSource configSource = new IniConfigSource(); 65 IConfigSource configSource = new IniConfigSource();
66 IConfig config = configSource.AddConfig("Startup"); 66 IConfig config = configSource.AddConfig("Startup");
67 config.Set("serverside_object_permissions", true); 67 config.Set("serverside_object_permissions", true);
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 100 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001"); 101 UUID objectOwnerId = UUID.Parse("20000000-0000-0000-0000-000000000001");
102 102
103 TestScene scene = SceneHelpers.SetupScene(); 103 TestScene scene = new SceneHelpers().SetupScene();
104 IConfigSource configSource = new IniConfigSource(); 104 IConfigSource configSource = new IniConfigSource();
105 IConfig config = configSource.AddConfig("Startup"); 105 IConfig config = configSource.AddConfig("Startup");
106 config.Set("serverside_object_permissions", true); 106 config.Set("serverside_object_permissions", true);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index be5b4a8..1add3dd 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
55 UUID ownerId = TestHelpers.ParseTail(0x1); 55 UUID ownerId = TestHelpers.ParseTail(0x1);
56 int nParts = 3; 56 int nParts = 3;
57 57
58 TestScene scene = SceneHelpers.SetupScene(); 58 TestScene scene = new SceneHelpers().SetupScene();
59 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10); 59 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10);
60 scene.AddSceneObject(sog1); 60 scene.AddSceneObject(sog1);
61 scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId }); 61 scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId });
@@ -71,7 +71,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
71 71
72 bool debugtest = false; 72 bool debugtest = false;
73 73
74 Scene scene = SceneHelpers.SetupScene(); 74 Scene scene = new SceneHelpers().SetupScene();
75 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); 75 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
76 SceneObjectGroup grp1 = part1.ParentGroup; 76 SceneObjectGroup grp1 = part1.ParentGroup;
77 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); 77 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
@@ -153,7 +153,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
153 153
154 bool debugtest = false; 154 bool debugtest = false;
155 155
156 Scene scene = SceneHelpers.SetupScene(); 156 Scene scene = new SceneHelpers().SetupScene();
157 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene); 157 SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
158 SceneObjectGroup grp1 = part1.ParentGroup; 158 SceneObjectGroup grp1 = part1.ParentGroup;
159 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene); 159 SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
@@ -286,7 +286,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
286 TestHelpers.InMethod(); 286 TestHelpers.InMethod();
287 //log4net.Config.XmlConfigurator.Configure(); 287 //log4net.Config.XmlConfigurator.Configure();
288 288
289 TestScene scene = SceneHelpers.SetupScene(); 289 TestScene scene = new SceneHelpers().SetupScene();
290 290
291 string rootPartName = "rootpart"; 291 string rootPartName = "rootpart";
292 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 292 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
@@ -325,7 +325,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
325 TestHelpers.InMethod(); 325 TestHelpers.InMethod();
326 //log4net.Config.XmlConfigurator.Configure(); 326 //log4net.Config.XmlConfigurator.Configure();
327 327
328 TestScene scene = SceneHelpers.SetupScene(); 328 TestScene scene = new SceneHelpers().SetupScene();
329 329
330 string rootPartName = "rootpart"; 330 string rootPartName = "rootpart";
331 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001"); 331 UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
index b49c6e7..0a94c19 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectResizeTests.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52 TestHelpers.InMethod(); 52 TestHelpers.InMethod();
53// log4net.Config.XmlConfigurator.Configure(); 53// log4net.Config.XmlConfigurator.Configure();
54 54
55 Scene scene = SceneHelpers.SetupScene(); 55 Scene scene = new SceneHelpers().SetupScene();
56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup; 56 SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup;
57 57
58 g1.GroupResize(new Vector3(2, 3, 4)); 58 g1.GroupResize(new Vector3(2, 3, 4));
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
75 TestHelpers.InMethod(); 75 TestHelpers.InMethod();
76 //log4net.Config.XmlConfigurator.Configure(); 76 //log4net.Config.XmlConfigurator.Configure();
77 77
78 Scene scene = SceneHelpers.SetupScene(); 78 Scene scene = new SceneHelpers().SetupScene();
79 79
80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero); 80 SceneObjectGroup g1 = SceneHelpers.CreateSceneObject(2, UUID.Zero);
81 g1.RootPart.Scale = new Vector3(2, 3, 4); 81 g1.RootPart.Scale = new Vector3(2, 3, 4);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
index c582cf6..d2361f8 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
52// UUID itemId = TestHelpers.ParseTail(0x2); 52// UUID itemId = TestHelpers.ParseTail(0x2);
53 string itemName = "Test Script Item"; 53 string itemName = "Test Script Item";
54 54
55 Scene scene = SceneHelpers.SetupScene(); 55 Scene scene = new SceneHelpers().SetupScene();
56 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId); 56 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
57 scene.AddNewSceneObject(so, true); 57 scene.AddNewSceneObject(so, true);
58 58
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.cs
new file mode 100644
index 0000000..6d255aa
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSpatialTests.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
28using System;
29using System.Reflection;
30using System.Threading;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock;
38
39namespace OpenSim.Region.Framework.Scenes.Tests
40{
41 /// <summary>
42 /// Spatial scene object tests (will eventually cover root and child part position, rotation properties, etc.)
43 /// </summary>
44 [TestFixture]
45 public class SceneObjectSpatialTests
46 {
47 TestScene m_scene;
48 UUID m_ownerId = TestHelpers.ParseTail(0x1);
49
50 [SetUp]
51 public void SetUp()
52 {
53 m_scene = new SceneHelpers().SetupScene();
54 }
55
56 [Test]
57 public void TestGetSceneObjectGroupPosition()
58 {
59 TestHelpers.InMethod();
60
61 Vector3 position = new Vector3(10, 20, 30);
62
63 SceneObjectGroup so
64 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
65 so.AbsolutePosition = position;
66 m_scene.AddNewSceneObject(so, false);
67
68 Assert.That(so.AbsolutePosition, Is.EqualTo(position));
69 }
70
71 [Test]
72 public void TestGetRootPartPosition()
73 {
74 TestHelpers.InMethod();
75
76 Vector3 partPosition = new Vector3(10, 20, 30);
77
78 SceneObjectGroup so
79 = SceneHelpers.CreateSceneObject(1, m_ownerId, "obj1", 0x10);
80 so.AbsolutePosition = partPosition;
81 m_scene.AddNewSceneObject(so, false);
82
83 Assert.That(so.RootPart.AbsolutePosition, Is.EqualTo(partPosition));
84 Assert.That(so.RootPart.GroupPosition, Is.EqualTo(partPosition));
85 Assert.That(so.RootPart.GetWorldPosition(), Is.EqualTo(partPosition));
86 Assert.That(so.RootPart.RelativePosition, Is.EqualTo(partPosition));
87 Assert.That(so.RootPart.OffsetPosition, Is.EqualTo(Vector3.Zero));
88 }
89
90 [Test]
91 public void TestGetChildPartPosition()
92 {
93 TestHelpers.InMethod();
94
95 Vector3 rootPartPosition = new Vector3(10, 20, 30);
96 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
97
98 SceneObjectGroup so
99 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
100 so.AbsolutePosition = rootPartPosition;
101 so.Parts[1].OffsetPosition = childOffsetPosition;
102
103 m_scene.AddNewSceneObject(so, false);
104
105 // Calculate child absolute position.
106 Vector3 childPosition = new Vector3(rootPartPosition + childOffsetPosition);
107
108 SceneObjectPart childPart = so.Parts[1];
109 Assert.That(childPart.AbsolutePosition, Is.EqualTo(childPosition));
110 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
111 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
112 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
113 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
114 }
115
116 [Test]
117 public void TestGetChildPartPositionAfterObjectRotation()
118 {
119 TestHelpers.InMethod();
120
121 Vector3 rootPartPosition = new Vector3(10, 20, 30);
122 Vector3 childOffsetPosition = new Vector3(2, 3, 4);
123
124 SceneObjectGroup so
125 = SceneHelpers.CreateSceneObject(2, m_ownerId, "obj1", 0x10);
126 so.AbsolutePosition = rootPartPosition;
127 so.Parts[1].OffsetPosition = childOffsetPosition;
128
129 m_scene.AddNewSceneObject(so, false);
130
131 so.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 0, -90 * Utils.DEG_TO_RAD));
132
133 // Calculate child absolute position.
134 Vector3 rotatedChildOffsetPosition
135 = new Vector3(childOffsetPosition.Y, -childOffsetPosition.X, childOffsetPosition.Z);
136
137 Vector3 childPosition = new Vector3(rootPartPosition + rotatedChildOffsetPosition);
138
139 SceneObjectPart childPart = so.Parts[1];
140
141 // FIXME: Should be childPosition after rotation?
142 Assert.That(childPart.AbsolutePosition, Is.EqualTo(rootPartPosition + childOffsetPosition));
143
144 Assert.That(childPart.GroupPosition, Is.EqualTo(rootPartPosition));
145 Assert.That(childPart.GetWorldPosition(), Is.EqualTo(childPosition));
146
147 // Relative to root part as (0, 0, 0)
148 Assert.That(childPart.RelativePosition, Is.EqualTo(childOffsetPosition));
149
150 // Relative to root part as (0, 0, 0)
151 Assert.That(childPart.OffsetPosition, Is.EqualTo(childOffsetPosition));
152 }
153 }
154} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
index 2a342d5..742c769 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectStatusTests.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using NUnit.Framework; 31using NUnit.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -43,24 +44,141 @@ namespace OpenSim.Region.Framework.Scenes.Tests
43 [TestFixture] 44 [TestFixture]
44 public class SceneObjectStatusTests 45 public class SceneObjectStatusTests
45 { 46 {
47 private TestScene m_scene;
48 private UUID m_ownerId = TestHelpers.ParseTail(0x1);
49 private SceneObjectGroup m_so1;
50 private SceneObjectGroup m_so2;
51
52 [SetUp]
53 public void Init()
54 {
55 m_scene = new SceneHelpers().SetupScene();
56 m_so1 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so1", 0x10);
57 m_so2 = SceneHelpers.CreateSceneObject(1, m_ownerId, "so2", 0x20);
58 }
59
46 [Test] 60 [Test]
47 public void TestSetPhantom() 61 public void TestSetPhantomSinglePrim()
48 { 62 {
49 TestHelpers.InMethod(); 63 TestHelpers.InMethod();
50 64
51// Scene scene = SceneSetupHelpers.SetupScene(); 65 m_scene.AddSceneObject(m_so1);
52 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, UUID.Zero); 66
53 SceneObjectPart rootPart = so.RootPart; 67 SceneObjectPart rootPart = m_so1.RootPart;
54 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 68 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
55 69
56 so.ScriptSetPhantomStatus(true); 70 m_so1.ScriptSetPhantomStatus(true);
57 71
58// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags); 72// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
59 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom)); 73 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Phantom));
60 74
61 so.ScriptSetPhantomStatus(false); 75 m_so1.ScriptSetPhantomStatus(false);
62 76
63 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None)); 77 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
64 } 78 }
79
80 [Test]
81 public void TestSetPhysicsSinglePrim()
82 {
83 TestHelpers.InMethod();
84
85 m_scene.AddSceneObject(m_so1);
86
87 SceneObjectPart rootPart = m_so1.RootPart;
88 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
89
90 m_so1.ScriptSetPhysicsStatus(true);
91
92// Console.WriteLine("so.RootPart.Flags [{0}]", so.RootPart.Flags);
93 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.Physics));
94
95 m_so1.ScriptSetPhysicsStatus(false);
96
97 Assert.That(rootPart.Flags, Is.EqualTo(PrimFlags.None));
98 }
99
100 [Test]
101 public void TestSetPhysicsLinkset()
102 {
103 TestHelpers.InMethod();
104
105 m_scene.AddSceneObject(m_so1);
106 m_scene.AddSceneObject(m_so2);
107
108 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
109
110 m_so1.ScriptSetPhysicsStatus(true);
111
112 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
113 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
114
115 m_so1.ScriptSetPhysicsStatus(false);
116
117 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
118 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
119
120 m_so1.ScriptSetPhysicsStatus(true);
121
122 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
123 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
124 }
125
126 /// <summary>
127 /// Test that linking results in the correct physical status for all linkees.
128 /// </summary>
129 [Test]
130 public void TestLinkPhysicsBothPhysical()
131 {
132 TestHelpers.InMethod();
133
134 m_scene.AddSceneObject(m_so1);
135 m_scene.AddSceneObject(m_so2);
136
137 m_so1.ScriptSetPhysicsStatus(true);
138 m_so2.ScriptSetPhysicsStatus(true);
139
140 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
141
142 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
143 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
144 }
145
146 /// <summary>
147 /// Test that linking results in the correct physical status for all linkees.
148 /// </summary>
149 [Test]
150 public void TestLinkPhysicsRootPhysicalOnly()
151 {
152 TestHelpers.InMethod();
153
154 m_scene.AddSceneObject(m_so1);
155 m_scene.AddSceneObject(m_so2);
156
157 m_so1.ScriptSetPhysicsStatus(true);
158
159 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
160
161 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.Physics));
162 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.Physics));
163 }
164
165 /// <summary>
166 /// Test that linking results in the correct physical status for all linkees.
167 /// </summary>
168 [Test]
169 public void TestLinkPhysicsChildPhysicalOnly()
170 {
171 TestHelpers.InMethod();
172
173 m_scene.AddSceneObject(m_so1);
174 m_scene.AddSceneObject(m_so2);
175
176 m_so2.ScriptSetPhysicsStatus(true);
177
178 m_scene.LinkObjects(m_ownerId, m_so1.LocalId, new List<uint>() { m_so2.LocalId });
179
180 Assert.That(m_so1.RootPart.Flags, Is.EqualTo(PrimFlags.None));
181 Assert.That(m_so1.Parts[1].Flags, Is.EqualTo(PrimFlags.None));
182 }
65 } 183 }
66} \ No newline at end of file 184} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
index c13d82e..c7eaff9 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectUserGroupTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
58 58
59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001"); 59 UUID userId = UUID.Parse("10000000-0000-0000-0000-000000000001");
60 60
61 TestScene scene = SceneHelpers.SetupScene(); 61 TestScene scene = new SceneHelpers().SetupScene();
62 IConfigSource configSource = new IniConfigSource(); 62 IConfigSource configSource = new IniConfigSource();
63 63
64 IConfig startupConfig = configSource.AddConfig("Startup"); 64 IConfig startupConfig = configSource.AddConfig("Startup");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index ed9b179..1aa48d7 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -67,10 +67,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests
67 public void Init() 67 public void Init()
68 { 68 {
69 TestHelpers.InMethod(); 69 TestHelpers.InMethod();
70 70
71 scene = SceneHelpers.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); 71 SceneHelpers sh = new SceneHelpers();
72 scene2 = SceneHelpers.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); 72
73 scene3 = SceneHelpers.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); 73 scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000);
74 scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000);
75 scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000);
74 76
75 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 77 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule();
76 interregionComms.Initialise(new IniConfigSource()); 78 interregionComms.Initialise(new IniConfigSource());
@@ -101,7 +103,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 TestHelpers.InMethod(); 103 TestHelpers.InMethod();
102// log4net.Config.XmlConfigurator.Configure(); 104// log4net.Config.XmlConfigurator.Configure();
103 105
104 TestScene scene = SceneHelpers.SetupScene(); 106 TestScene scene = new SceneHelpers().SetupScene();
105 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 107 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
106 108
107 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); 109 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null);
@@ -126,7 +128,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
126 IConfig config = configSource.AddConfig("Modules"); 128 IConfig config = configSource.AddConfig("Modules");
127 config.Set("SimulationServices", "LocalSimulationConnectorModule"); 129 config.Set("SimulationServices", "LocalSimulationConnectorModule");
128 130
129 TestScene scene = SceneHelpers.SetupScene(); 131 SceneHelpers sceneHelpers = new SceneHelpers();
132 TestScene scene = sceneHelpers.SetupScene();
130 SceneHelpers.SetupSceneModules(scene, configSource, lsc); 133 SceneHelpers.SetupSceneModules(scene, configSource, lsc);
131 134
132 UUID agentId = TestHelpers.ParseTail(0x01); 135 UUID agentId = TestHelpers.ParseTail(0x01);
@@ -176,8 +179,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
176 179
177// UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001"); 180// UUID agent1Id = UUID.Parse("00000000-0000-0000-0000-000000000001");
178 181
179 TestScene myScene1 = SceneHelpers.SetupScene("Neighbour y", UUID.Random(), 1000, 1000); 182 TestScene myScene1 = new SceneHelpers().SetupScene("Neighbour y", UUID.Random(), 1000, 1000);
180 TestScene myScene2 = SceneHelpers.SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000); 183 TestScene myScene2 = new SceneHelpers().SetupScene("Neighbour y + 1", UUID.Random(), 1001, 1000);
181 184
182 IConfigSource configSource = new IniConfigSource(); 185 IConfigSource configSource = new IniConfigSource();
183 IConfig config = configSource.AddConfig("Startup"); 186 IConfig config = configSource.AddConfig("Startup");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
index 89f8007..646e5fa 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs
@@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
59 TestHelpers.InMethod(); 59 TestHelpers.InMethod();
60// log4net.Config.XmlConfigurator.Configure(); 60// log4net.Config.XmlConfigurator.Configure();
61 61
62 TestScene scene = SceneHelpers.SetupScene(); 62 TestScene scene = new SceneHelpers().SetupScene();
63 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 63 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
64 sp.Flying = true; 64 sp.Flying = true;
65 sp.PhysicsCollisionUpdate(new CollisionEventUpdate()); 65 sp.PhysicsCollisionUpdate(new CollisionEventUpdate());
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index cfea10d..1d1ff88 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -64,7 +64,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
64 [SetUp] 64 [SetUp]
65 public void Init() 65 public void Init()
66 { 66 {
67 m_scene = SceneHelpers.SetupScene(); 67 m_scene = new SceneHelpers().SetupScene();
68 } 68 }
69 69
70 [Test] 70 [Test]
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
index b7b8db4..313e350 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
50 [SetUp] 50 [SetUp]
51 public void Init() 51 public void Init()
52 { 52 {
53 m_scene = SceneHelpers.SetupScene(); 53 m_scene = new SceneHelpers().SetupScene();
54 m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); 54 m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
55 } 55 }
56 56
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index bebc10c..ccfe4ff 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -34,10 +34,14 @@ using OpenSim.Framework;
34using OpenSim.Framework.Communications; 34using OpenSim.Framework.Communications;
35using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
36using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.CoreModules.Framework;
38using OpenSim.Region.CoreModules.Framework.EntityTransfer;
37using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; 39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
40using OpenSim.Region.CoreModules.World.Permissions;
38using OpenSim.Tests.Common; 41using OpenSim.Tests.Common;
39using OpenSim.Tests.Common.Mock; 42using OpenSim.Tests.Common.Mock;
40using System.Threading; 43using System.IO;
44using System.Text;
41 45
42namespace OpenSim.Region.Framework.Scenes.Tests 46namespace OpenSim.Region.Framework.Scenes.Tests
43{ 47{
@@ -47,145 +51,344 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 [TestFixture] 51 [TestFixture]
48 public class ScenePresenceTeleportTests 52 public class ScenePresenceTeleportTests
49 { 53 {
50 /// <summary> 54 [TestFixtureSetUp]
51 /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. 55 public void FixtureInit()
52 /// </summary> 56 {
53 /// Does not yet do what is says on the tin. 57 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
54 /// Commenting for now 58 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
55 //[Test, LongRunning] 59 }
56 public void TestSimpleNotNeighboursTeleport() 60
61 [TestFixtureTearDown]
62 public void TearDown()
63 {
64 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
65 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
66 // tests really shouldn't).
67 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
68 }
69
70 [Test]
71 public void TestSameRegionTeleport()
57 { 72 {
58 TestHelpers.InMethod(); 73 TestHelpers.InMethod();
59 ThreadRunResults results = new ThreadRunResults(); 74// log4net.Config.XmlConfigurator.Configure();
60 results.Result = false; 75
61 results.Message = "Test did not run"; 76 EntityTransferModule etm = new EntityTransferModule();
62 TestRunning testClass = new TestRunning(results); 77
78 IConfigSource config = new IniConfigSource();
79 config.AddConfig("Modules");
80 // Not strictly necessary since FriendsModule assumes it is the default (!)
81 config.Configs["Modules"].Set("EntityTransferModule", etm.Name);
82
83 TestScene scene = new SceneHelpers().SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
84 SceneHelpers.SetupSceneModules(scene, config, etm);
85
86 Vector3 teleportPosition = new Vector3(10, 11, 12);
87 Vector3 teleportLookAt = new Vector3(20, 21, 22);
63 88
64 Thread testThread = new Thread(testClass.run); 89 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
90 sp.AbsolutePosition = new Vector3(30, 31, 32);
91 scene.RequestTeleportLocation(
92 sp.ControllingClient,
93 scene.RegionInfo.RegionHandle,
94 teleportPosition,
95 teleportLookAt,
96 (uint)TeleportFlags.ViaLocation);
65 97
66 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against 98 Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition));
67 // A thread abort exception in the simulator code.
68 testThread.Start();
69 testThread.Join();
70 99
71 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); 100 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
72 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); 101 // position instead).
102// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
73 } 103 }
74 104
75 [TearDown] 105 [Test]
76 public void TearDown() 106 public void TestSameSimulatorSeparatedRegionsTeleport()
77 { 107 {
78 try 108 TestHelpers.InMethod();
79 { 109// log4net.Config.XmlConfigurator.Configure();
80 if (MainServer.Instance != null) MainServer.Instance.Stop(); 110
81 } 111 UUID userId = TestHelpers.ParseTail(0x1);
82 catch (NullReferenceException) 112
83 { } 113 EntityTransferModule etmA = new EntityTransferModule();
114 EntityTransferModule etmB = new EntityTransferModule();
115 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
116
117 IConfigSource config = new IniConfigSource();
118 IConfig modulesConfig = config.AddConfig("Modules");
119 modulesConfig.Set("EntityTransferModule", etmA.Name);
120 modulesConfig.Set("SimulationServices", lscm.Name);
121 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
122
123 // In order to run a single threaded regression test we do not want the entity transfer module waiting
124 // for a callback from the destination scene before removing its avatar data.
125 entityTransferConfig.Set("wait_for_callback", false);
126
127 SceneHelpers sh = new SceneHelpers();
128 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
129 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
130
131 SceneHelpers.SetupSceneModules(sceneA, config, etmA);
132 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
133 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
134
135 Vector3 teleportPosition = new Vector3(10, 11, 12);
136 Vector3 teleportLookAt = new Vector3(20, 21, 22);
137
138 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
139 sp.AbsolutePosition = new Vector3(30, 31, 32);
140
141 // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
142 // UDP stack (?)
143// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB;
144
145 sceneA.RequestTeleportLocation(
146 sp.ControllingClient,
147 sceneB.RegionInfo.RegionHandle,
148 teleportPosition,
149 teleportLookAt,
150 (uint)TeleportFlags.ViaLocation);
151
152 ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
153
154 Assert.That(sceneA.GetScenePresence(userId), Is.Null);
155
156 ScenePresence sceneBSp = sceneB.GetScenePresence(userId);
157 Assert.That(sceneBSp, Is.Not.Null);
158 Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
159 Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
160
161 // TODO: Add assertions to check correct circuit details in both scenes.
162
163 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
164 // position instead).
165// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
84 } 166 }
85 167
86 } 168 /// <summary>
169 /// Test teleport procedures when the target simulator returns false when queried about access.
170 /// </summary>
171 [Test]
172 public void TestSameSimulatorSeparatedRegionsQueryAccessFails()
173 {
174 TestHelpers.InMethod();
175// TestHelpers.EnableLogging();
87 176
88 public class ThreadRunResults 177 UUID userId = TestHelpers.ParseTail(0x1);
89 { 178 Vector3 preTeleportPosition = new Vector3(30, 31, 32);
90 public bool Result = false;
91 public string Message = string.Empty;
92 }
93 179
94 public class TestRunning 180 EntityTransferModule etmA = new EntityTransferModule();
95 { 181 EntityTransferModule etmB = new EntityTransferModule();
96 public ThreadRunResults results; 182
97 public TestRunning(ThreadRunResults t) 183 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
184
185 IConfigSource config = new IniConfigSource();
186 config.AddConfig("Modules");
187 config.Configs["Modules"].Set("EntityTransferModule", etmA.Name);
188 config.Configs["Modules"].Set("SimulationServices", lscm.Name);
189
190 config.AddConfig("EntityTransfer");
191
192 // In order to run a single threaded regression test we do not want the entity transfer module waiting
193 // for a callback from the destination scene before removing its avatar data.
194 config.Configs["EntityTransfer"].Set("wait_for_callback", false);
195
196 config.AddConfig("Startup");
197 config.Configs["Startup"].Set("serverside_object_permissions", true);
198
199 SceneHelpers sh = new SceneHelpers();
200 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
201 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
202
203 SceneHelpers.SetupSceneModules(sceneA, config, etmA );
204
205 // We need to set up the permisions module on scene B so that our later use of agent limit to deny
206 // QueryAccess won't succeed anyway because administrators are always allowed in and the default
207 // IsAdministrator if no permissions module is present is true.
208 SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB });
209
210 // Shared scene modules
211 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
212
213 Vector3 teleportPosition = new Vector3(10, 11, 12);
214 Vector3 teleportLookAt = new Vector3(20, 21, 22);
215
216 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
217 sp.AbsolutePosition = preTeleportPosition;
218
219 // Make sceneB return false on query access
220 sceneB.RegionInfo.RegionSettings.AgentLimit = 0;
221
222 sceneA.RequestTeleportLocation(
223 sp.ControllingClient,
224 sceneB.RegionInfo.RegionHandle,
225 teleportPosition,
226 teleportLookAt,
227 (uint)TeleportFlags.ViaLocation);
228
229// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
230
231 Assert.That(sceneB.GetScenePresence(userId), Is.Null);
232
233 ScenePresence sceneASp = sceneA.GetScenePresence(userId);
234 Assert.That(sceneASp, Is.Not.Null);
235 Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
236 Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
237
238 // TODO: Add assertions to check correct circuit details in both scenes.
239
240 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
241 // position instead).
242// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
243
244// TestHelpers.DisableLogging();
245 }
246
247 /// <summary>
248 /// Test teleport procedures when the target simulator create agent step is refused.
249 /// </summary>
250 [Test]
251 public void TestSameSimulatorSeparatedRegionsCreateAgentFails()
98 { 252 {
99 results = t; 253 TestHelpers.InMethod();
254// TestHelpers.EnableLogging();
255
256 UUID userId = TestHelpers.ParseTail(0x1);
257 Vector3 preTeleportPosition = new Vector3(30, 31, 32);
258
259 EntityTransferModule etmA = new EntityTransferModule();
260 EntityTransferModule etmB = new EntityTransferModule();
261 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
262
263 IConfigSource config = new IniConfigSource();
264 config.AddConfig("Modules");
265 config.Configs["Modules"].Set("EntityTransferModule", etmA.Name);
266 config.Configs["Modules"].Set("SimulationServices", lscm.Name);
267
268 config.AddConfig("EntityTransfer");
269
270 // In order to run a single threaded regression test we do not want the entity transfer module waiting
271 // for a callback from the destination scene before removing its avatar data.
272 config.Configs["EntityTransfer"].Set("wait_for_callback", false);
273
274 SceneHelpers sh = new SceneHelpers();
275 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
276 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000);
277
278 SceneHelpers.SetupSceneModules(sceneA, config, etmA);
279 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
280
281 // Shared scene modules
282 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
283
284 Vector3 teleportPosition = new Vector3(10, 11, 12);
285 Vector3 teleportLookAt = new Vector3(20, 21, 22);
286
287 ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
288 sp.AbsolutePosition = preTeleportPosition;
289
290 // Make sceneB refuse CreateAgent
291 sceneB.LoginsDisabled = true;
292
293 sceneA.RequestTeleportLocation(
294 sp.ControllingClient,
295 sceneB.RegionInfo.RegionHandle,
296 teleportPosition,
297 teleportLookAt,
298 (uint)TeleportFlags.ViaLocation);
299
300// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
301
302 Assert.That(sceneB.GetScenePresence(userId), Is.Null);
303
304 ScenePresence sceneASp = sceneA.GetScenePresence(userId);
305 Assert.That(sceneASp, Is.Not.Null);
306 Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
307 Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
308
309 // TODO: Add assertions to check correct circuit details in both scenes.
310
311 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
312 // position instead).
313// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
314
315// TestHelpers.DisableLogging();
100 } 316 }
101 public void run(object o) 317
318 [Test]
319 public void TestSameSimulatorNeighbouringRegionsTeleport()
102 { 320 {
103 321 TestHelpers.InMethod();
104 //results.Result = true; 322// TestHelpers.EnableLogging();
105 log4net.Config.XmlConfigurator.Configure(); 323
106 324 UUID userId = TestHelpers.ParseTail(0x1);
107 UUID sceneAId = UUID.Parse("00000000-0000-0000-0000-000000000100"); 325
108 UUID sceneBId = UUID.Parse("00000000-0000-0000-0000-000000000200"); 326 EntityTransferModule etmA = new EntityTransferModule();
109 327 EntityTransferModule etmB = new EntityTransferModule();
110 // shared module 328 LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
111 ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); 329
112 330 IConfigSource config = new IniConfigSource();
113 331 IConfig modulesConfig = config.AddConfig("Modules");
114 Scene sceneB = SceneHelpers.SetupScene("sceneB", sceneBId, 1010, 1010); 332 modulesConfig.Set("EntityTransferModule", etmA.Name);
115 SceneHelpers.SetupSceneModules(sceneB, new IniConfigSource(), interregionComms); 333 modulesConfig.Set("SimulationServices", lscm.Name);
116 sceneB.RegisterRegionWithGrid(); 334 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
117 335
118 Scene sceneA = SceneHelpers.SetupScene("sceneA", sceneAId, 1000, 1000); 336 // In order to run a single threaded regression test we do not want the entity transfer module waiting
119 SceneHelpers.SetupSceneModules(sceneA, new IniConfigSource(), interregionComms); 337 // for a callback from the destination scene before removing its avatar data.
120 sceneA.RegisterRegionWithGrid(); 338 entityTransferConfig.Set("wait_for_callback", false);
121 339
122 UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000041"); 340 SceneHelpers sh = new SceneHelpers();
123 TestClient client = (TestClient)SceneHelpers.AddScenePresence(sceneA, agentId).ControllingClient; 341 TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
124 342 TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
125 ICapabilitiesModule sceneACapsModule = sceneA.RequestModuleInterface<ICapabilitiesModule>(); 343
126 344 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
127 results.Result = (sceneACapsModule.GetCapsPath(agentId) == client.CapsSeedUrl); 345 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
128 346 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
129 if (!results.Result) 347
130 { 348 Vector3 teleportPosition = new Vector3(10, 11, 12);
131 results.Message = "Incorrect caps object path set up in sceneA"; 349 Vector3 teleportLookAt = new Vector3(20, 21, 22);
132 return; 350
133 } 351 ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager);
134 352 originalSp.AbsolutePosition = new Vector3(30, 31, 32);
135 /* 353
136 Assert.That( 354 ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId);
137 sceneACapsModule.GetCapsPath(agentId), 355 Assert.That(beforeSceneASp, Is.Not.Null);
138 Is.EqualTo(client.CapsSeedUrl), 356 Assert.That(beforeSceneASp.IsChildAgent, Is.False);
139 "Incorrect caps object path set up in sceneA"); 357
140 */ 358 ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId);
141 // FIXME: This is a hack to get the test working - really the normal OpenSim mechanisms should be used. 359 Assert.That(beforeSceneBSp, Is.Not.Null);
142 360 Assert.That(beforeSceneBSp.IsChildAgent, Is.True);
143 361
144 client.TeleportTargetScene = sceneB; 362 // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole
145 client.Teleport(sceneB.RegionInfo.RegionHandle, new Vector3(100, 100, 100), new Vector3(40, 40, 40)); 363 // UDP stack (?)
146 364// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB;
147 results.Result = (sceneB.GetScenePresence(agentId) != null); 365
148 if (!results.Result) 366 sceneA.RequestTeleportLocation(
149 { 367 beforeSceneASp.ControllingClient,
150 results.Message = "Client does not have an agent in sceneB"; 368 sceneB.RegionInfo.RegionHandle,
151 return; 369 teleportPosition,
152 } 370 teleportLookAt,
153 371 (uint)TeleportFlags.ViaLocation);
154 //Assert.That(sceneB.GetScenePresence(agentId), Is.Not.Null, "Client does not have an agent in sceneB"); 372
155 373 ((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide();
156 //Assert.That(sceneA.GetScenePresence(agentId), Is.Null, "Client still had an agent in sceneA"); 374
157 375 ScenePresence afterSceneASp = sceneA.GetScenePresence(userId);
158 results.Result = (sceneA.GetScenePresence(agentId) == null); 376 Assert.That(afterSceneASp, Is.Not.Null);
159 if (!results.Result) 377 Assert.That(afterSceneASp.IsChildAgent, Is.True);
160 { 378
161 results.Message = "Client still had an agent in sceneA"; 379 ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId);
162 return; 380 Assert.That(afterSceneBSp, Is.Not.Null);
163 } 381 Assert.That(afterSceneBSp.IsChildAgent, Is.False);
164 382 Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
165 ICapabilitiesModule sceneBCapsModule = sceneB.RequestModuleInterface<ICapabilitiesModule>(); 383 Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
166 384
167 385 // TODO: Add assertions to check correct circuit details in both scenes.
168 results.Result = ("http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + 386
169 "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/" == client.CapsSeedUrl); 387 // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
170 if (!results.Result) 388 // position instead).
171 { 389// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
172 results.Message = "Incorrect caps object path set up in sceneB"; 390
173 return; 391// TestHelpers.DisableLogging();
174 }
175
176 // Temporary assertion - caps url construction should at least be doable through a method.
177 /*
178 Assert.That(
179 "http://" + sceneB.RegionInfo.ExternalHostName + ":" + sceneB.RegionInfo.HttpPort + "/CAPS/" + sceneBCapsModule.GetCapsPath(agentId) + "0000/",
180 Is.EqualTo(client.CapsSeedUrl),
181 "Incorrect caps object path set up in sceneB");
182 */
183 // This assertion will currently fail since we don't remove the caps paths when no longer needed
184 //Assert.That(sceneACapsModule.GetCapsPath(agentId), Is.Null, "sceneA still had a caps object path");
185
186 // TODO: Check that more of everything is as it should be
187
188 // TODO: test what happens if we try to teleport to a region that doesn't exist
189 } 392 }
190 } 393 }
191} 394} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 5c9a77d..d722a09 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
60 { 60 {
61 TestHelpers.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneHelpers.SetupScene(); 63 Scene scene = new SceneHelpers().SetupScene();
64 scene.Update(1); 64 scene.Update(1);
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index 55c80f5..d15141b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests
58 TestHelpers.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneHelpers.SetupScene(); 61 Scene scene = new SceneHelpers().SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 63 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
64 SceneObjectPart sop1 = sog1.RootPart; 64 SceneObjectPart sop1 = sog1.RootPart;
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Tests
81 TestHelpers.InMethod(); 81 TestHelpers.InMethod();
82// log4net.Config.XmlConfigurator.Configure(); 82// log4net.Config.XmlConfigurator.Configure();
83 83
84 Scene scene = SceneHelpers.SetupScene(); 84 Scene scene = new SceneHelpers().SetupScene();
85 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 85 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
86 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 86 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
87 SceneObjectPart sop1 = sog1.RootPart; 87 SceneObjectPart sop1 = sog1.RootPart;
@@ -124,7 +124,7 @@ namespace OpenSim.Region.Framework.Tests
124 TestHelpers.InMethod(); 124 TestHelpers.InMethod();
125// log4net.Config.XmlConfigurator.Configure(); 125// log4net.Config.XmlConfigurator.Configure();
126 126
127 Scene scene = SceneHelpers.SetupScene(); 127 Scene scene = new SceneHelpers().SetupScene();
128 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 128 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
129 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 129 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
130 SceneObjectPart sop1 = sog1.RootPart; 130 SceneObjectPart sop1 = sog1.RootPart;
@@ -153,7 +153,7 @@ namespace OpenSim.Region.Framework.Tests
153 TestHelpers.InMethod(); 153 TestHelpers.InMethod();
154// log4net.Config.XmlConfigurator.Configure(); 154// log4net.Config.XmlConfigurator.Configure();
155 155
156 Scene scene = SceneHelpers.SetupScene(); 156 Scene scene = new SceneHelpers().SetupScene();
157 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); 157 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
158 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID); 158 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
159 SceneObjectPart sop1 = sog1.RootPart; 159 SceneObjectPart sop1 = sog1.RootPart;
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 55fc1e7..44d2d45 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Tests
58 TestHelpers.InMethod(); 58 TestHelpers.InMethod();
59// log4net.Config.XmlConfigurator.Configure(); 59// log4net.Config.XmlConfigurator.Configure();
60 60
61 Scene scene = SceneHelpers.SetupScene(); 61 Scene scene = new SceneHelpers().SetupScene();
62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 62 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); 63 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); 64 InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID);
@@ -85,7 +85,7 @@ namespace OpenSim.Region.Framework.Tests
85 TestHelpers.InMethod(); 85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 86// log4net.Config.XmlConfigurator.Configure();
87 87
88 Scene scene = SceneHelpers.SetupScene(); 88 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002)); 90 UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1002));
91 InventoryFolderBase folder1 91 InventoryFolderBase folder1
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index d9fe87c..198e487 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
47 public void Init() 47 public void Init()
48 { 48 {
49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service. 49 // FIXME: We don't need a full scene here - it would be enough to set up the asset service.
50 Scene scene = SceneHelpers.SetupScene(); 50 Scene scene = new SceneHelpers().SetupScene();
51 m_assetService = scene.AssetService; 51 m_assetService = scene.AssetService;
52 m_uuidGatherer = new UuidGatherer(m_assetService); 52 m_uuidGatherer = new UuidGatherer(m_assetService);
53 } 53 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
new file mode 100644
index 0000000..1b9e3ac
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
@@ -0,0 +1,195 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Statistics;
40using OpenSim.Region.ClientStack.LindenUDP;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.Avatar.Attachments
45{
46 /// <summary>
47 /// A module that just holds commands for inspecting avatar appearance.
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsCommandModule")]
50 public class AttachmentsCommandModule : ISharedRegionModule
51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private List<Scene> m_scenes = new List<Scene>();
55// private IAvatarFactoryModule m_avatarFactory;
56
57 public string Name { get { return "Attachments Command Module"; } }
58
59 public Type ReplaceableInterface { get { return null; } }
60
61 public void Initialise(IConfigSource source)
62 {
63// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: INITIALIZED MODULE");
64 }
65
66 public void PostInitialise()
67 {
68// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: POST INITIALIZED MODULE");
69 }
70
71 public void Close()
72 {
73// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: CLOSED MODULE");
74 }
75
76 public void AddRegion(Scene scene)
77 {
78// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
79 }
80
81 public void RemoveRegion(Scene scene)
82 {
83// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
84
85 lock (m_scenes)
86 m_scenes.Remove(scene);
87 }
88
89 public void RegionLoaded(Scene scene)
90 {
91// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
92
93 lock (m_scenes)
94 m_scenes.Add(scene);
95
96 scene.AddCommand(
97 "Users", this, "attachments show",
98 "attachments show [<first-name> <last-name>]",
99 "Show attachment information for avatars in this simulator.",
100 HandleShowAttachmentsCommand);
101 }
102
103 protected void HandleShowAttachmentsCommand(string module, string[] cmd)
104 {
105 if (cmd.Length != 2 && cmd.Length < 4)
106 {
107 MainConsole.Instance.OutputFormat("Usage: attachments show [<first-name> <last-name>]");
108 return;
109 }
110
111 bool targetNameSupplied = false;
112 string optionalTargetFirstName = null;
113 string optionalTargetLastName = null;
114
115 if (cmd.Length >= 4)
116 {
117 targetNameSupplied = true;
118 optionalTargetFirstName = cmd[2];
119 optionalTargetLastName = cmd[3];
120 }
121
122 StringBuilder sb = new StringBuilder();
123
124 lock (m_scenes)
125 {
126 foreach (Scene scene in m_scenes)
127 {
128 if (targetNameSupplied)
129 {
130 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
131 if (sp != null && !sp.IsChildAgent)
132 GetAttachmentsReport(sp, sb);
133 }
134 else
135 {
136 scene.ForEachRootScenePresence(sp => GetAttachmentsReport(sp, sb));
137 }
138 }
139 }
140
141 MainConsole.Instance.Output(sb.ToString());
142 }
143
144 private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb)
145 {
146 sb.AppendFormat("Attachments for {0}\n", sp.Name);
147
148 ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 };
149 ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36));
150 ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10));
151 ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36));
152 ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14));
153 ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15));
154
155// sb.AppendFormat(
156// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n",
157// "Attachment Name", "Local ID", "Item ID", "Attach Point", "Position");
158
159 List<SceneObjectGroup> attachmentObjects = sp.GetAttachments();
160 foreach (SceneObjectGroup attachmentObject in attachmentObjects)
161 {
162// InventoryItemBase attachmentItem
163// = m_scenes[0].InventoryService.GetItem(new InventoryItemBase(attachmentObject.FromItemID));
164
165// if (attachmentItem == null)
166// {
167// sb.AppendFormat(
168// "WARNING: Couldn't find attachment for item {0} at point {1}\n",
169// attachmentData.ItemID, (AttachmentPoint)attachmentData.AttachPoint);
170// continue;
171// }
172// else
173// {
174// sb.AppendFormat(
175// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n",
176// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID,
177// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos);
178 ct.Rows.Add(
179 new ConsoleDisplayTableRow(
180 new List<string>()
181 {
182 attachmentObject.Name,
183 attachmentObject.LocalId.ToString(),
184 attachmentObject.FromItemID.ToString(),
185 ((AttachmentPoint)attachmentObject.AttachmentPoint).ToString(),
186 attachmentObject.RootPart.AttachedPos.ToString()
187 }));
188// }
189 }
190
191 ct.AddToStringBuilder(sb);
192 sb.Append("\n");
193 }
194 }
195} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
index e68f9d0..2602050 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
@@ -58,6 +58,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
58 private Scene m_scene; 58 private Scene m_scene;
59 private IFriendsModule m_friendsModule; 59 private IFriendsModule m_friendsModule;
60 private IUserManagement m_userManagementModule; 60 private IUserManagement m_userManagementModule;
61 private IPresenceService m_presenceService;
61 62
62// private IAvatarFactoryModule m_avatarFactory; 63// private IAvatarFactoryModule m_avatarFactory;
63 64
@@ -99,8 +100,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
99 100
100 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 101 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
101 m_userManagementModule = m_scene.RequestModuleInterface<IUserManagement>(); 102 m_userManagementModule = m_scene.RequestModuleInterface<IUserManagement>();
103 m_presenceService = m_scene.RequestModuleInterface<IPresenceService>();
102 104
103 if (m_friendsModule != null && m_userManagementModule != null) 105 if (m_friendsModule != null && m_userManagementModule != null && m_presenceService != null)
104 { 106 {
105 m_scene.AddCommand( 107 m_scene.AddCommand(
106 "Friends", this, "friends show", 108 "Friends", this, "friends show",
@@ -162,7 +164,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
162 164
163 MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId); 165 MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId);
164 166
165 MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags"); 167 MainConsole.Instance.OutputFormat(
168 "{0,-36} {1,-36} {2,-7} {3,7} {4,10}", "UUID", "Name", "Status", "MyFlags", "TheirFlags");
166 169
167 foreach (FriendInfo friend in friends) 170 foreach (FriendInfo friend in friends)
168 { 171 {
@@ -175,14 +178,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
175 178
176 UUID friendId; 179 UUID friendId;
177 string friendName; 180 string friendName;
181 string onlineText;
178 182
179 if (UUID.TryParse(friend.Friend, out friendId)) 183 if (UUID.TryParse(friend.Friend, out friendId))
180 friendName = m_userManagementModule.GetUserName(friendId); 184 friendName = m_userManagementModule.GetUserName(friendId);
181 else 185 else
182 friendName = friend.Friend; 186 friendName = friend.Friend;
183 187
188 OpenSim.Services.Interfaces.PresenceInfo[] pi = m_presenceService.GetAgents(new string[] { friend.Friend });
189 if (pi.Length > 0)
190 onlineText = "online";
191 else
192 onlineText = "offline";
193
184 MainConsole.Instance.OutputFormat( 194 MainConsole.Instance.OutputFormat(
185 "{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags); 195 "{0,-36} {1,-36} {2,-7} {3,-7} {4,-10}",
196 friend.Friend, friendName, onlineText, friend.MyFlags, friend.TheirFlags);
186 } 197 }
187 } 198 }
188 } 199 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 8af3652..6c53d95 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -306,30 +306,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
306 agentID, caps, scene.RegionInfo.RegionName); 306 agentID, caps, scene.RegionInfo.RegionName);
307 307
308 string capsBase = "/CAPS/" + caps.CapsObjectPath; 308 string capsBase = "/CAPS/" + caps.CapsObjectPath;
309 caps.RegisterHandler("ProvisionVoiceAccountRequest", 309 caps.RegisterHandler(
310 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, 310 "ProvisionVoiceAccountRequest",
311 delegate(string request, string path, string param, 311 new RestStreamHandler(
312 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 312 "POST",
313 { 313 capsBase + m_provisionVoiceAccountRequestPath,
314 return ProvisionVoiceAccountRequest(scene, request, path, param, 314 (request, path, param, httpRequest, httpResponse)
315 agentID, caps); 315 => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps),
316 })); 316 "ProvisionVoiceAccountRequest",
317 caps.RegisterHandler("ParcelVoiceInfoRequest", 317 agentID.ToString()));
318 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, 318
319 delegate(string request, string path, string param, 319 caps.RegisterHandler(
320 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 320 "ParcelVoiceInfoRequest",
321 { 321 new RestStreamHandler(
322 return ParcelVoiceInfoRequest(scene, request, path, param, 322 "POST",
323 agentID, caps); 323 capsBase + m_parcelVoiceInfoRequestPath,
324 })); 324 (request, path, param, httpRequest, httpResponse)
325 caps.RegisterHandler("ChatSessionRequest", 325 => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps),
326 new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, 326 "ParcelVoiceInfoRequest",
327 delegate(string request, string path, string param, 327 agentID.ToString()));
328 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 328
329 { 329 caps.RegisterHandler(
330 return ChatSessionRequest(scene, request, path, param, 330 "ChatSessionRequest",
331 agentID, caps); 331 new RestStreamHandler(
332 })); 332 "POST",
333 capsBase + m_chatSessionRequestPath,
334 (request, path, param, httpRequest, httpResponse)
335 => ChatSessionRequest(scene, request, path, param, agentID, caps),
336 "ChatSessionRequest",
337 agentID.ToString()));
333 } 338 }
334 339
335 /// <summary> 340 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index 4dbac1d..396d4c5 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -406,30 +406,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
406 m_log.DebugFormat("[VivoxVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); 406 m_log.DebugFormat("[VivoxVoice] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
407 407
408 string capsBase = "/CAPS/" + caps.CapsObjectPath; 408 string capsBase = "/CAPS/" + caps.CapsObjectPath;
409 caps.RegisterHandler("ProvisionVoiceAccountRequest", 409
410 new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, 410 caps.RegisterHandler(
411 delegate(string request, string path, string param, 411 "ProvisionVoiceAccountRequest",
412 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 412 new RestStreamHandler(
413 { 413 "POST",
414 return ProvisionVoiceAccountRequest(scene, request, path, param, 414 capsBase + m_provisionVoiceAccountRequestPath,
415 agentID, caps); 415 (request, path, param, httpRequest, httpResponse)
416 })); 416 => ProvisionVoiceAccountRequest(scene, request, path, param, agentID, caps),
417 caps.RegisterHandler("ParcelVoiceInfoRequest", 417 "ProvisionVoiceAccountRequest",
418 new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, 418 agentID.ToString()));
419 delegate(string request, string path, string param, 419
420 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 420 caps.RegisterHandler(
421 { 421 "ParcelVoiceInfoRequest",
422 return ParcelVoiceInfoRequest(scene, request, path, param, 422 new RestStreamHandler(
423 agentID, caps); 423 "POST",
424 })); 424 capsBase + m_parcelVoiceInfoRequestPath,
425 caps.RegisterHandler("ChatSessionRequest", 425 (request, path, param, httpRequest, httpResponse)
426 new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath, 426 => ParcelVoiceInfoRequest(scene, request, path, param, agentID, caps),
427 delegate(string request, string path, string param, 427 "ParcelVoiceInfoRequest",
428 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 428 agentID.ToString()));
429 { 429
430 return ChatSessionRequest(scene, request, path, param, 430 caps.RegisterHandler(
431 agentID, caps); 431 "ChatSessionRequest",
432 })); 432 new RestStreamHandler(
433 "POST",
434 capsBase + m_chatSessionRequestPath,
435 (request, path, param, httpRequest, httpResponse)
436 => ChatSessionRequest(scene, request, path, param, agentID, caps),
437 "ChatSessionRequest",
438 agentID.ToString()));
433 } 439 }
434 440
435 /// <summary> 441 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 130513d..5d57f70 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -1401,9 +1401,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1401 { 1401 {
1402 response = WebUtil.PostToService(m_groupsServerURI, requestArgs); 1402 response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1403 } 1403 }
1404 catch (Exception e) 1404 catch (Exception)
1405 { 1405 {
1406 m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey); 1406 m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey);
1407 } 1407 }
1408 1408
1409 // and cache the response 1409 // and cache the response
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index d2f6327..ac638f1 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
50 TestHelpers.InMethod(); 50 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure(); 51// log4net.Config.XmlConfigurator.Configure();
52 52
53 TestScene scene = SceneHelpers.SetupScene(); 53 TestScene scene = new SceneHelpers().SetupScene();
54 IConfigSource configSource = new IniConfigSource(); 54 IConfigSource configSource = new IniConfigSource();
55 IConfig config = configSource.AddConfig("Groups"); 55 IConfig config = configSource.AddConfig("Groups");
56 config.Set("Enabled", true); 56 config.Set("Enabled", true);
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
new file mode 100644
index 0000000..34894ba
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs
@@ -0,0 +1,500 @@
1/*
2 * Copyright (c) Contributors
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 OpenSim 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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46{
47 public class JsonStore
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private OSD m_ValueStore;
53
54 protected class TakeValueCallbackClass
55 {
56 public string Path { get; set; }
57 public bool UseJson { get; set; }
58 public TakeValueCallback Callback { get; set; }
59
60 public TakeValueCallbackClass(string spath, bool usejson, TakeValueCallback cback)
61 {
62 Path = spath;
63 UseJson = usejson;
64 Callback = cback;
65 }
66 }
67
68 protected List<TakeValueCallbackClass> m_TakeStore;
69 protected List<TakeValueCallbackClass> m_ReadStore;
70
71
72 // -----------------------------------------------------------------
73 /// <summary>
74 ///
75 /// </summary>
76 // -----------------------------------------------------------------
77 public JsonStore() : this("") {}
78
79 public JsonStore(string value)
80 {
81 m_TakeStore = new List<TakeValueCallbackClass>();
82 m_ReadStore = new List<TakeValueCallbackClass>();
83
84 if (String.IsNullOrEmpty(value))
85 m_ValueStore = new OSDMap();
86 else
87 m_ValueStore = OSDParser.DeserializeJson(value);
88 }
89
90 // -----------------------------------------------------------------
91 /// <summary>
92 ///
93 /// </summary>
94 // -----------------------------------------------------------------
95 public bool TestPath(string expr, bool useJson)
96 {
97 Stack<string> path = ParsePathExpression(expr);
98 OSD result = ProcessPathExpression(m_ValueStore,path);
99
100 if (result == null)
101 return false;
102
103 if (useJson || result.Type == OSDType.String)
104 return true;
105
106 return false;
107 }
108
109 // -----------------------------------------------------------------
110 /// <summary>
111 ///
112 /// </summary>
113 // -----------------------------------------------------------------
114 public bool GetValue(string expr, out string value, bool useJson)
115 {
116 Stack<string> path = ParsePathExpression(expr);
117 OSD result = ProcessPathExpression(m_ValueStore,path);
118 return ConvertOutputValue(result,out value,useJson);
119 }
120
121
122 // -----------------------------------------------------------------
123 /// <summary>
124 ///
125 /// </summary>
126 // -----------------------------------------------------------------
127 public bool RemoveValue(string expr)
128 {
129 return SetValueFromExpression(expr,null);
130 }
131
132 // -----------------------------------------------------------------
133 /// <summary>
134 ///
135 /// </summary>
136 // -----------------------------------------------------------------
137 public bool SetValue(string expr, string value, bool useJson)
138 {
139 OSD ovalue = useJson ? OSDParser.DeserializeJson(value) : new OSDString(value);
140 return SetValueFromExpression(expr,ovalue);
141 }
142
143 // -----------------------------------------------------------------
144 /// <summary>
145 ///
146 /// </summary>
147 // -----------------------------------------------------------------
148 public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
149 {
150 Stack<string> path = ParsePathExpression(expr);
151 string pexpr = PathExpressionToKey(path);
152
153 OSD result = ProcessPathExpression(m_ValueStore,path);
154 if (result == null)
155 {
156 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
157 return false;
158 }
159
160 string value = String.Empty;
161 if (! ConvertOutputValue(result,out value,useJson))
162 {
163 // the structure does not match the request so i guess we'll wait
164 m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
165 return false;
166 }
167
168 SetValueFromExpression(expr,null);
169 cback(value);
170
171 return true;
172 }
173
174 // -----------------------------------------------------------------
175 /// <summary>
176 ///
177 /// </summary>
178 // -----------------------------------------------------------------
179 public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
180 {
181 Stack<string> path = ParsePathExpression(expr);
182 string pexpr = PathExpressionToKey(path);
183
184 OSD result = ProcessPathExpression(m_ValueStore,path);
185 if (result == null)
186 {
187 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
188 return false;
189 }
190
191 string value = String.Empty;
192 if (! ConvertOutputValue(result,out value,useJson))
193 {
194 // the structure does not match the request so i guess we'll wait
195 m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback));
196 return false;
197 }
198
199 cback(value);
200
201 return true;
202 }
203
204 // -----------------------------------------------------------------
205 /// <summary>
206 ///
207 /// </summary>
208 // -----------------------------------------------------------------
209 protected bool SetValueFromExpression(string expr, OSD ovalue)
210 {
211 Stack<string> path = ParsePathExpression(expr);
212 if (path.Count == 0)
213 {
214 m_ValueStore = ovalue;
215 return true;
216 }
217
218 string pkey = path.Pop();
219 string pexpr = PathExpressionToKey(path);
220 if (pexpr != "")
221 pexpr += ".";
222
223 OSD result = ProcessPathExpression(m_ValueStore,path);
224 if (result == null)
225 return false;
226
227 Regex aPattern = new Regex("\\[([0-9]+|\\+)\\]");
228 MatchCollection amatches = aPattern.Matches(pkey,0);
229
230 if (amatches.Count > 0)
231 {
232 if (result.Type != OSDType.Array)
233 return false;
234
235 OSDArray amap = result as OSDArray;
236
237 Match match = amatches[0];
238 GroupCollection groups = match.Groups;
239 string akey = groups[1].Value;
240
241 if (akey == "+")
242 {
243 string npkey = String.Format("[{0}]",amap.Count);
244
245 amap.Add(ovalue);
246 InvokeNextCallback(pexpr + npkey);
247 return true;
248 }
249
250 int aval = Convert.ToInt32(akey);
251 if (0 <= aval && aval < amap.Count)
252 {
253 if (ovalue == null)
254 amap.RemoveAt(aval);
255 else
256 {
257 amap[aval] = ovalue;
258 InvokeNextCallback(pexpr + pkey);
259 }
260 return true;
261 }
262
263 return false;
264 }
265
266 Regex hPattern = new Regex("{([^}]+)}");
267 MatchCollection hmatches = hPattern.Matches(pkey,0);
268
269 if (hmatches.Count > 0)
270 {
271 Match match = hmatches[0];
272 GroupCollection groups = match.Groups;
273 string hkey = groups[1].Value;
274
275 if (result is OSDMap)
276 {
277 OSDMap hmap = result as OSDMap;
278 if (ovalue != null)
279 {
280 hmap[hkey] = ovalue;
281 InvokeNextCallback(pexpr + pkey);
282 }
283 else if (hmap.ContainsKey(hkey))
284 hmap.Remove(hkey);
285
286 return true;
287 }
288
289 return false;
290 }
291
292 // Shouldn't get here if the path was checked correctly
293 m_log.WarnFormat("[JsonStore] invalid path expression");
294 return false;
295 }
296
297 // -----------------------------------------------------------------
298 /// <summary>
299 ///
300 /// </summary>
301 // -----------------------------------------------------------------
302 protected bool InvokeNextCallback(string pexpr)
303 {
304 // Process all of the reads that match the expression first
305 List<TakeValueCallbackClass> reads =
306 m_ReadStore.FindAll(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
307
308 foreach (TakeValueCallbackClass readcb in reads)
309 {
310 m_ReadStore.Remove(readcb);
311 ReadValue(readcb.Path,readcb.UseJson,readcb.Callback);
312 }
313
314 // Process one take next
315 TakeValueCallbackClass takecb =
316 m_TakeStore.Find(delegate(TakeValueCallbackClass tb) { return pexpr.StartsWith(tb.Path); });
317
318 if (takecb != null)
319 {
320 m_TakeStore.Remove(takecb);
321 TakeValue(takecb.Path,takecb.UseJson,takecb.Callback);
322
323 return true;
324 }
325
326 return false;
327 }
328
329 // -----------------------------------------------------------------
330 /// <summary>
331 /// Parse the path expression and put the components into a stack. We
332 /// use a stack because we process the path in inverse order later
333 /// </summary>
334 // -----------------------------------------------------------------
335 protected static Stack<string> ParsePathExpression(string path)
336 {
337 Stack<string> m_path = new Stack<string>();
338
339 // add front and rear separators
340 path = "." + path + ".";
341
342 // add separators for quoted paths
343 Regex pass1 = new Regex("{[^}]+}");
344 path = pass1.Replace(path,".$0.",-1,0);
345
346 // add separators for array references
347 Regex pass2 = new Regex("(\\[[0-9]+\\]|\\[\\+\\])");
348 path = pass2.Replace(path,".$0.",-1,0);
349
350 // add quotes to bare identifier
351 Regex pass3 = new Regex("\\.([a-zA-Z]+)");
352 path = pass3.Replace(path,".{$1}",-1,0);
353
354 // remove extra separators
355 Regex pass4 = new Regex("\\.+");
356 path = pass4.Replace(path,".",-1,0);
357
358 Regex validate = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$");
359 if (validate.IsMatch(path))
360 {
361 Regex parser = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)");
362 MatchCollection matches = parser.Matches(path,0);
363 foreach (Match match in matches)
364 m_path.Push(match.Groups[1].Value);
365 }
366
367 return m_path;
368 }
369
370 // -----------------------------------------------------------------
371 /// <summary>
372 ///
373 /// </summary>
374 /// <param>path is a stack where the top level of the path is at the bottom of the stack</param>
375 // -----------------------------------------------------------------
376 protected static OSD ProcessPathExpression(OSD map, Stack<string> path)
377 {
378 if (path.Count == 0)
379 return map;
380
381 string pkey = path.Pop();
382
383 OSD rmap = ProcessPathExpression(map,path);
384 if (rmap == null)
385 return null;
386
387 // ---------- Check for an array index ----------
388 Regex aPattern = new Regex("\\[([0-9]+)\\]");
389 MatchCollection amatches = aPattern.Matches(pkey,0);
390
391 if (amatches.Count > 0)
392 {
393 if (rmap.Type != OSDType.Array)
394 {
395 m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Array,rmap.Type,pkey);
396 return null;
397 }
398
399 OSDArray amap = rmap as OSDArray;
400
401 Match match = amatches[0];
402 GroupCollection groups = match.Groups;
403 string akey = groups[1].Value;
404 int aval = Convert.ToInt32(akey);
405
406 if (aval < amap.Count)
407 return (OSD) amap[aval];
408
409 return null;
410 }
411
412 // ---------- Check for a hash index ----------
413 Regex hPattern = new Regex("{([^}]+)}");
414 MatchCollection hmatches = hPattern.Matches(pkey,0);
415
416 if (hmatches.Count > 0)
417 {
418 if (rmap.Type != OSDType.Map)
419 {
420 m_log.WarnFormat("[JsonStore] wrong type for key {2}, expecting {0}, got {1}",OSDType.Map,rmap.Type,pkey);
421 return null;
422 }
423
424 OSDMap hmap = rmap as OSDMap;
425
426 Match match = hmatches[0];
427 GroupCollection groups = match.Groups;
428 string hkey = groups[1].Value;
429
430 if (hmap.ContainsKey(hkey))
431 return (OSD) hmap[hkey];
432
433 return null;
434 }
435
436 // Shouldn't get here if the path was checked correctly
437 m_log.WarnFormat("[JsonStore] Path type (unknown) does not match the structure");
438 return null;
439 }
440
441 // -----------------------------------------------------------------
442 /// <summary>
443 ///
444 /// </summary>
445 // -----------------------------------------------------------------
446 protected static bool ConvertOutputValue(OSD result, out string value, bool useJson)
447 {
448 value = String.Empty;
449
450 // If we couldn't process the path
451 if (result == null)
452 return false;
453
454 if (useJson)
455 {
456 // The path pointed to an intermediate hash structure
457 if (result.Type == OSDType.Map)
458 {
459 value = OSDParser.SerializeJsonString(result as OSDMap);
460 return true;
461 }
462
463 // The path pointed to an intermediate hash structure
464 if (result.Type == OSDType.Array)
465 {
466 value = OSDParser.SerializeJsonString(result as OSDArray);
467 return true;
468 }
469
470 value = "'" + result.AsString() + "'";
471 return true;
472 }
473
474 if (result.Type == OSDType.String)
475 {
476 value = result.AsString();
477 return true;
478 }
479
480 return false;
481 }
482
483 // -----------------------------------------------------------------
484 /// <summary>
485 ///
486 /// </summary>
487 // -----------------------------------------------------------------
488 protected static string PathExpressionToKey(Stack<string> path)
489 {
490 if (path.Count == 0)
491 return "";
492
493 string pkey = "";
494 foreach (string k in path)
495 pkey = (pkey == "") ? k : (k + "." + pkey);
496
497 return pkey;
498 }
499 }
500}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
new file mode 100644
index 0000000..311531c
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -0,0 +1,430 @@
1/*
2 * Copyright (c) Contributors
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 OpenSim 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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45
46namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreModule")]
49
50 public class JsonStoreModule : INonSharedRegionModule, IJsonStoreModule
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private IConfig m_config = null;
56 private bool m_enabled = false;
57 private Scene m_scene = null;
58
59 private Dictionary<UUID,JsonStore> m_JsonValueStore;
60 private UUID m_sharedStore;
61
62#region IRegionModule Members
63
64 // -----------------------------------------------------------------
65 /// <summary>
66 /// Name of this shared module is it's class name
67 /// </summary>
68 // -----------------------------------------------------------------
69 public string Name
70 {
71 get { return this.GetType().Name; }
72 }
73
74 // -----------------------------------------------------------------
75 /// <summary>
76 /// Initialise this shared module
77 /// </summary>
78 /// <param name="scene">this region is getting initialised</param>
79 /// <param name="source">nini config, we are not using this</param>
80 // -----------------------------------------------------------------
81 public void Initialise(IConfigSource config)
82 {
83 try
84 {
85 if ((m_config = config.Configs["JsonStore"]) == null)
86 {
87 // There is no configuration, the module is disabled
88 // m_log.InfoFormat("[JsonStore] no configuration info");
89 return;
90 }
91
92 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
93 }
94 catch (Exception e)
95 {
96 m_log.ErrorFormat("[JsonStore] initialization error: {0}",e.Message);
97 return;
98 }
99
100 if (m_enabled)
101 m_log.DebugFormat("[JsonStore] module is enabled");
102 }
103
104 // -----------------------------------------------------------------
105 /// <summary>
106 /// everything is loaded, perform post load configuration
107 /// </summary>
108 // -----------------------------------------------------------------
109 public void PostInitialise()
110 {
111 }
112
113 // -----------------------------------------------------------------
114 /// <summary>
115 /// Nothing to do on close
116 /// </summary>
117 // -----------------------------------------------------------------
118 public void Close()
119 {
120 }
121
122 // -----------------------------------------------------------------
123 /// <summary>
124 /// </summary>
125 // -----------------------------------------------------------------
126 public void AddRegion(Scene scene)
127 {
128 if (m_enabled)
129 {
130 m_scene = scene;
131 m_scene.RegisterModuleInterface<IJsonStoreModule>(this);
132
133 m_sharedStore = UUID.Zero;
134 m_JsonValueStore = new Dictionary<UUID,JsonStore>();
135 m_JsonValueStore.Add(m_sharedStore,new JsonStore(""));
136 }
137 }
138
139 // -----------------------------------------------------------------
140 /// <summary>
141 /// </summary>
142 // -----------------------------------------------------------------
143 public void RemoveRegion(Scene scene)
144 {
145 // need to remove all references to the scene in the subscription
146 // list to enable full garbage collection of the scene object
147 }
148
149 // -----------------------------------------------------------------
150 /// <summary>
151 /// Called when all modules have been added for a region. This is
152 /// where we hook up events
153 /// </summary>
154 // -----------------------------------------------------------------
155 public void RegionLoaded(Scene scene)
156 {
157 if (m_enabled) {}
158 }
159
160 /// -----------------------------------------------------------------
161 /// <summary>
162 /// </summary>
163 // -----------------------------------------------------------------
164 public Type ReplaceableInterface
165 {
166 get { return null; }
167 }
168
169#endregion
170
171#region ScriptInvocationInteface
172
173 // -----------------------------------------------------------------
174 /// <summary>
175 ///
176 /// </summary>
177 // -----------------------------------------------------------------
178 public bool CreateStore(string value, out UUID result)
179 {
180 result = UUID.Zero;
181
182 if (! m_enabled) return false;
183
184 UUID uuid = UUID.Random();
185 JsonStore map = null;
186
187 try
188 {
189 map = new JsonStore(value);
190 }
191 catch (Exception e)
192 {
193 m_log.InfoFormat("[JsonStore] Unable to initialize store from {0}; {1}",value,e.Message);
194 return false;
195 }
196
197 lock (m_JsonValueStore)
198 m_JsonValueStore.Add(uuid,map);
199
200 result = uuid;
201 return true;
202 }
203
204 // -----------------------------------------------------------------
205 /// <summary>
206 ///
207 /// </summary>
208 // -----------------------------------------------------------------
209 public bool DestroyStore(UUID storeID)
210 {
211 if (! m_enabled) return false;
212
213 lock (m_JsonValueStore)
214 m_JsonValueStore.Remove(storeID);
215
216 return true;
217 }
218
219 // -----------------------------------------------------------------
220 /// <summary>
221 ///
222 /// </summary>
223 // -----------------------------------------------------------------
224 public bool TestPath(UUID storeID, string path, bool useJson)
225 {
226 if (! m_enabled) return false;
227
228 JsonStore map = null;
229 lock (m_JsonValueStore)
230 {
231 if (! m_JsonValueStore.TryGetValue(storeID,out map))
232 {
233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
234 return true;
235 }
236 }
237
238 try
239 {
240 lock (map)
241 return map.TestPath(path,useJson);
242 }
243 catch (Exception e)
244 {
245 m_log.InfoFormat("[JsonStore] Path test failed for {0} in {1}; {2}",path,storeID,e.Message);
246 }
247
248 return false;
249 }
250
251 // -----------------------------------------------------------------
252 /// <summary>
253 ///
254 /// </summary>
255 // -----------------------------------------------------------------
256 public bool SetValue(UUID storeID, string path, string value, bool useJson)
257 {
258 if (! m_enabled) return false;
259
260 JsonStore map = null;
261 lock (m_JsonValueStore)
262 {
263 if (! m_JsonValueStore.TryGetValue(storeID,out map))
264 {
265 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
266 return false;
267 }
268 }
269
270 try
271 {
272 lock (map)
273 if (map.SetValue(path,value,useJson))
274 return true;
275 }
276 catch (Exception e)
277 {
278 m_log.InfoFormat("[JsonStore] Unable to assign {0} to {1} in {2}; {3}",value,path,storeID,e.Message);
279 }
280
281 return false;
282 }
283
284 // -----------------------------------------------------------------
285 /// <summary>
286 ///
287 /// </summary>
288 // -----------------------------------------------------------------
289 public bool RemoveValue(UUID storeID, string path)
290 {
291 if (! m_enabled) return false;
292
293 JsonStore map = null;
294 lock (m_JsonValueStore)
295 {
296 if (! m_JsonValueStore.TryGetValue(storeID,out map))
297 {
298 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
299 return false;
300 }
301 }
302
303 try
304 {
305 lock (map)
306 if (map.RemoveValue(path))
307 return true;
308 }
309 catch (Exception e)
310 {
311 m_log.InfoFormat("[JsonStore] Unable to remove {0} in {1}; {2}",path,storeID,e.Message);
312 }
313
314 return false;
315 }
316
317 // -----------------------------------------------------------------
318 /// <summary>
319 ///
320 /// </summary>
321 // -----------------------------------------------------------------
322 public bool GetValue(UUID storeID, string path, bool useJson, out string value)
323 {
324 value = String.Empty;
325
326 if (! m_enabled) return false;
327
328 JsonStore map = null;
329 lock (m_JsonValueStore)
330 {
331 if (! m_JsonValueStore.TryGetValue(storeID,out map))
332 return false;
333 }
334
335 try
336 {
337 lock (map)
338 {
339 return map.GetValue(path, out value, useJson);
340 }
341 }
342 catch (Exception e)
343 {
344 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.Message);
345 }
346
347 return false;
348 }
349
350 // -----------------------------------------------------------------
351 /// <summary>
352 ///
353 /// </summary>
354 // -----------------------------------------------------------------
355 public void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
356 {
357 if (! m_enabled)
358 {
359 cback(String.Empty);
360 return;
361 }
362
363 JsonStore map = null;
364 lock (m_JsonValueStore)
365 {
366 if (! m_JsonValueStore.TryGetValue(storeID,out map))
367 {
368 cback(String.Empty);
369 return;
370 }
371 }
372
373 try
374 {
375 lock (map)
376 {
377 map.TakeValue(path, useJson, cback);
378 return;
379 }
380 }
381 catch (Exception e)
382 {
383 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
384 }
385
386 cback(String.Empty);
387 }
388
389 // -----------------------------------------------------------------
390 /// <summary>
391 ///
392 /// </summary>
393 // -----------------------------------------------------------------
394 public void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback)
395 {
396 if (! m_enabled)
397 {
398 cback(String.Empty);
399 return;
400 }
401
402 JsonStore map = null;
403 lock (m_JsonValueStore)
404 {
405 if (! m_JsonValueStore.TryGetValue(storeID,out map))
406 {
407 cback(String.Empty);
408 return;
409 }
410 }
411
412 try
413 {
414 lock (map)
415 {
416 map.ReadValue(path, useJson, cback);
417 return;
418 }
419 }
420 catch (Exception e)
421 {
422 m_log.InfoFormat("[JsonStore] unable to retrieve value; {0}",e.ToString());
423 }
424
425 cback(String.Empty);
426 }
427
428#endregion
429 }
430}
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
new file mode 100644
index 0000000..4949097
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -0,0 +1,499 @@
1/*
2 * Copyright (c) Contributors
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 OpenSim 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 */
27using Mono.Addins;
28
29using System;
30using System.Reflection;
31using System.Threading;
32using System.Text;
33using System.Net;
34using System.Net.Sockets;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using System.Collections.Generic;
43using System.Text.RegularExpressions;
44
45namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "JsonStoreScriptModule")]
48
49 public class JsonStoreScriptModule : INonSharedRegionModule
50 {
51 private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private IConfig m_config = null;
55 private bool m_enabled = false;
56 private Scene m_scene = null;
57
58 private IScriptModuleComms m_comms;
59 private IJsonStoreModule m_store;
60
61#region IRegionModule Members
62
63 // -----------------------------------------------------------------
64 /// <summary>
65 /// Name of this shared module is it's class name
66 /// </summary>
67 // -----------------------------------------------------------------
68 public string Name
69 {
70 get { return this.GetType().Name; }
71 }
72
73 // -----------------------------------------------------------------
74 /// <summary>
75 /// Initialise this shared module
76 /// </summary>
77 /// <param name="scene">this region is getting initialised</param>
78 /// <param name="source">nini config, we are not using this</param>
79 // -----------------------------------------------------------------
80 public void Initialise(IConfigSource config)
81 {
82 try
83 {
84 if ((m_config = config.Configs["JsonStore"]) == null)
85 {
86 // There is no configuration, the module is disabled
87 // m_log.InfoFormat("[JsonStoreScripts] no configuration info");
88 return;
89 }
90
91 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
92 }
93 catch (Exception e)
94 {
95 m_log.ErrorFormat("[JsonStoreScripts] initialization error: {0}",e.Message);
96 return;
97 }
98
99 if (m_enabled)
100 m_log.DebugFormat("[JsonStoreScripts] module is enabled");
101 }
102
103 // -----------------------------------------------------------------
104 /// <summary>
105 /// everything is loaded, perform post load configuration
106 /// </summary>
107 // -----------------------------------------------------------------
108 public void PostInitialise()
109 {
110 }
111
112 // -----------------------------------------------------------------
113 /// <summary>
114 /// Nothing to do on close
115 /// </summary>
116 // -----------------------------------------------------------------
117 public void Close()
118 {
119 }
120
121 // -----------------------------------------------------------------
122 /// <summary>
123 /// </summary>
124 // -----------------------------------------------------------------
125 public void AddRegion(Scene scene)
126 {
127 }
128
129 // -----------------------------------------------------------------
130 /// <summary>
131 /// </summary>
132 // -----------------------------------------------------------------
133 public void RemoveRegion(Scene scene)
134 {
135 // need to remove all references to the scene in the subscription
136 // list to enable full garbage collection of the scene object
137 }
138
139 // -----------------------------------------------------------------
140 /// <summary>
141 /// Called when all modules have been added for a region. This is
142 /// where we hook up events
143 /// </summary>
144 // -----------------------------------------------------------------
145 public void RegionLoaded(Scene scene)
146 {
147 if (m_enabled)
148 {
149 m_scene = scene;
150 m_comms = m_scene.RequestModuleInterface<IScriptModuleComms>();
151 if (m_comms == null)
152 {
153 m_log.ErrorFormat("[JsonStoreScripts] ScriptModuleComms interface not defined");
154 m_enabled = false;
155 return;
156 }
157
158 m_store = m_scene.RequestModuleInterface<IJsonStoreModule>();
159 if (m_store == null)
160 {
161 m_log.ErrorFormat("[JsonStoreScripts] JsonModule interface not defined");
162 m_enabled = false;
163 return;
164 }
165
166 try
167 {
168 m_comms.RegisterScriptInvocation(this,"JsonCreateStore");
169 m_comms.RegisterScriptInvocation(this,"JsonDestroyStore");
170
171 m_comms.RegisterScriptInvocation(this,"JsonReadNotecard");
172 m_comms.RegisterScriptInvocation(this,"JsonWriteNotecard");
173
174 m_comms.RegisterScriptInvocation(this,"JsonTestPath");
175 m_comms.RegisterScriptInvocation(this,"JsonTestPathJson");
176
177 m_comms.RegisterScriptInvocation(this,"JsonGetValue");
178 m_comms.RegisterScriptInvocation(this,"JsonGetValueJson");
179
180 m_comms.RegisterScriptInvocation(this,"JsonTakeValue");
181 m_comms.RegisterScriptInvocation(this,"JsonTakeValueJson");
182
183 m_comms.RegisterScriptInvocation(this,"JsonReadValue");
184 m_comms.RegisterScriptInvocation(this,"JsonReadValueJson");
185
186 m_comms.RegisterScriptInvocation(this,"JsonSetValue");
187 m_comms.RegisterScriptInvocation(this,"JsonSetValueJson");
188
189 m_comms.RegisterScriptInvocation(this,"JsonRemoveValue");
190 }
191 catch (Exception e)
192 {
193 // See http://opensimulator.org/mantis/view.php?id=5971 for more information
194 m_log.WarnFormat("[JsonStroreScripts] script method registration failed; {0}",e.Message);
195 m_enabled = false;
196 }
197 }
198 }
199
200 /// -----------------------------------------------------------------
201 /// <summary>
202 /// </summary>
203 // -----------------------------------------------------------------
204 public Type ReplaceableInterface
205 {
206 get { return null; }
207 }
208
209#endregion
210
211#region ScriptInvocationInteface
212 // -----------------------------------------------------------------
213 /// <summary>
214 ///
215 /// </summary>
216 // -----------------------------------------------------------------
217 protected void GenerateRuntimeError(string msg)
218 {
219 throw new Exception("JsonStore Runtime Error: " + msg);
220 }
221
222 // -----------------------------------------------------------------
223 /// <summary>
224 ///
225 /// </summary>
226 // -----------------------------------------------------------------
227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
228 {
229 UUID uuid = UUID.Zero;
230 if (! m_store.CreateStore(value, out uuid))
231 GenerateRuntimeError("Failed to create Json store");
232
233 return uuid;
234 }
235
236 // -----------------------------------------------------------------
237 /// <summary>
238 ///
239 /// </summary>
240 // -----------------------------------------------------------------
241 protected int JsonDestroyStore(UUID hostID, UUID scriptID, UUID storeID)
242 {
243 return m_store.DestroyStore(storeID) ? 1 : 0;
244 }
245
246 // -----------------------------------------------------------------
247 /// <summary>
248 ///
249 /// </summary>
250 // -----------------------------------------------------------------
251 protected UUID JsonReadNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
252 {
253 UUID reqID = UUID.Random();
254 Util.FireAndForget(delegate(object o) { DoJsonReadNotecard(reqID,hostID,scriptID,storeID,path,assetID); });
255 return reqID;
256 }
257
258 // -----------------------------------------------------------------
259 /// <summary>
260 ///
261 /// </summary>
262 // -----------------------------------------------------------------
263 protected UUID JsonWriteNotecard(UUID hostID, UUID scriptID, UUID storeID, string path, string name)
264 {
265 UUID reqID = UUID.Random();
266 Util.FireAndForget(delegate(object o) { DoJsonWriteNotecard(reqID,hostID,scriptID,storeID,path,name); });
267 return reqID;
268 }
269
270 // -----------------------------------------------------------------
271 /// <summary>
272 ///
273 /// </summary>
274 // -----------------------------------------------------------------
275 protected int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
276 {
277 return m_store.TestPath(storeID,path,false) ? 1 : 0;
278 }
279
280 protected int JsonTestPathJson(UUID hostID, UUID scriptID, UUID storeID, string path)
281 {
282 return m_store.TestPath(storeID,path,true) ? 1 : 0;
283 }
284
285 // -----------------------------------------------------------------
286 /// <summary>
287 ///
288 /// </summary>
289 // -----------------------------------------------------------------
290 protected int JsonSetValue(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
291 {
292 return m_store.SetValue(storeID,path,value,false) ? 1 : 0;
293 }
294
295 protected int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
296 {
297 return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
298 }
299
300 // -----------------------------------------------------------------
301 /// <summary>
302 ///
303 /// </summary>
304 // -----------------------------------------------------------------
305 protected int JsonRemoveValue(UUID hostID, UUID scriptID, UUID storeID, string path)
306 {
307 return m_store.RemoveValue(storeID,path) ? 1 : 0;
308 }
309
310 // -----------------------------------------------------------------
311 /// <summary>
312 ///
313 /// </summary>
314 // -----------------------------------------------------------------
315 protected string JsonGetValue(UUID hostID, UUID scriptID, UUID storeID, string path)
316 {
317 string value = String.Empty;
318 m_store.GetValue(storeID,path,false,out value);
319 return value;
320 }
321
322 protected string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
323 {
324 string value = String.Empty;
325 m_store.GetValue(storeID,path,true, out value);
326 return value;
327 }
328
329 // -----------------------------------------------------------------
330 /// <summary>
331 ///
332 /// </summary>
333 // -----------------------------------------------------------------
334 protected UUID JsonTakeValue(UUID hostID, UUID scriptID, UUID storeID, string path)
335 {
336 UUID reqID = UUID.Random();
337 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,false); });
338 return reqID;
339 }
340
341 protected UUID JsonTakeValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
342 {
343 UUID reqID = UUID.Random();
344 Util.FireAndForget(delegate(object o) { DoJsonTakeValue(scriptID,reqID,storeID,path,true); });
345 return reqID;
346 }
347
348 private void DoJsonTakeValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
349 {
350 try
351 {
352 m_store.TakeValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
353 return;
354 }
355 catch (Exception e)
356 {
357 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString());
358 }
359
360 DispatchValue(scriptID,reqID,String.Empty);
361 }
362
363
364 // -----------------------------------------------------------------
365 /// <summary>
366 ///
367 /// </summary>
368 // -----------------------------------------------------------------
369 protected UUID JsonReadValue(UUID hostID, UUID scriptID, UUID storeID, string path)
370 {
371 UUID reqID = UUID.Random();
372 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,false); });
373 return reqID;
374 }
375
376 protected UUID JsonReadValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
377 {
378 UUID reqID = UUID.Random();
379 Util.FireAndForget(delegate(object o) { DoJsonReadValue(scriptID,reqID,storeID,path,true); });
380 return reqID;
381 }
382
383 private void DoJsonReadValue(UUID scriptID, UUID reqID, UUID storeID, string path, bool useJson)
384 {
385 try
386 {
387 m_store.ReadValue(storeID,path,useJson,delegate(string value) { DispatchValue(scriptID,reqID,value); });
388 return;
389 }
390 catch (Exception e)
391 {
392 m_log.InfoFormat("[JsonStoreScripts] unable to retrieve value; {0}",e.ToString());
393 }
394
395 DispatchValue(scriptID,reqID,String.Empty);
396 }
397
398#endregion
399
400 // -----------------------------------------------------------------
401 /// <summary>
402 ///
403 /// </summary>
404 // -----------------------------------------------------------------
405 protected void DispatchValue(UUID scriptID, UUID reqID, string value)
406 {
407 m_comms.DispatchReply(scriptID,1,value,reqID.ToString());
408 }
409
410 // -----------------------------------------------------------------
411 /// <summary>
412 ///
413 /// </summary>
414 // -----------------------------------------------------------------
415 private void DoJsonReadNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, UUID assetID)
416 {
417 AssetBase a = m_scene.AssetService.Get(assetID.ToString());
418 if (a == null)
419 GenerateRuntimeError(String.Format("Unable to find notecard asset {0}",assetID));
420
421 if (a.Type != (sbyte)AssetType.Notecard)
422 GenerateRuntimeError(String.Format("Invalid notecard asset {0}",assetID));
423
424 m_log.DebugFormat("[JsonStoreScripts] read notecard in context {0}",storeID);
425
426 try
427 {
428 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
429 string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data));
430 int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0;
431 m_comms.DispatchReply(scriptID,result,"",reqID.ToString());
432 return;
433 }
434 catch (Exception e)
435 {
436 m_log.WarnFormat("[JsonStoreScripts] Json parsing failed; {0}",e.Message);
437 }
438
439 GenerateRuntimeError(String.Format("Json parsing failed for {0}",assetID.ToString()));
440 m_comms.DispatchReply(scriptID,0,"",reqID.ToString());
441 }
442
443 // -----------------------------------------------------------------
444 /// <summary>
445 ///
446 /// </summary>
447 // -----------------------------------------------------------------
448 private void DoJsonWriteNotecard(UUID reqID, UUID hostID, UUID scriptID, UUID storeID, string path, string name)
449 {
450 string data;
451 if (! m_store.GetValue(storeID,path,true, out data))
452 {
453 m_comms.DispatchReply(scriptID,0,UUID.Zero.ToString(),reqID.ToString());
454 return;
455 }
456
457 SceneObjectPart host = m_scene.GetSceneObjectPart(hostID);
458
459 // Create new asset
460 UUID assetID = UUID.Random();
461 AssetBase asset = new AssetBase(assetID, name, (sbyte)AssetType.Notecard, host.OwnerID.ToString());
462 asset.Description = "Json store";
463
464 int textLength = data.Length;
465 data = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
466 + textLength.ToString() + "\n" + data + "}\n";
467
468 asset.Data = Util.UTF8.GetBytes(data);
469 m_scene.AssetService.Store(asset);
470
471 // Create Task Entry
472 TaskInventoryItem taskItem = new TaskInventoryItem();
473
474 taskItem.ResetIDs(host.UUID);
475 taskItem.ParentID = host.UUID;
476 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
477 taskItem.Name = asset.Name;
478 taskItem.Description = asset.Description;
479 taskItem.Type = (int)AssetType.Notecard;
480 taskItem.InvType = (int)InventoryType.Notecard;
481 taskItem.OwnerID = host.OwnerID;
482 taskItem.CreatorID = host.OwnerID;
483 taskItem.BasePermissions = (uint)PermissionMask.All;
484 taskItem.CurrentPermissions = (uint)PermissionMask.All;
485 taskItem.EveryonePermissions = 0;
486 taskItem.NextPermissions = (uint)PermissionMask.All;
487 taskItem.GroupID = host.GroupID;
488 taskItem.GroupPermissions = 0;
489 taskItem.Flags = 0;
490 taskItem.PermsGranter = UUID.Zero;
491 taskItem.PermsMask = 0;
492 taskItem.AssetID = asset.FullID;
493
494 host.Inventory.AddInventoryItem(taskItem, false);
495
496 m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString());
497 }
498 }
499}
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
index 922eaaf..d192309 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
68 public Vector3 WorldPosition 68 public Vector3 WorldPosition
69 { 69 {
70 get { return GetSP().AbsolutePosition; } 70 get { return GetSP().AbsolutePosition; }
71 set { GetSP().TeleportWithMomentum(value); } 71 set { GetSP().Teleport(value); }
72 } 72 }
73 73
74 public bool IsChildAgent 74 public bool IsChildAgent
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index cab30de..74a85e2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -38,7 +38,7 @@ using OpenMetaverse;
38using System.Linq; 38using System.Linq;
39using System.Linq.Expressions; 39using System.Linq.Expressions;
40 40
41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
42{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms 44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 8996865..e798382 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -76,22 +76,27 @@ namespace OpenSim.Region.OptionalModules.World.NPC
76 76
77 public void Say(string message) 77 public void Say(string message)
78 { 78 {
79 SendOnChatFromClient(message, ChatTypeEnum.Say); 79 SendOnChatFromClient(0, message, ChatTypeEnum.Say);
80 } 80 }
81 81
82 public void Shout(string message) 82 public void Say(int channel, string message)
83 { 83 {
84 SendOnChatFromClient(message, ChatTypeEnum.Shout); 84 SendOnChatFromClient(channel, message, ChatTypeEnum.Say);
85 } 85 }
86 86
87 public void Whisper(string message) 87 public void Shout(int channel, string message)
88 { 88 {
89 SendOnChatFromClient(message, ChatTypeEnum.Whisper); 89 SendOnChatFromClient(channel, message, ChatTypeEnum.Shout);
90 }
91
92 public void Whisper(int channel, string message)
93 {
94 SendOnChatFromClient(channel, message, ChatTypeEnum.Whisper);
90 } 95 }
91 96
92 public void Broadcast(string message) 97 public void Broadcast(string message)
93 { 98 {
94 SendOnChatFromClient(message, ChatTypeEnum.Broadcast); 99 SendOnChatFromClient(0, message, ChatTypeEnum.Broadcast);
95 } 100 }
96 101
97 public void GiveMoney(UUID target, int amount) 102 public void GiveMoney(UUID target, int amount)
@@ -146,10 +151,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
146 151
147 #region Internal Functions 152 #region Internal Functions
148 153
149 private void SendOnChatFromClient(string message, ChatTypeEnum chatType) 154 private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType)
150 { 155 {
151 OSChatMessage chatFromClient = new OSChatMessage(); 156 OSChatMessage chatFromClient = new OSChatMessage();
152 chatFromClient.Channel = 0; 157 chatFromClient.Channel = channel;
153 chatFromClient.From = Name; 158 chatFromClient.From = Name;
154 chatFromClient.Message = message; 159 chatFromClient.Message = message;
155 chatFromClient.Position = StartPos; 160 chatFromClient.Position = StartPos;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index ebf5e84..a32ab2a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -155,18 +155,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
155 ScenePresence sp; 155 ScenePresence sp;
156 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp)) 156 if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
157 { 157 {
158 m_log.DebugFormat(
159 "[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
160
161 sp.CompleteMovement(npcAvatar, false); 158 sp.CompleteMovement(npcAvatar, false);
162 m_avatars.Add(npcAvatar.AgentId, npcAvatar); 159 m_avatars.Add(npcAvatar.AgentId, npcAvatar);
160 m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name);
163 } 161 }
164 else
165 {
166 m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
167 npcAvatar.AgentId = UUID.Zero;
168 }
169
170 } 162 }
171 ev.Set(); 163 ev.Set();
172 }); 164 });
@@ -178,7 +170,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
178 return npcAvatar.AgentId; 170 return npcAvatar.AgentId;
179 } 171 }
180 172
181 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget) 173 public bool MoveToTarget(UUID agentID, Scene scene, Vector3 pos, bool noFly, bool landAtTarget, bool running)
182 { 174 {
183 lock (m_avatars) 175 lock (m_avatars)
184 { 176 {
@@ -192,6 +184,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
192 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget); 184 sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
193 185
194 sp.MoveToTarget(pos, noFly, landAtTarget); 186 sp.MoveToTarget(pos, noFly, landAtTarget);
187 sp.SetAlwaysRun = running;
195 188
196 return true; 189 return true;
197 } 190 }
@@ -221,6 +214,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
221 214
222 public bool Say(UUID agentID, Scene scene, string text) 215 public bool Say(UUID agentID, Scene scene, string text)
223 { 216 {
217 return Say(agentID, scene, text, 0);
218 }
219
220 public bool Say(UUID agentID, Scene scene, string text, int channel)
221 {
224 lock (m_avatars) 222 lock (m_avatars)
225 { 223 {
226 if (m_avatars.ContainsKey(agentID)) 224 if (m_avatars.ContainsKey(agentID))
@@ -228,7 +226,25 @@ namespace OpenSim.Region.OptionalModules.World.NPC
228 ScenePresence sp; 226 ScenePresence sp;
229 scene.TryGetScenePresence(agentID, out sp); 227 scene.TryGetScenePresence(agentID, out sp);
230 228
231 m_avatars[agentID].Say(text); 229 m_avatars[agentID].Say(channel, text);
230
231 return true;
232 }
233 }
234
235 return false;
236 }
237
238 public bool Shout(UUID agentID, Scene scene, string text, int channel)
239 {
240 lock (m_avatars)
241 {
242 if (m_avatars.ContainsKey(agentID))
243 {
244 ScenePresence sp;
245 scene.TryGetScenePresence(agentID, out sp);
246
247 m_avatars[agentID].Shout(channel, text);
232 248
233 return true; 249 return true;
234 } 250 }
@@ -255,6 +271,24 @@ namespace OpenSim.Region.OptionalModules.World.NPC
255 return false; 271 return false;
256 } 272 }
257 273
274 public bool Whisper(UUID agentID, Scene scene, string text, int channel)
275 {
276 lock (m_avatars)
277 {
278 if (m_avatars.ContainsKey(agentID))
279 {
280 ScenePresence sp;
281 scene.TryGetScenePresence(agentID, out sp);
282
283 m_avatars[agentID].Whisper(channel, text);
284
285 return true;
286 }
287 }
288
289 return false;
290 }
291
258 public bool Stand(UUID agentID, Scene scene) 292 public bool Stand(UUID agentID, Scene scene)
259 { 293 {
260 lock (m_avatars) 294 lock (m_avatars)
@@ -308,7 +342,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
308 scene.RemoveClient(agentID, false); 342 scene.RemoveClient(agentID, false);
309 m_avatars.Remove(agentID); 343 m_avatars.Remove(agentID);
310 344
311// m_log.DebugFormat("[NPC MODULE]: Removed {0} {1}", agentID, av.Name); 345 m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name);
312 return true; 346 return true;
313 } 347 }
314 } 348 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index eea0b2e..65dad2d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
85 m_attMod = new AttachmentsModule(); 85 m_attMod = new AttachmentsModule();
86 m_npcMod = new NPCModule(); 86 m_npcMod = new NPCModule();
87 87
88 m_scene = SceneHelpers.SetupScene(); 88 m_scene = new SceneHelpers().SetupScene();
89 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule()); 89 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule());
90 } 90 }
91 91
@@ -242,7 +242,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
242 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 242 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
243 243
244 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 244 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
245 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false); 245 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
246 246
247 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 247 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
248 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f))); 248 //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f)));
@@ -267,7 +267,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
267 // Try a second movement 267 // Try a second movement
268 startPos = npc.AbsolutePosition; 268 startPos = npc.AbsolutePosition;
269 targetPos = startPos + new Vector3(10, 0, 0); 269 targetPos = startPos + new Vector3(10, 0, 0);
270 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false); 270 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false, false);
271 271
272 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 272 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
273// Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1))); 273// Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1)));
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
index b1a3ff9..e43136a 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs
@@ -36,13 +36,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
36{ 36{
37 public class BasicActor : PhysicsActor 37 public class BasicActor : PhysicsActor
38 { 38 {
39 private Vector3 _position;
40 private Vector3 _velocity;
41 private Vector3 _acceleration;
42 private Vector3 _size; 39 private Vector3 _size;
43 private Vector3 m_rotationalVelocity;
44 private bool flying;
45 private bool iscolliding;
46 40
47 public BasicActor(Vector3 size) 41 public BasicActor(Vector3 size)
48 { 42 {
@@ -55,11 +49,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
55 set { return; } 49 set { return; }
56 } 50 }
57 51
58 public override Vector3 RotationalVelocity 52 public override Vector3 RotationalVelocity { get; set; }
59 {
60 get { return m_rotationalVelocity; }
61 set { m_rotationalVelocity = value; }
62 }
63 53
64 public override bool SetAlwaysRun 54 public override bool SetAlwaysRun
65 { 55 {
@@ -105,17 +95,9 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
105 set { return; } 95 set { return; }
106 } 96 }
107 97
108 public override bool Flying 98 public override bool Flying { get; set; }
109 {
110 get { return flying; }
111 set { flying = value; }
112 }
113 99
114 public override bool IsColliding 100 public override bool IsColliding { get; set; }
115 {
116 get { return iscolliding; }
117 set { iscolliding = value; }
118 }
119 101
120 public override bool CollidingGround 102 public override bool CollidingGround
121 { 103 {
@@ -134,11 +116,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
134 get { return false; } 116 get { return false; }
135 } 117 }
136 118
137 public override Vector3 Position 119 public override Vector3 Position { get; set; }
138 {
139 get { return _position; }
140 set { _position = value; }
141 }
142 120
143 public override Vector3 Size 121 public override Vector3 Size
144 { 122 {
@@ -206,11 +184,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
206 get { return Vector3.Zero; } 184 get { return Vector3.Zero; }
207 } 185 }
208 186
209 public override Vector3 Velocity 187 public override Vector3 Velocity { get; set; }
210 {
211 get { return _velocity; }
212 set { _velocity = value; }
213 }
214 188
215 public override Vector3 Torque 189 public override Vector3 Torque
216 { 190 {
@@ -230,11 +204,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
230 set { } 204 set { }
231 } 205 }
232 206
233 public override Vector3 Acceleration 207 public override Vector3 Acceleration { get; set; }
234 {
235 get { return _acceleration; }
236 set { _acceleration = value; }
237 }
238 208
239 public override bool Kinematic 209 public override bool Kinematic
240 { 210 {
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs
new file mode 100644
index 0000000..b89eeed
--- /dev/null
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPrim.cs
@@ -0,0 +1,314 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using Nini.Config;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BasicPhysicsPlugin
36{
37 public class BasicPhysicsPrim : PhysicsActor
38 {
39 private Vector3 _size;
40 private PrimitiveBaseShape _shape;
41
42 public BasicPhysicsPrim(
43 string name, uint localId, Vector3 position, Vector3 size, Quaternion orientation, PrimitiveBaseShape shape)
44 {
45 Name = name;
46 LocalID = localId;
47 Position = position;
48 Size = size;
49 Orientation = orientation;
50 Shape = shape;
51 }
52
53 public override int PhysicsActorType
54 {
55 get { return (int) ActorTypes.Agent; }
56 set { return; }
57 }
58
59 public override Vector3 RotationalVelocity { get; set; }
60
61 public override bool SetAlwaysRun
62 {
63 get { return false; }
64 set { return; }
65 }
66
67 public override uint LocalID
68 {
69 set { return; }
70 }
71
72 public override bool Grabbed
73 {
74 set { return; }
75 }
76
77 public override bool Selected
78 {
79 set { return; }
80 }
81
82 public override float Buoyancy
83 {
84 get { return 0f; }
85 set { return; }
86 }
87
88 public override bool FloatOnWater
89 {
90 set { return; }
91 }
92
93 public override bool IsPhysical
94 {
95 get { return false; }
96 set { return; }
97 }
98
99 public override bool ThrottleUpdates
100 {
101 get { return false; }
102 set { return; }
103 }
104
105 public override bool Flying { get; set; }
106
107 public override bool IsColliding { get; set; }
108
109 public override bool CollidingGround
110 {
111 get { return false; }
112 set { return; }
113 }
114
115 public override bool CollidingObj
116 {
117 get { return false; }
118 set { return; }
119 }
120
121 public override bool Stopped
122 {
123 get { return false; }
124 }
125
126 public override Vector3 Position { get; set; }
127
128 public override Vector3 Size
129 {
130 get { return _size; }
131 set {
132 _size = value;
133 _size.Z = _size.Z / 2.0f;
134 }
135 }
136
137 public override PrimitiveBaseShape Shape
138 {
139 set { _shape = value; }
140 }
141
142 public override float Mass
143 {
144 get { return 0f; }
145 }
146
147 public override Vector3 Force
148 {
149 get { return Vector3.Zero; }
150 set { return; }
151 }
152
153 public override int VehicleType
154 {
155 get { return 0; }
156 set { return; }
157 }
158
159 public override void VehicleFloatParam(int param, float value)
160 {
161
162 }
163
164 public override void VehicleVectorParam(int param, Vector3 value)
165 {
166
167 }
168
169 public override void VehicleRotationParam(int param, Quaternion rotation)
170 {
171
172 }
173
174 public override void VehicleFlags(int param, bool remove)
175 {
176
177 }
178
179 public override void SetVolumeDetect(int param)
180 {
181
182 }
183
184 public override Vector3 CenterOfMass
185 {
186 get { return Vector3.Zero; }
187 }
188
189 public override Vector3 GeometricCenter
190 {
191 get { return Vector3.Zero; }
192 }
193
194 public override Vector3 Velocity { get; set; }
195
196 public override Vector3 Torque
197 {
198 get { return Vector3.Zero; }
199 set { return; }
200 }
201
202 public override float CollisionScore
203 {
204 get { return 0f; }
205 set { }
206 }
207
208 public override Quaternion Orientation { get; set; }
209
210 public override Vector3 Acceleration { get; set; }
211
212 public override bool Kinematic
213 {
214 get { return true; }
215 set { }
216 }
217
218 public override void link(PhysicsActor obj)
219 {
220 }
221
222 public override void delink()
223 {
224 }
225
226 public override void LockAngularMotion(Vector3 axis)
227 {
228 }
229
230 public override void AddForce(Vector3 force, bool pushforce)
231 {
232 }
233
234 public override void AddAngularForce(Vector3 force, bool pushforce)
235 {
236 }
237
238 public override void SetMomentum(Vector3 momentum)
239 {
240 }
241
242 public override void CrossingFailure()
243 {
244 }
245
246 public override Vector3 PIDTarget
247 {
248 set { return; }
249 }
250
251 public override bool PIDActive
252 {
253 set { return; }
254 }
255
256 public override float PIDTau
257 {
258 set { return; }
259 }
260
261 public override float PIDHoverHeight
262 {
263 set { return; }
264 }
265
266 public override bool PIDHoverActive
267 {
268 set { return; }
269 }
270
271 public override PIDHoverType PIDHoverType
272 {
273 set { return; }
274 }
275
276 public override float PIDHoverTau
277 {
278 set { return; }
279 }
280
281 public override Quaternion APIDTarget
282 {
283 set { return; }
284 }
285
286 public override bool APIDActive
287 {
288 set { return; }
289 }
290
291 public override float APIDStrength
292 {
293 set { return; }
294 }
295
296 public override float APIDDamping
297 {
298 set { return; }
299 }
300
301 public override void SubscribeEvents(int ms)
302 {
303 }
304
305 public override void UnSubscribeEvents()
306 {
307 }
308
309 public override bool SubscribedEvents()
310 {
311 return false;
312 }
313 }
314}
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
index 2e14216..f5826ed 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs
@@ -34,9 +34,17 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BasicPhysicsPlugin 35namespace OpenSim.Region.Physics.BasicPhysicsPlugin
36{ 36{
37 /// <summary>
38 /// This is an incomplete extremely basic physics implementation
39 /// </summary>
40 /// <remarks>
41 /// Not useful for anything at the moment apart from some regression testing in other components where some form
42 /// of physics plugin is needed.
43 /// </remarks>
37 public class BasicScene : PhysicsScene 44 public class BasicScene : PhysicsScene
38 { 45 {
39 private List<BasicActor> _actors = new List<BasicActor>(); 46 private List<BasicActor> _actors = new List<BasicActor>();
47 private List<BasicPhysicsPrim> _prims = new List<BasicPhysicsPrim>();
40 private float[] _heightMap; 48 private float[] _heightMap;
41 49
42 //protected internal string sceneIdentifier; 50 //protected internal string sceneIdentifier;
@@ -50,10 +58,19 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
50 { 58 {
51 } 59 }
52 60
53 public override void Dispose() 61 public override void Dispose() {}
62
63 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
64 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
54 { 65 {
66 BasicPhysicsPrim prim = new BasicPhysicsPrim(primName, localid, position, size, rotation, pbs);
67 prim.IsPhysical = isPhysical;
68
69 _prims.Add(prim);
55 70
71 return prim;
56 } 72 }
73
57 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 74 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
58 { 75 {
59 BasicActor act = new BasicActor(size); 76 BasicActor act = new BasicActor(size);
@@ -63,30 +80,18 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
63 return act; 80 return act;
64 } 81 }
65 82
66 public override void RemovePrim(PhysicsActor prim) 83 public override void RemovePrim(PhysicsActor actor)
67 { 84 {
85 BasicPhysicsPrim prim = (BasicPhysicsPrim)actor;
86 if (_prims.Contains(prim))
87 _prims.Remove(prim);
68 } 88 }
69 89
70 public override void RemoveAvatar(PhysicsActor actor) 90 public override void RemoveAvatar(PhysicsActor actor)
71 { 91 {
72 BasicActor act = (BasicActor) actor; 92 BasicActor act = (BasicActor)actor;
73 if (_actors.Contains(act)) 93 if (_actors.Contains(act))
74 {
75 _actors.Remove(act); 94 _actors.Remove(act);
76 }
77 }
78
79/*
80 public override PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation)
81 {
82 return null;
83 }
84*/
85
86 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
87 Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
88 {
89 return null;
90 } 95 }
91 96
92 public override void AddPhysicsActorTaint(PhysicsActor prim) 97 public override void AddPhysicsActorTaint(PhysicsActor prim)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 8397eb4..54b69a2 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1261,14 +1261,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1261 { 1261 {
1262 m_requestedUpdateFrequency = ms; 1262 m_requestedUpdateFrequency = ms;
1263 m_eventsubscription = ms; 1263 m_eventsubscription = ms;
1264 CollisionEventsThisFrame.Clear(); 1264
1265 // Don't clear collision event reporting here. This is called directly from scene code and so can lead
1266 // to a race condition with the simulate loop
1267
1265 _parent_scene.AddCollisionEventReporting(this); 1268 _parent_scene.AddCollisionEventReporting(this);
1266 } 1269 }
1267 1270
1268 public override void UnSubscribeEvents() 1271 public override void UnSubscribeEvents()
1269 { 1272 {
1270 CollisionEventsThisFrame.Clear(); 1273 CollisionEventsThisFrame.Clear();
1271 _parent_scene.RemoveCollisionEventReporting(this); 1274
1275 // Don't clear collision event reporting here. This is called directly from scene code and so can lead
1276 // to a race condition with the simulate loop
1277
1272 m_requestedUpdateFrequency = 0; 1278 m_requestedUpdateFrequency = 0;
1273 m_eventsubscription = 0; 1279 m_eventsubscription = 0;
1274 } 1280 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 6f37347..a41c856 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -156,7 +156,15 @@ namespace OpenSim.Region.Physics.OdePlugin
156 /// </summary> 156 /// </summary>
157 public IntPtr m_targetSpace = IntPtr.Zero; 157 public IntPtr m_targetSpace = IntPtr.Zero;
158 158
159 /// <summary>
160 /// The prim geometry, used for collision detection.
161 /// </summary>
162 /// <remarks>
163 /// This is never null except for a brief period when the geometry needs to be replaced (due to resizing or
164 /// mesh change) or when the physical prim is being removed from the scene.
165 /// </remarks>
159 public IntPtr prim_geom { get; private set; } 166 public IntPtr prim_geom { get; private set; }
167
160 public IntPtr _triMeshData { get; private set; } 168 public IntPtr _triMeshData { get; private set; }
161 169
162 private IntPtr _linkJointGroup = IntPtr.Zero; 170 private IntPtr _linkJointGroup = IntPtr.Zero;
@@ -325,14 +333,12 @@ namespace OpenSim.Region.Physics.OdePlugin
325 { 333 {
326 prim_geom = geom; 334 prim_geom = geom;
327//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); 335//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
328 if (prim_geom != IntPtr.Zero)
329 {
330 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
331 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
332 336
333 _parent_scene.geom_name_map[prim_geom] = Name; 337 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
334 _parent_scene.actor_name_map[prim_geom] = this; 338 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
335 } 339
340 _parent_scene.geom_name_map[prim_geom] = Name;
341 _parent_scene.actor_name_map[prim_geom] = this;
336 342
337 if (childPrim) 343 if (childPrim)
338 { 344 {
@@ -765,11 +771,8 @@ namespace OpenSim.Region.Physics.OdePlugin
765 m_collisionCategories &= ~CollisionCategories.Body; 771 m_collisionCategories &= ~CollisionCategories.Body;
766 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 772 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
767 773
768 if (prim_geom != IntPtr.Zero) 774 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
769 { 775 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
770 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
771 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
772 }
773 776
774 d.BodyDestroy(Body); 777 d.BodyDestroy(Body);
775 lock (childrenPrim) 778 lock (childrenPrim)
@@ -793,11 +796,8 @@ namespace OpenSim.Region.Physics.OdePlugin
793 m_collisionCategories &= ~CollisionCategories.Body; 796 m_collisionCategories &= ~CollisionCategories.Body;
794 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 797 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
795 798
796 if (prim_geom != IntPtr.Zero) 799 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
797 { 800 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
798 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
799 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
800 }
801 801
802 Body = IntPtr.Zero; 802 Body = IntPtr.Zero;
803 } 803 }
@@ -864,10 +864,7 @@ namespace OpenSim.Region.Physics.OdePlugin
864// _parent_scene.waitForSpaceUnlock(m_targetSpace); 864// _parent_scene.waitForSpaceUnlock(m_targetSpace);
865 try 865 try
866 { 866 {
867 if (prim_geom == IntPtr.Zero) 867 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
868 {
869 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
870 }
871 } 868 }
872 catch (AccessViolationException) 869 catch (AccessViolationException)
873 { 870 {
@@ -890,73 +887,67 @@ namespace OpenSim.Region.Physics.OdePlugin
890#if SPAM 887#if SPAM
891Console.WriteLine("ZProcessTaints for " + Name); 888Console.WriteLine("ZProcessTaints for " + Name);
892#endif 889#endif
890
891 // This must be processed as the very first taint so that later operations have a prim_geom to work with
892 // if this is a new prim.
893 if (m_taintadd) 893 if (m_taintadd)
894 {
895 changeadd(); 894 changeadd();
896 }
897
898 if (prim_geom != IntPtr.Zero)
899 {
900 if (!_position.ApproxEquals(m_taintposition, 0f))
901 changemove();
902 895
903 if (m_taintrot != _orientation) 896 if (!_position.ApproxEquals(m_taintposition, 0f))
904 { 897 changemove();
905 if (childPrim && IsPhysical) // For physical child prim... 898
906 { 899 if (m_taintrot != _orientation)
907 rotate(); 900 {
908 // KF: ODE will also rotate the parent prim! 901 if (childPrim && IsPhysical) // For physical child prim...
909 // so rotate the root back to where it was 902 {
910 OdePrim parent = (OdePrim)_parent; 903 rotate();
911 parent.rotate(); 904 // KF: ODE will also rotate the parent prim!
912 } 905 // so rotate the root back to where it was
913 else 906 OdePrim parent = (OdePrim)_parent;
914 { 907 parent.rotate();
915 //Just rotate the prim
916 rotate();
917 }
918 } 908 }
919 909 else
920 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) 910 {
921 changePhysicsStatus(); 911 //Just rotate the prim
912 rotate();
913 }
914 }
915
916 if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent))
917 changePhysicsStatus();
922 918
923 if (!_size.ApproxEquals(m_taintsize, 0f)) 919 if (!_size.ApproxEquals(m_taintsize, 0f))
924 changesize(); 920 changesize();
925 921
926 if (m_taintshape) 922 if (m_taintshape)
927 changeshape(); 923 changeshape();
928 924
929 if (m_taintforce) 925 if (m_taintforce)
930 changeAddForce(); 926 changeAddForce();
931 927
932 if (m_taintaddangularforce) 928 if (m_taintaddangularforce)
933 changeAddAngularForce(); 929 changeAddAngularForce();
934 930
935 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) 931 if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
936 changeSetTorque(); 932 changeSetTorque();
937 933
938 if (m_taintdisable) 934 if (m_taintdisable)
939 changedisable(); 935 changedisable();
940 936
941 if (m_taintselected != m_isSelected) 937 if (m_taintselected != m_isSelected)
942 changeSelectedStatus(); 938 changeSelectedStatus();
943 939
944 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) 940 if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
945 changevelocity(); 941 changevelocity();
946 942
947 if (m_taintparent != _parent) 943 if (m_taintparent != _parent)
948 changelink(); 944 changelink();
949 945
950 if (m_taintCollidesWater != m_collidesWater) 946 if (m_taintCollidesWater != m_collidesWater)
951 changefloatonwater(); 947 changefloatonwater();
952 948
953 if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) 949 if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f))
954 changeAngularLock(); 950 changeAngularLock();
955 }
956 else
957 {
958 m_log.ErrorFormat("[PHYSICS]: The scene reused a disposed PhysActor for {0}! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)", Name);
959 }
960 } 951 }
961 952
962 /// <summary> 953 /// <summary>
@@ -1052,150 +1043,146 @@ Console.WriteLine("ZProcessTaints for " + Name);
1052 /// <param name="prim">Child prim</param> 1043 /// <param name="prim">Child prim</param>
1053 private void AddChildPrim(OdePrim prim) 1044 private void AddChildPrim(OdePrim prim)
1054 { 1045 {
1055//Console.WriteLine("AddChildPrim " + Name); 1046 if (LocalID == prim.LocalID)
1056 if (LocalID != prim.LocalID) 1047 return;
1048
1049 if (Body == IntPtr.Zero)
1057 { 1050 {
1058 if (Body == IntPtr.Zero) 1051 Body = d.BodyCreate(_parent_scene.world);
1052 setMass();
1053 }
1054
1055 lock (childrenPrim)
1056 {
1057 if (childrenPrim.Contains(prim))
1058 return;
1059
1060// m_log.DebugFormat(
1061// "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID);
1062
1063 childrenPrim.Add(prim);
1064
1065 foreach (OdePrim prm in childrenPrim)
1059 { 1066 {
1060 Body = d.BodyCreate(_parent_scene.world); 1067 d.Mass m2;
1061 setMass(); 1068 d.MassSetZero(out m2);
1069 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1070
1071 d.Quaternion quat = new d.Quaternion();
1072 quat.W = prm._orientation.W;
1073 quat.X = prm._orientation.X;
1074 quat.Y = prm._orientation.Y;
1075 quat.Z = prm._orientation.Z;
1076
1077 d.Matrix3 mat = new d.Matrix3();
1078 d.RfromQ(out mat, ref quat);
1079 d.MassRotate(ref m2, ref mat);
1080 d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
1081 d.MassAdd(ref pMass, ref m2);
1062 } 1082 }
1063 if (Body != IntPtr.Zero) 1083
1084 foreach (OdePrim prm in childrenPrim)
1064 { 1085 {
1065 lock (childrenPrim) 1086 prm.m_collisionCategories |= CollisionCategories.Body;
1066 { 1087 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1067 if (!childrenPrim.Contains(prim))
1068 {
1069//Console.WriteLine("childrenPrim.Add " + prim);
1070 childrenPrim.Add(prim);
1071
1072 foreach (OdePrim prm in childrenPrim)
1073 {
1074 d.Mass m2;
1075 d.MassSetZero(out m2);
1076 d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z);
1077
1078 d.Quaternion quat = new d.Quaternion();
1079 quat.W = prm._orientation.W;
1080 quat.X = prm._orientation.X;
1081 quat.Y = prm._orientation.Y;
1082 quat.Z = prm._orientation.Z;
1083
1084 d.Matrix3 mat = new d.Matrix3();
1085 d.RfromQ(out mat, ref quat);
1086 d.MassRotate(ref m2, ref mat);
1087 d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z);
1088 d.MassAdd(ref pMass, ref m2);
1089 }
1090
1091 foreach (OdePrim prm in childrenPrim)
1092 {
1093 prm.m_collisionCategories |= CollisionCategories.Body;
1094 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1095 1088
1096 if (prm.prim_geom == IntPtr.Zero)
1097 {
1098 m_log.WarnFormat(
1099 "[PHYSICS]: Unable to link one of the linkset elements {0} for parent {1}. No geom yet",
1100 prm.Name, prim.Name);
1101 continue;
1102 }
1103//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); 1089//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name);
1104 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); 1090 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1105 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); 1091 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1106
1107 1092
1108 d.Quaternion quat = new d.Quaternion(); 1093 d.Quaternion quat = new d.Quaternion();
1109 quat.W = prm._orientation.W; 1094 quat.W = prm._orientation.W;
1110 quat.X = prm._orientation.X; 1095 quat.X = prm._orientation.X;
1111 quat.Y = prm._orientation.Y; 1096 quat.Y = prm._orientation.Y;
1112 quat.Z = prm._orientation.Z; 1097 quat.Z = prm._orientation.Z;
1113 1098
1114 d.Matrix3 mat = new d.Matrix3(); 1099 d.Matrix3 mat = new d.Matrix3();
1115 d.RfromQ(out mat, ref quat); 1100 d.RfromQ(out mat, ref quat);
1116 if (Body != IntPtr.Zero) 1101 if (Body != IntPtr.Zero)
1117 { 1102 {
1118 d.GeomSetBody(prm.prim_geom, Body); 1103 d.GeomSetBody(prm.prim_geom, Body);
1119 prm.childPrim = true; 1104 prm.childPrim = true;
1120 d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); 1105 d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z);
1121 //d.GeomSetOffsetPosition(prim.prim_geom, 1106 //d.GeomSetOffsetPosition(prim.prim_geom,
1122 // (Position.X - prm.Position.X) - pMass.c.X, 1107 // (Position.X - prm.Position.X) - pMass.c.X,
1123 // (Position.Y - prm.Position.Y) - pMass.c.Y, 1108 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1124 // (Position.Z - prm.Position.Z) - pMass.c.Z); 1109 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1125 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); 1110 d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat);
1126 //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); 1111 //d.GeomSetOffsetRotation(prm.prim_geom, ref mat);
1127 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); 1112 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1128 d.BodySetMass(Body, ref pMass); 1113 d.BodySetMass(Body, ref pMass);
1129 } 1114 }
1130 else 1115 else
1131 { 1116 {
1132 m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); 1117 m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name);
1133 } 1118 }
1134 1119
1135 prm.m_interpenetrationcount = 0; 1120 prm.m_interpenetrationcount = 0;
1136 prm.m_collisionscore = 0; 1121 prm.m_collisionscore = 0;
1137 prm.m_disabled = false; 1122 prm.m_disabled = false;
1138 1123
1139 // The body doesn't already have a finite rotation mode set here 1124 // The body doesn't already have a finite rotation mode set here
1140 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) 1125 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
1141 { 1126 {
1142 prm.createAMotor(m_angularlock); 1127 prm.createAMotor(m_angularlock);
1143 } 1128 }
1144 prm.Body = Body; 1129 prm.Body = Body;
1145 _parent_scene.ActivatePrim(prm); 1130 _parent_scene.ActivatePrim(prm);
1146 } 1131 }
1147 1132
1148 m_collisionCategories |= CollisionCategories.Body; 1133 m_collisionCategories |= CollisionCategories.Body;
1149 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1134 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1150 1135
1151//Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); 1136//Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name);
1152 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1137 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1153//Console.WriteLine(" Post GeomSetCategoryBits 2"); 1138//Console.WriteLine(" Post GeomSetCategoryBits 2");
1154 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1139 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1155
1156 d.Quaternion quat2 = new d.Quaternion();
1157 quat2.W = _orientation.W;
1158 quat2.X = _orientation.X;
1159 quat2.Y = _orientation.Y;
1160 quat2.Z = _orientation.Z;
1161
1162 d.Matrix3 mat2 = new d.Matrix3();
1163 d.RfromQ(out mat2, ref quat2);
1164 d.GeomSetBody(prim_geom, Body);
1165 d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
1166 //d.GeomSetOffsetPosition(prim.prim_geom,
1167 // (Position.X - prm.Position.X) - pMass.c.X,
1168 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1169 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1170 //d.GeomSetOffsetRotation(prim_geom, ref mat2);
1171 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1172 d.BodySetMass(Body, ref pMass);
1173
1174 d.BodySetAutoDisableFlag(Body, true);
1175 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1176 1140
1177 m_interpenetrationcount = 0; 1141 d.Quaternion quat2 = new d.Quaternion();
1178 m_collisionscore = 0; 1142 quat2.W = _orientation.W;
1179 m_disabled = false; 1143 quat2.X = _orientation.X;
1144 quat2.Y = _orientation.Y;
1145 quat2.Z = _orientation.Z;
1180 1146
1181 // The body doesn't already have a finite rotation mode set here 1147 d.Matrix3 mat2 = new d.Matrix3();
1182 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) 1148 d.RfromQ(out mat2, ref quat2);
1183 { 1149 d.GeomSetBody(prim_geom, Body);
1184 createAMotor(m_angularlock); 1150 d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z);
1185 } 1151 //d.GeomSetOffsetPosition(prim.prim_geom,
1186 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); 1152 // (Position.X - prm.Position.X) - pMass.c.X,
1187 if (m_vehicle.Type != Vehicle.TYPE_NONE) 1153 // (Position.Y - prm.Position.Y) - pMass.c.Y,
1188 m_vehicle.Enable(Body, _parent_scene); 1154 // (Position.Z - prm.Position.Z) - pMass.c.Z);
1155 //d.GeomSetOffsetRotation(prim_geom, ref mat2);
1156 d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z);
1157 d.BodySetMass(Body, ref pMass);
1189 1158
1190 _parent_scene.ActivatePrim(this); 1159 d.BodySetAutoDisableFlag(Body, true);
1191 } 1160 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
1192 } 1161
1162 m_interpenetrationcount = 0;
1163 m_collisionscore = 0;
1164 m_disabled = false;
1165
1166 // The body doesn't already have a finite rotation mode set here
1167 if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null)
1168 {
1169 createAMotor(m_angularlock);
1193 } 1170 }
1171
1172 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
1173
1174 if (m_vehicle.Type != Vehicle.TYPE_NONE)
1175 m_vehicle.Enable(Body, _parent_scene);
1176
1177 _parent_scene.ActivatePrim(this);
1194 } 1178 }
1195 } 1179 }
1196 1180
1197 private void ChildSetGeom(OdePrim odePrim) 1181 private void ChildSetGeom(OdePrim odePrim)
1198 { 1182 {
1183// m_log.DebugFormat(
1184// "[ODE PRIM]: ChildSetGeom {0} {1} for {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID);
1185
1199 //if (IsPhysical && Body != IntPtr.Zero) 1186 //if (IsPhysical && Body != IntPtr.Zero)
1200 lock (childrenPrim) 1187 lock (childrenPrim)
1201 { 1188 {
@@ -1210,12 +1197,14 @@ Console.WriteLine("ZProcessTaints for " + Name);
1210 //prm.childPrim = false; 1197 //prm.childPrim = false;
1211 } 1198 }
1212 } 1199 }
1200
1213 disableBody(); 1201 disableBody();
1214 1202
1215 if (Body != IntPtr.Zero) 1203 // Spurious - Body == IntPtr.Zero after disableBody()
1216 { 1204// if (Body != IntPtr.Zero)
1217 _parent_scene.DeactivatePrim(this); 1205// {
1218 } 1206// _parent_scene.DeactivatePrim(this);
1207// }
1219 1208
1220 lock (childrenPrim) 1209 lock (childrenPrim)
1221 { 1210 {
@@ -1229,6 +1218,9 @@ Console.WriteLine("ZProcessTaints for " + Name);
1229 1218
1230 private void ChildDelink(OdePrim odePrim) 1219 private void ChildDelink(OdePrim odePrim)
1231 { 1220 {
1221// m_log.DebugFormat(
1222// "[ODE PRIM]: Delinking prim {0} {1} from {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID);
1223
1232 // Okay, we have a delinked child.. need to rebuild the body. 1224 // Okay, we have a delinked child.. need to rebuild the body.
1233 lock (childrenPrim) 1225 lock (childrenPrim)
1234 { 1226 {
@@ -1243,6 +1235,7 @@ Console.WriteLine("ZProcessTaints for " + Name);
1243 //prm.childPrim = false; 1235 //prm.childPrim = false;
1244 } 1236 }
1245 } 1237 }
1238
1246 disableBody(); 1239 disableBody();
1247 1240
1248 lock (childrenPrim) 1241 lock (childrenPrim)
@@ -1251,10 +1244,11 @@ Console.WriteLine("ZProcessTaints for " + Name);
1251 childrenPrim.Remove(odePrim); 1244 childrenPrim.Remove(odePrim);
1252 } 1245 }
1253 1246
1254 if (Body != IntPtr.Zero) 1247 // Spurious - Body == IntPtr.Zero after disableBody()
1255 { 1248// if (Body != IntPtr.Zero)
1256 _parent_scene.DeactivatePrim(this); 1249// {
1257 } 1250// _parent_scene.DeactivatePrim(this);
1251// }
1258 1252
1259 lock (childrenPrim) 1253 lock (childrenPrim)
1260 { 1254 {
@@ -1303,11 +1297,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1303 disableBodySoft(); 1297 disableBodySoft();
1304 } 1298 }
1305 1299
1306 if (prim_geom != IntPtr.Zero) 1300 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1307 { 1301 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1308 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1309 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1310 }
1311 1302
1312 if (IsPhysical) 1303 if (IsPhysical)
1313 { 1304 {
@@ -1328,11 +1319,8 @@ Console.WriteLine("ZProcessTaints for " + Name);
1328 if (m_collidesWater) 1319 if (m_collidesWater)
1329 m_collisionFlags |= CollisionCategories.Water; 1320 m_collisionFlags |= CollisionCategories.Water;
1330 1321
1331 if (prim_geom != IntPtr.Zero) 1322 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1332 { 1323 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1333 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1334 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1335 }
1336 1324
1337 if (IsPhysical) 1325 if (IsPhysical)
1338 { 1326 {
@@ -1472,6 +1460,9 @@ Console.WriteLine("CreateGeom:");
1472 } 1460 }
1473 else 1461 else
1474 { 1462 {
1463 m_log.WarnFormat(
1464 "[ODE PRIM]: Called RemoveGeom() on {0} {1} where geometry was already null.", Name, LocalID);
1465
1475 return false; 1466 return false;
1476 } 1467 }
1477 } 1468 }
@@ -1505,16 +1496,13 @@ Console.WriteLine("changeadd 1");
1505#endif 1496#endif
1506 CreateGeom(m_targetSpace, mesh); 1497 CreateGeom(m_targetSpace, mesh);
1507 1498
1508 if (prim_geom != IntPtr.Zero) 1499 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1509 { 1500 d.Quaternion myrot = new d.Quaternion();
1510 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); 1501 myrot.X = _orientation.X;
1511 d.Quaternion myrot = new d.Quaternion(); 1502 myrot.Y = _orientation.Y;
1512 myrot.X = _orientation.X; 1503 myrot.Z = _orientation.Z;
1513 myrot.Y = _orientation.Y; 1504 myrot.W = _orientation.W;
1514 myrot.Z = _orientation.Z; 1505 d.GeomSetQuaternion(prim_geom, ref myrot);
1515 myrot.W = _orientation.W;
1516 d.GeomSetQuaternion(prim_geom, ref myrot);
1517 }
1518 1506
1519 if (IsPhysical && Body == IntPtr.Zero) 1507 if (IsPhysical && Body == IntPtr.Zero)
1520 enableBody(); 1508 enableBody();
@@ -1579,24 +1567,20 @@ Console.WriteLine(" JointCreateFixed");
1579 //m_log.Debug("[BUG]: race!"); 1567 //m_log.Debug("[BUG]: race!");
1580 //} 1568 //}
1581 } 1569 }
1582 else
1583 {
1584 // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
1585 // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1586// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1587 1570
1588 IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); 1571 // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
1589 m_targetSpace = tempspace; 1572 // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1573// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1574
1575 IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
1576 m_targetSpace = tempspace;
1590 1577
1591// _parent_scene.waitForSpaceUnlock(m_targetSpace); 1578// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1592 if (prim_geom != IntPtr.Zero) 1579
1593 { 1580 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1594 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1595 1581
1596// _parent_scene.waitForSpaceUnlock(m_targetSpace); 1582// _parent_scene.waitForSpaceUnlock(m_targetSpace);
1597 d.SpaceAdd(m_targetSpace, prim_geom); 1583 d.SpaceAdd(m_targetSpace, prim_geom);
1598 }
1599 }
1600 1584
1601 changeSelectedStatus(); 1585 changeSelectedStatus();
1602 1586
@@ -2047,18 +2031,16 @@ Console.WriteLine(" JointCreateFixed");
2047 { 2031 {
2048 m_collidesWater = m_taintCollidesWater; 2032 m_collidesWater = m_taintCollidesWater;
2049 2033
2050 if (prim_geom != IntPtr.Zero) 2034 if (m_collidesWater)
2051 { 2035 {
2052 if (m_collidesWater) 2036 m_collisionFlags |= CollisionCategories.Water;
2053 {
2054 m_collisionFlags |= CollisionCategories.Water;
2055 }
2056 else
2057 {
2058 m_collisionFlags &= ~CollisionCategories.Water;
2059 }
2060 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2061 } 2037 }
2038 else
2039 {
2040 m_collisionFlags &= ~CollisionCategories.Water;
2041 }
2042
2043 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2062 } 2044 }
2063 2045
2064 /// <summary> 2046 /// <summary>
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 842ff91..409b27b 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -2226,7 +2226,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2226 /// <param name="prim"></param> 2226 /// <param name="prim"></param>
2227 internal void RemovePrimThreadLocked(OdePrim prim) 2227 internal void RemovePrimThreadLocked(OdePrim prim)
2228 { 2228 {
2229//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); 2229// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID);
2230
2230 lock (prim) 2231 lock (prim)
2231 { 2232 {
2232 RemoveCollisionEventReporting(prim); 2233 RemoveCollisionEventReporting(prim);
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index d8d9554..40daf13 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -43,9 +43,8 @@ using Mono.Addins;
43[assembly: AddinDependency("OpenSim", "0.5")] 43[assembly: AddinDependency("OpenSim", "0.5")]
44namespace OpenSim.Region.RegionCombinerModule 44namespace OpenSim.Region.RegionCombinerModule
45{ 45{
46
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
48 public class RegionCombinerModule : ISharedRegionModule 47 public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
49 { 48 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 50
@@ -59,8 +58,22 @@ namespace OpenSim.Region.RegionCombinerModule
59 get { return null; } 58 get { return null; }
60 } 59 }
61 60
62 private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>(); 61 /// <summary>
62 /// Is this module enabled?
63 /// </summary>
63 private bool enabledYN = false; 64 private bool enabledYN = false;
65
66 /// <summary>
67 /// This holds the root regions for the megaregions.
68 /// </summary>
69 /// <remarks>
70 /// Usually there is only ever one megaregion (and hence only one entry here).
71 /// </remarks>
72 private Dictionary<UUID, RegionConnections> m_regions = new Dictionary<UUID, RegionConnections>();
73
74 /// <summary>
75 /// The scenes that comprise the megaregion.
76 /// </summary>
64 private Dictionary<UUID, Scene> m_startingScenes = new Dictionary<UUID, Scene>(); 77 private Dictionary<UUID, Scene> m_startingScenes = new Dictionary<UUID, Scene>();
65 78
66 public void Initialise(IConfigSource source) 79 public void Initialise(IConfigSource source)
@@ -69,9 +82,11 @@ namespace OpenSim.Region.RegionCombinerModule
69 enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); 82 enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false);
70 83
71 if (enabledYN) 84 if (enabledYN)
85 {
72 MainConsole.Instance.Commands.AddCommand( 86 MainConsole.Instance.Commands.AddCommand(
73 "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", 87 "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms",
74 "Fixes phantom objects after an import to megaregions", FixPhantoms); 88 "Fixes phantom objects after an import to megaregions", FixPhantoms);
89 }
75 } 90 }
76 91
77 public void Close() 92 public void Close()
@@ -80,6 +95,8 @@ namespace OpenSim.Region.RegionCombinerModule
80 95
81 public void AddRegion(Scene scene) 96 public void AddRegion(Scene scene)
82 { 97 {
98 if (enabledYN)
99 scene.RegisterModuleInterface<IRegionCombinerModule>(this);
83 } 100 }
84 101
85 public void RemoveRegion(Scene scene) 102 public void RemoveRegion(Scene scene)
@@ -89,7 +106,110 @@ namespace OpenSim.Region.RegionCombinerModule
89 public void RegionLoaded(Scene scene) 106 public void RegionLoaded(Scene scene)
90 { 107 {
91 if (enabledYN) 108 if (enabledYN)
109 {
92 RegionLoadedDoWork(scene); 110 RegionLoadedDoWork(scene);
111
112 scene.EventManager.OnNewPresence += NewPresence;
113 }
114 }
115
116 public bool IsRootForMegaregion(UUID regionId)
117 {
118 lock (m_regions)
119 return m_regions.ContainsKey(regionId);
120 }
121
122 public Vector2 GetSizeOfMegaregion(UUID regionId)
123 {
124 lock (m_regions)
125 {
126 if (m_regions.ContainsKey(regionId))
127 {
128 RegionConnections rootConn = m_regions[regionId];
129
130 return new Vector2((float)rootConn.XEnd, (float)rootConn.YEnd);
131 }
132 }
133
134 throw new Exception(string.Format("Region with id {0} not found", regionId));
135 }
136
137 private void NewPresence(ScenePresence presence)
138 {
139 if (presence.IsChildAgent)
140 {
141 byte[] throttleData;
142
143 try
144 {
145 throttleData = presence.ControllingClient.GetThrottlesPacked(1);
146 }
147 catch (NotImplementedException)
148 {
149 return;
150 }
151
152 if (throttleData == null)
153 return;
154
155 if (throttleData.Length == 0)
156 return;
157
158 if (throttleData.Length != 28)
159 return;
160
161 byte[] adjData;
162 int pos = 0;
163
164 if (!BitConverter.IsLittleEndian)
165 {
166 byte[] newData = new byte[7 * 4];
167 Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4);
168
169 for (int i = 0; i < 7; i++)
170 Array.Reverse(newData, i * 4, 4);
171
172 adjData = newData;
173 }
174 else
175 {
176 adjData = throttleData;
177 }
178
179 // 0.125f converts from bits to bytes
180 int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
181 int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
182 int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
183 int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
184 int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
185 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
186 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
187 // State is a subcategory of task that we allocate a percentage to
188
189
190 //int total = resend + land + wind + cloud + task + texture + asset;
191
192 byte[] data = new byte[7 * 4];
193 int ii = 0;
194
195 Buffer.BlockCopy(Utils.FloatToBytes(resend), 0, data, ii, 4); ii += 4;
196 Buffer.BlockCopy(Utils.FloatToBytes(land * 50), 0, data, ii, 4); ii += 4;
197 Buffer.BlockCopy(Utils.FloatToBytes(wind), 0, data, ii, 4); ii += 4;
198 Buffer.BlockCopy(Utils.FloatToBytes(cloud), 0, data, ii, 4); ii += 4;
199 Buffer.BlockCopy(Utils.FloatToBytes(task), 0, data, ii, 4); ii += 4;
200 Buffer.BlockCopy(Utils.FloatToBytes(texture), 0, data, ii, 4); ii += 4;
201 Buffer.BlockCopy(Utils.FloatToBytes(asset), 0, data, ii, 4);
202
203 try
204 {
205 presence.ControllingClient.SetChildAgentThrottle(data);
206 }
207 catch (NotImplementedException)
208 {
209 return;
210 }
211
212 }
93 } 213 }
94 214
95 private void RegionLoadedDoWork(Scene scene) 215 private void RegionLoadedDoWork(Scene scene)
@@ -124,24 +244,21 @@ namespace OpenSim.Region.RegionCombinerModule
124 westBorder.CrossDirection = Cardinals.W; 244 westBorder.CrossDirection = Cardinals.W;
125 scene.WestBorders[0] = westBorder; 245 scene.WestBorders[0] = westBorder;
126 246
127 247 RegionConnections newConn = new RegionConnections();
128 248 newConn.ConnectedRegions = new List<RegionData>();
129 RegionConnections regionConnections = new RegionConnections(); 249 newConn.RegionScene = scene;
130 regionConnections.ConnectedRegions = new List<RegionData>(); 250 newConn.RegionLandChannel = scene.LandChannel;
131 regionConnections.RegionScene = scene; 251 newConn.RegionId = scene.RegionInfo.originRegionID;
132 regionConnections.RegionLandChannel = scene.LandChannel; 252 newConn.X = scene.RegionInfo.RegionLocX;
133 regionConnections.RegionId = scene.RegionInfo.originRegionID; 253 newConn.Y = scene.RegionInfo.RegionLocY;
134 regionConnections.X = scene.RegionInfo.RegionLocX; 254 newConn.XEnd = (int)Constants.RegionSize;
135 regionConnections.Y = scene.RegionInfo.RegionLocY; 255 newConn.YEnd = (int)Constants.RegionSize;
136 regionConnections.XEnd = (int)Constants.RegionSize;
137 regionConnections.YEnd = (int)Constants.RegionSize;
138
139 256
140 lock (m_regions) 257 lock (m_regions)
141 { 258 {
142 bool connectedYN = false; 259 bool connectedYN = false;
143 260
144 foreach (RegionConnections conn in m_regions.Values) 261 foreach (RegionConnections rootConn in m_regions.Values)
145 { 262 {
146 #region commented 263 #region commented
147 /* 264 /*
@@ -306,13 +423,9 @@ namespace OpenSim.Region.RegionCombinerModule
306 //xxy 423 //xxy
307 //xxx 424 //xxx
308 425
309 426 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY)
310 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
311 >= (regionConnections.X * (int)Constants.RegionSize))
312 && (((int)conn.Y * (int)Constants.RegionSize)
313 >= (regionConnections.Y * (int)Constants.RegionSize)))
314 { 427 {
315 connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene); 428 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
316 break; 429 break;
317 } 430 }
318 431
@@ -320,12 +433,9 @@ namespace OpenSim.Region.RegionCombinerModule
320 //xyx 433 //xyx
321 //xxx 434 //xxx
322 //xxx 435 //xxx
323 if ((((int)conn.X * (int)Constants.RegionSize) 436 if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
324 >= (regionConnections.X * (int)Constants.RegionSize))
325 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
326 >= (regionConnections.Y * (int)Constants.RegionSize)))
327 { 437 {
328 connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene); 438 connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene);
329 break; 439 break;
330 } 440 }
331 441
@@ -333,12 +443,9 @@ namespace OpenSim.Region.RegionCombinerModule
333 //xxy 443 //xxy
334 //xxx 444 //xxx
335 //xxx 445 //xxx
336 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd 446 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
337 >= (regionConnections.X * (int)Constants.RegionSize))
338 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
339 >= (regionConnections.Y * (int)Constants.RegionSize)))
340 { 447 {
341 connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene); 448 connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene);
342 break; 449 break;
343 450
344 } 451 }
@@ -347,66 +454,63 @@ namespace OpenSim.Region.RegionCombinerModule
347 // If !connectYN means that this region is a root region 454 // If !connectYN means that this region is a root region
348 if (!connectedYN) 455 if (!connectedYN)
349 { 456 {
350 DoWorkForRootRegion(regionConnections, scene); 457 DoWorkForRootRegion(newConn, scene);
351
352 } 458 }
353 } 459 }
460
354 // Set up infinite borders around the entire AABB of the combined ConnectedRegions 461 // Set up infinite borders around the entire AABB of the combined ConnectedRegions
355 AdjustLargeRegionBounds(); 462 AdjustLargeRegionBounds();
356 } 463 }
357 464
358 private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene) 465 private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
359 { 466 {
360 Vector3 offset = Vector3.Zero; 467 Vector3 offset = Vector3.Zero;
361 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - 468 offset.X = newConn.PosX - rootConn.PosX;
362 ((conn.X * (int)Constants.RegionSize))); 469 offset.Y = newConn.PosY - rootConn.PosY;
363 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
364 ((conn.Y * (int)Constants.RegionSize)));
365 470
366 Vector3 extents = Vector3.Zero; 471 Vector3 extents = Vector3.Zero;
367 extents.Y = conn.YEnd; 472 extents.Y = rootConn.YEnd;
368 extents.X = conn.XEnd + regionConnections.XEnd; 473 extents.X = rootConn.XEnd + newConn.XEnd;
369 474
370 conn.UpdateExtents(extents); 475 rootConn.UpdateExtents(extents);
371 476
372 m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", 477 m_log.DebugFormat(
373 conn.RegionScene.RegionInfo.RegionName, 478 "[REGION COMBINER MODULE]: Root region {0} is to the west of region {1}, Offset: {2}, Extents: {3}",
374 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); 479 rootConn.RegionScene.RegionInfo.RegionName,
480 newConn.RegionScene.RegionInfo.RegionName, offset, extents);
375 481
376 scene.BordersLocked = true; 482 scene.BordersLocked = true;
377 conn.RegionScene.BordersLocked = true; 483 rootConn.RegionScene.BordersLocked = true;
378 484
379 RegionData ConnectedRegion = new RegionData(); 485 RegionData ConnectedRegion = new RegionData();
380 ConnectedRegion.Offset = offset; 486 ConnectedRegion.Offset = offset;
381 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 487 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
382 ConnectedRegion.RegionScene = scene; 488 ConnectedRegion.RegionScene = scene;
383 conn.ConnectedRegions.Add(ConnectedRegion); 489 rootConn.ConnectedRegions.Add(ConnectedRegion);
384 490
385 // Inform root region Physics about the extents of this region 491 // Inform root region Physics about the extents of this region
386 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 492 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
387 493
388 // Inform Child region that it needs to forward it's terrain to the root region 494 // Inform Child region that it needs to forward it's terrain to the root region
389 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); 495 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
390 496
391 // Extend the borders as appropriate 497 // Extend the borders as appropriate
392 lock (conn.RegionScene.EastBorders) 498 lock (rootConn.RegionScene.EastBorders)
393 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; 499 rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
394 500
395 lock (conn.RegionScene.NorthBorders) 501 lock (rootConn.RegionScene.NorthBorders)
396 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; 502 rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
397 503
398 lock (conn.RegionScene.SouthBorders) 504 lock (rootConn.RegionScene.SouthBorders)
399 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; 505 rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
400 506
401 lock (scene.WestBorders) 507 lock (scene.WestBorders)
402 { 508 {
403 509 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
404
405 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
406 510
407 // Trigger auto teleport to root region 511 // Trigger auto teleport to root region
408 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; 512 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
409 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; 513 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
410 } 514 }
411 515
412 // Reset Terrain.. since terrain loads before we get here, we need to load 516 // Reset Terrain.. since terrain loads before we get here, we need to load
@@ -415,56 +519,58 @@ namespace OpenSim.Region.RegionCombinerModule
415 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 519 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
416 520
417 // Unlock borders 521 // Unlock borders
418 conn.RegionScene.BordersLocked = false; 522 rootConn.RegionScene.BordersLocked = false;
419 scene.BordersLocked = false; 523 scene.BordersLocked = false;
420 524
421 // Create a client event forwarder and add this region's events to the root region. 525 // Create a client event forwarder and add this region's events to the root region.
422 if (conn.ClientEventForwarder != null) 526 if (rootConn.ClientEventForwarder != null)
423 conn.ClientEventForwarder.AddSceneToEventForwarding(scene); 527 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
424 528
425 return true; 529 return true;
426 } 530 }
427 531
428 private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) 532 private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
429 { 533 {
430 Vector3 offset = Vector3.Zero; 534 Vector3 offset = Vector3.Zero;
431 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - 535 offset.X = newConn.PosX - rootConn.PosX;
432 ((conn.X * (int)Constants.RegionSize))); 536 offset.Y = newConn.PosY - rootConn.PosY;
433 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
434 ((conn.Y * (int)Constants.RegionSize)));
435 537
436 Vector3 extents = Vector3.Zero; 538 Vector3 extents = Vector3.Zero;
437 extents.Y = regionConnections.YEnd + conn.YEnd; 539 extents.Y = newConn.YEnd + rootConn.YEnd;
438 extents.X = conn.XEnd; 540 extents.X = rootConn.XEnd;
439 conn.UpdateExtents(extents); 541 rootConn.UpdateExtents(extents);
440 542
441 scene.BordersLocked = true; 543 scene.BordersLocked = true;
442 conn.RegionScene.BordersLocked = true; 544 rootConn.RegionScene.BordersLocked = true;
443 545
444 RegionData ConnectedRegion = new RegionData(); 546 RegionData ConnectedRegion = new RegionData();
445 ConnectedRegion.Offset = offset; 547 ConnectedRegion.Offset = offset;
446 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 548 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
447 ConnectedRegion.RegionScene = scene; 549 ConnectedRegion.RegionScene = scene;
448 conn.ConnectedRegions.Add(ConnectedRegion); 550 rootConn.ConnectedRegions.Add(ConnectedRegion);
551
552 m_log.DebugFormat(
553 "[REGION COMBINER MODULE]: Root region {0} is to the south of region {1}, Offset: {2}, Extents: {3}",
554 rootConn.RegionScene.RegionInfo.RegionName,
555 newConn.RegionScene.RegionInfo.RegionName, offset, extents);
449 556
450 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", 557 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
451 conn.RegionScene.RegionInfo.RegionName, 558 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
452 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
453 559
454 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 560 lock (rootConn.RegionScene.NorthBorders)
455 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); 561 rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
562
563 lock (rootConn.RegionScene.EastBorders)
564 rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
565
566 lock (rootConn.RegionScene.WestBorders)
567 rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
456 568
457 lock (conn.RegionScene.NorthBorders)
458 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
459 lock (conn.RegionScene.EastBorders)
460 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
461 lock (conn.RegionScene.WestBorders)
462 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
463 lock (scene.SouthBorders) 569 lock (scene.SouthBorders)
464 { 570 {
465 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south 571 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
466 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; 572 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
467 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; 573 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
468 } 574 }
469 575
470 // Reset Terrain.. since terrain normally loads first. 576 // Reset Terrain.. since terrain normally loads first.
@@ -473,83 +579,92 @@ namespace OpenSim.Region.RegionCombinerModule
473 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 579 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
474 580
475 scene.BordersLocked = false; 581 scene.BordersLocked = false;
476 conn.RegionScene.BordersLocked = false; 582 rootConn.RegionScene.BordersLocked = false;
477 if (conn.ClientEventForwarder != null) 583
478 conn.ClientEventForwarder.AddSceneToEventForwarding(scene); 584 if (rootConn.ClientEventForwarder != null)
585 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
586
479 return true; 587 return true;
480 } 588 }
481 589
482 private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) 590 private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
483 { 591 {
484 Vector3 offset = Vector3.Zero; 592 Vector3 offset = Vector3.Zero;
485 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - 593 offset.X = newConn.PosX - rootConn.PosX;
486 ((conn.X * (int)Constants.RegionSize))); 594 offset.Y = newConn.PosY - rootConn.PosY;
487 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
488 ((conn.Y * (int)Constants.RegionSize)));
489 595
490 Vector3 extents = Vector3.Zero; 596 Vector3 extents = Vector3.Zero;
491 extents.Y = regionConnections.YEnd + conn.YEnd; 597
492 extents.X = regionConnections.XEnd + conn.XEnd; 598 // We do not want to inflate the extents for regions strictly to the NE of the root region, since this
493 conn.UpdateExtents(extents); 599 // would double count regions strictly to the north and east that have already been added.
600// extents.Y = regionConnections.YEnd + conn.YEnd;
601// extents.X = regionConnections.XEnd + conn.XEnd;
602// conn.UpdateExtents(extents);
603
604 extents.Y = rootConn.YEnd;
605 extents.X = rootConn.XEnd;
494 606
495 scene.BordersLocked = true; 607 scene.BordersLocked = true;
496 conn.RegionScene.BordersLocked = true; 608 rootConn.RegionScene.BordersLocked = true;
497 609
498 RegionData ConnectedRegion = new RegionData(); 610 RegionData ConnectedRegion = new RegionData();
499 ConnectedRegion.Offset = offset; 611 ConnectedRegion.Offset = offset;
500 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 612 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
501 ConnectedRegion.RegionScene = scene; 613 ConnectedRegion.RegionScene = scene;
502 614
503 conn.ConnectedRegions.Add(ConnectedRegion); 615 rootConn.ConnectedRegions.Add(ConnectedRegion);
616
617 m_log.DebugFormat(
618 "[REGION COMBINER MODULE]: Region {0} is to the southwest of Scene {1}, Offset: {2}, Extents: {3}",
619 rootConn.RegionScene.RegionInfo.RegionName,
620 newConn.RegionScene.RegionInfo.RegionName, offset, extents);
504 621
505 m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", 622 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
506 conn.RegionScene.RegionInfo.RegionName, 623 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
507 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
508 624
509 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 625 lock (rootConn.RegionScene.NorthBorders)
510 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
511 lock (conn.RegionScene.NorthBorders)
512 { 626 {
513 if (conn.RegionScene.NorthBorders.Count == 1)// && 2) 627 if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2)
514 { 628 {
515 //compound border 629 //compound border
516 // already locked above 630 // already locked above
517 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; 631 rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
518 632
519 lock (conn.RegionScene.EastBorders) 633 lock (rootConn.RegionScene.EastBorders)
520 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; 634 rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
521 lock (conn.RegionScene.WestBorders) 635
522 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; 636 lock (rootConn.RegionScene.WestBorders)
637 rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
523 } 638 }
524 } 639 }
525 640
526 lock (scene.SouthBorders) 641 lock (scene.SouthBorders)
527 { 642 {
528 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south 643 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
529 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; 644 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
530 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; 645 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
531 } 646 }
532 647
533 lock (conn.RegionScene.EastBorders) 648 lock (rootConn.RegionScene.EastBorders)
534 { 649 {
535 if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) 650 if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
536 { 651 {
537 652
538 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; 653 rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
539 lock (conn.RegionScene.NorthBorders)
540 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
541 lock (conn.RegionScene.SouthBorders)
542 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
543 654
655 lock (rootConn.RegionScene.NorthBorders)
656 rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
544 657
658 lock (rootConn.RegionScene.SouthBorders)
659 rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
545 } 660 }
546 } 661 }
547 662
548 lock (scene.WestBorders) 663 lock (scene.WestBorders)
549 { 664 {
550 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West 665 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
551 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; 666 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
552 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; 667 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
553 } 668 }
554 669
555 /* 670 /*
@@ -568,46 +683,50 @@ namespace OpenSim.Region.RegionCombinerModule
568 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 683 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
569 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 684 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
570 scene.BordersLocked = false; 685 scene.BordersLocked = false;
571 conn.RegionScene.BordersLocked = false; 686 rootConn.RegionScene.BordersLocked = false;
572 687
573 if (conn.ClientEventForwarder != null) 688 if (rootConn.ClientEventForwarder != null)
574 conn.ClientEventForwarder.AddSceneToEventForwarding(scene); 689 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
575 690
576 return true; 691 return true;
577 692
578 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); 693 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
579
580 } 694 }
581 695
582 private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) 696 private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene)
583 { 697 {
698 m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName);
699
584 RegionData rdata = new RegionData(); 700 RegionData rdata = new RegionData();
585 rdata.Offset = Vector3.Zero; 701 rdata.Offset = Vector3.Zero;
586 rdata.RegionId = scene.RegionInfo.originRegionID; 702 rdata.RegionId = scene.RegionInfo.originRegionID;
587 rdata.RegionScene = scene; 703 rdata.RegionScene = scene;
588 // save it's land channel 704 // save it's land channel
589 regionConnections.RegionLandChannel = scene.LandChannel; 705 rootConn.RegionLandChannel = scene.LandChannel;
590 706
591 // Substitue our landchannel 707 // Substitue our landchannel
592 RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel, 708 RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel,
593 regionConnections.ConnectedRegions); 709 rootConn.ConnectedRegions);
710
594 scene.LandChannel = lnd; 711 scene.LandChannel = lnd;
712
595 // Forward the permissions modules of each of the connected regions to the root region 713 // Forward the permissions modules of each of the connected regions to the root region
596 lock (m_regions) 714 lock (m_regions)
597 { 715 {
598 foreach (RegionData r in regionConnections.ConnectedRegions) 716 foreach (RegionData r in rootConn.ConnectedRegions)
599 { 717 {
600 ForwardPermissionRequests(regionConnections, r.RegionScene); 718 ForwardPermissionRequests(rootConn, r.RegionScene);
601 } 719 }
602 }
603 // Create the root region's Client Event Forwarder
604 regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections);
605 720
606 // Sets up the CoarseLocationUpdate forwarder for this root region 721 // Create the root region's Client Event Forwarder
607 scene.EventManager.OnNewPresence += SetCourseLocationDelegate; 722 rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn);
608 723
609 // Adds this root region to a dictionary of regions that are connectable 724 // Sets up the CoarseLocationUpdate forwarder for this root region
610 m_regions.Add(scene.RegionInfo.originRegionID, regionConnections); 725 scene.EventManager.OnNewPresence += SetCourseLocationDelegate;
726
727 // Adds this root region to a dictionary of regions that are connectable
728 m_regions.Add(scene.RegionInfo.originRegionID, rootConn);
729 }
611 } 730 }
612 731
613 private void SetCourseLocationDelegate(ScenePresence presence) 732 private void SetCourseLocationDelegate(ScenePresence presence)
@@ -864,6 +983,7 @@ namespace OpenSim.Region.RegionCombinerModule
864 return true; 983 return true;
865 } 984 }
866 } 985 }
986
867 oborder = null; 987 oborder = null;
868 return false; 988 return false;
869 } 989 }
@@ -873,14 +993,19 @@ namespace OpenSim.Region.RegionCombinerModule
873 pPosition = pPosition/(int) Constants.RegionSize; 993 pPosition = pPosition/(int) Constants.RegionSize;
874 int OffsetX = (int) pPosition.X; 994 int OffsetX = (int) pPosition.X;
875 int OffsetY = (int) pPosition.Y; 995 int OffsetY = (int) pPosition.Y;
876 foreach (RegionConnections regConn in m_regions.Values) 996
997 lock (m_regions)
877 { 998 {
878 foreach (RegionData reg in regConn.ConnectedRegions) 999 foreach (RegionConnections regConn in m_regions.Values)
879 { 1000 {
880 if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) 1001 foreach (RegionData reg in regConn.ConnectedRegions)
881 return reg; 1002 {
1003 if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY)
1004 return reg;
1005 }
882 } 1006 }
883 } 1007 }
1008
884 return new RegionData(); 1009 return new RegionData();
885 } 1010 }
886 1011
@@ -936,18 +1061,17 @@ namespace OpenSim.Region.RegionCombinerModule
936 } 1061 }
937 1062
938 #region console commands 1063 #region console commands
1064
939 public void FixPhantoms(string module, string[] cmdparams) 1065 public void FixPhantoms(string module, string[] cmdparams)
940 { 1066 {
941 List<Scene> scenes = new List<Scene>(m_startingScenes.Values); 1067 List<Scene> scenes = new List<Scene>(m_startingScenes.Values);
1068
942 foreach (Scene s in scenes) 1069 foreach (Scene s in scenes)
943 { 1070 {
944 s.ForEachSOG(delegate(SceneObjectGroup e) 1071 s.ForEachSOG(so => so.AbsolutePosition = so.AbsolutePosition);
945 {
946 e.AbsolutePosition = e.AbsolutePosition;
947 }
948 );
949 } 1072 }
950 } 1073 }
1074
951 #endregion 1075 #endregion
952 } 1076 }
953} 1077}
diff --git a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
index 3aa9f20..fba51d2 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework;
31using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33 34
@@ -49,17 +50,45 @@ namespace OpenSim.Region.RegionCombinerModule
49 /// LargeLandChannel for combined region 50 /// LargeLandChannel for combined region
50 /// </summary> 51 /// </summary>
51 public ILandChannel RegionLandChannel; 52 public ILandChannel RegionLandChannel;
53
54 /// <summary>
55 /// The x map co-ordinate for this region (where each co-ordinate is a Constants.RegionSize block).
56 /// </summary>
52 public uint X; 57 public uint X;
58
59 /// <summary>
60 /// The y co-ordinate for this region (where each cor-odinate is a Constants.RegionSize block).
61 /// </summary>
53 public uint Y; 62 public uint Y;
54 public int XEnd; 63
55 public int YEnd; 64 /// <summary>
65 /// The X meters position of this connection.
66 /// </summary>
67 public uint PosX { get { return X * Constants.RegionSize; } }
68
69 /// <summary>
70 /// The Y meters co-ordinate of this connection.
71 /// </summary>
72 public uint PosY { get { return Y * Constants.RegionSize; } }
73
74 /// <summary>
75 /// The size of the megaregion in meters.
76 /// </summary>
77 public uint XEnd;
78
79 /// <summary>
80 /// The size of the megaregion in meters.
81 /// </summary>
82 public uint YEnd;
83
56 public List<RegionData> ConnectedRegions; 84 public List<RegionData> ConnectedRegions;
57 public RegionCombinerPermissionModule PermissionModule; 85 public RegionCombinerPermissionModule PermissionModule;
58 public RegionCombinerClientEventForwarder ClientEventForwarder; 86 public RegionCombinerClientEventForwarder ClientEventForwarder;
87
59 public void UpdateExtents(Vector3 extents) 88 public void UpdateExtents(Vector3 extents)
60 { 89 {
61 XEnd = (int)extents.X; 90 XEnd = (uint)extents.X;
62 YEnd = (int)extents.Y; 91 YEnd = (uint)extents.Y;
63 } 92 }
64 } 93 }
65} \ No newline at end of file 94} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
index bb5bacc..2027ca6 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptApi.cs
@@ -27,17 +27,22 @@
27 27
28using System; 28using System;
29using OpenMetaverse; 29using OpenMetaverse;
30using OpenSim.Framework;
30using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
31 32
32
33namespace OpenSim.Region.ScriptEngine.Interfaces 33namespace OpenSim.Region.ScriptEngine.Interfaces
34{ 34{
35 public interface IScriptApi 35 public interface IScriptApi
36 { 36 {
37 // 37 /// <summary>
38 // Each API has an identifier, which is used to load the 38 /// Initialize the API
39 // proper runtime assembly at load time. 39 /// </summary>
40 // 40 /// <remarks>
41 void Initialize(IScriptEngine engine, SceneObjectPart part, uint localID, UUID item); 41 /// Each API has an identifier, which is used to load the
42 /// proper runtime assembly at load time.
43 /// <param name='engine'>/param>
44 /// <param name='part'></param>
45 /// <param name='item'></param>
46 void Initialize(IScriptEngine engine, SceneObjectPart part, TaskInventoryItem item);
42 } 47 }
43} 48} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs
index 47ed6ba..684138f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/ApiManager.cs
@@ -29,42 +29,43 @@ using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using log4net;
32using OpenSim.Region.ScriptEngine.Interfaces; 33using OpenSim.Region.ScriptEngine.Interfaces;
33 34
34namespace OpenSim.Region.ScriptEngine.Shared.Api 35namespace OpenSim.Region.ScriptEngine.Shared.Api
35{ 36{
36 public class ApiManager 37 public class ApiManager
37 { 38 {
39// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40
38 private Dictionary<string,Type> m_Apis = new Dictionary<string,Type>(); 41 private Dictionary<string,Type> m_Apis = new Dictionary<string,Type>();
39 42
40 public string[] GetApis() 43 public string[] GetApis()
41 { 44 {
42 if (m_Apis.Count > 0) 45 if (m_Apis.Count <= 0)
43 { 46 {
44 List<string> l = new List<string>(m_Apis.Keys); 47 Assembly a = Assembly.GetExecutingAssembly();
45 return l.ToArray();
46 }
47 48
48 Assembly a = Assembly.GetExecutingAssembly(); 49 Type[] types = a.GetExportedTypes();
49 50
50 Type[] types = a.GetExportedTypes(); 51 foreach (Type t in types)
51
52 foreach (Type t in types)
53 {
54 string name = t.ToString();
55 int idx = name.LastIndexOf('.');
56 if (idx != -1)
57 name = name.Substring(idx+1);
58
59 if (name.EndsWith("_Api"))
60 { 52 {
61 name = name.Substring(0, name.Length - 4); 53 string name = t.ToString();
62 m_Apis[name] = t; 54 int idx = name.LastIndexOf('.');
55 if (idx != -1)
56 name = name.Substring(idx+1);
57
58 if (name.EndsWith("_Api"))
59 {
60 name = name.Substring(0, name.Length - 4);
61 m_Apis[name] = t;
62 }
63 } 63 }
64 } 64 }
65 65
66 List<string> ret = new List<string>(m_Apis.Keys); 66// m_log.DebugFormat("[API MANAGER]: Found {0} apis", m_Apis.Keys.Count);
67 return ret.ToArray(); 67
68 return new List<string>(m_Apis.Keys).ToArray();
68 } 69 }
69 70
70 public IScriptApi CreateApi(string api) 71 public IScriptApi CreateApi(string api)
@@ -76,4 +77,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
76 return ret; 77 return ret;
77 } 78 }
78 } 79 }
79} 80} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
index 489c1c6..b5fa6de 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -59,16 +59,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
59 { 59 {
60 internal IScriptEngine m_ScriptEngine; 60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host; 61 internal SceneObjectPart m_host;
62 internal uint m_localID; 62 internal TaskInventoryItem m_item;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false; 63 internal bool m_CMFunctionsEnabled = false;
65 64
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
67 { 66 {
68 m_ScriptEngine = ScriptEngine; 67 m_ScriptEngine = ScriptEngine;
69 m_host = host; 68 m_host = host;
70 m_localID = localID; 69 m_item = item;
71 m_itemID = itemID;
72 70
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) 71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true; 72 m_CMFunctionsEnabled = true;
@@ -95,7 +93,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
95 public string cmDetectedCountry(int number) 93 public string cmDetectedCountry(int number)
96 { 94 {
97 m_host.AddScriptLPS(1); 95 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
99 if (detectedParams == null) 97 if (detectedParams == null)
100 return String.Empty; 98 return String.Empty;
101 return detectedParams.Country; 99 return detectedParams.Country;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index eb68038..03f4108 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -88,8 +88,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
88 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
89 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
90 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
91 protected uint m_localID; 91
92 protected UUID m_itemID; 92 /// <summary>
93 /// The item that hosts this script
94 /// </summary>
95 protected TaskInventoryItem m_item;
96
93 protected bool throwErrorOnNotImplemented = true; 97 protected bool throwErrorOnNotImplemented = true;
94 protected AsyncCommandManager AsyncCommands = null; 98 protected AsyncCommandManager AsyncCommands = null;
95 protected float m_ScriptDelayFactor = 1.0f; 99 protected float m_ScriptDelayFactor = 1.0f;
@@ -107,11 +111,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
107 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 new Dictionary<UUID, UserInfoCacheEntry>(); 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
110 115
111 protected Timer m_ShoutSayTimer; 116 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0; 117 protected int m_SayShoutCount = 0;
113 118
114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 119 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
115 { 120 {
116 m_ShoutSayTimer = new Timer(1000); 121 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed; 122 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
@@ -120,10 +125,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
120 125
121 m_ScriptEngine = ScriptEngine; 126 m_ScriptEngine = ScriptEngine;
122 m_host = host; 127 m_host = host;
123 m_localID = localID; 128 m_item = item;
124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 129 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
126 130
131 LoadLimits(); // read script limits from config.
132
133 m_TransferModule =
134 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
135 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
136
137 AsyncCommands = new AsyncCommandManager(ScriptEngine);
138 }
139
140 /* load configuration items that affect script, object and run-time behavior. */
141 private void LoadLimits()
142 {
127 m_ScriptDelayFactor = 143 m_ScriptDelayFactor =
128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 144 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
129 m_ScriptDistanceFactor = 145 m_ScriptDistanceFactor =
@@ -136,12 +152,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); 152 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
137 if (m_notecardLineReadCharsMax > 65535) 153 if (m_notecardLineReadCharsMax > 65535)
138 m_notecardLineReadCharsMax = 65535; 154 m_notecardLineReadCharsMax = 65535;
139 155 // load limits for particular subsystems.
140 m_TransferModule = 156 IConfig SMTPConfig;
141 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 157 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) {
142 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 158 // there's an smtp config, so load in the snooze time.
143 159 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
144 AsyncCommands = new AsyncCommandManager(ScriptEngine); 160 }
145 } 161 }
146 162
147 public override Object InitializeLifetimeService() 163 public override Object InitializeLifetimeService()
@@ -173,7 +189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
173 [DebuggerNonUserCode] 189 [DebuggerNonUserCode]
174 public void state(string newState) 190 public void state(string newState)
175 { 191 {
176 m_ScriptEngine.SetState(m_itemID, newState); 192 m_ScriptEngine.SetState(m_item.ItemID, newState);
177 } 193 }
178 194
179 /// <summary> 195 /// <summary>
@@ -184,7 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
184 public void llResetScript() 200 public void llResetScript()
185 { 201 {
186 m_host.AddScriptLPS(1); 202 m_host.AddScriptLPS(1);
187 m_ScriptEngine.ApiResetScript(m_itemID); 203 m_ScriptEngine.ApiResetScript(m_item.ItemID);
188 } 204 }
189 205
190 public void llResetOtherScript(string name) 206 public void llResetOtherScript(string name)
@@ -336,77 +352,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
336 } 352 }
337 } 353 }
338 354
339 protected UUID InventorySelf()
340 {
341 UUID invItemID = new UUID();
342 bool unlock = false;
343 if (!m_host.TaskInventory.IsReadLockedByMe())
344 {
345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
349 {
350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
351 {
352 invItemID = inv.Key;
353 break;
354 }
355 }
356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
360 return invItemID;
361 }
362
363 protected UUID InventoryKey(string name, int type) 355 protected UUID InventoryKey(string name, int type)
364 { 356 {
365 m_host.AddScriptLPS(1); 357 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
366 m_host.TaskInventory.LockItemsForRead(true);
367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
369 {
370 if (inv.Value.Name == name)
371 {
372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
375 {
376 return UUID.Zero;
377 }
378
379 return inv.Value.AssetID;
380 }
381 }
382
383 m_host.TaskInventory.LockItemsForRead(false);
384 return UUID.Zero;
385 }
386
387 protected UUID InventoryKey(string name)
388 {
389 m_host.AddScriptLPS(1);
390 358
391 359 if (item != null && item.Type == type)
392 m_host.TaskInventory.LockItemsForRead(true); 360 return item.AssetID;
393 361 else
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 362 return UUID.Zero;
395 {
396 if (inv.Value.Name == name)
397 {
398 m_host.TaskInventory.LockItemsForRead(false);
399 return inv.Value.AssetID;
400 }
401 }
402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
406 return UUID.Zero;
407 } 363 }
408 364
409
410 /// <summary> 365 /// <summary>
411 /// accepts a valid UUID, -or- a name of an inventory item. 366 /// accepts a valid UUID, -or- a name of an inventory item.
412 /// Returns a valid UUID or UUID.Zero if key invalid and item not found 367 /// Returns a valid UUID or UUID.Zero if key invalid and item not found
@@ -416,19 +371,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
416 /// <returns></returns> 371 /// <returns></returns>
417 protected UUID KeyOrName(string k) 372 protected UUID KeyOrName(string k)
418 { 373 {
419 UUID key = UUID.Zero; 374 UUID key;
420 375
421 // if we can parse the string as a key, use it. 376 // if we can parse the string as a key, use it.
422 if (UUID.TryParse(k, out key))
423 {
424 return key;
425 }
426 // else try to locate the name in inventory of object. found returns key, 377 // else try to locate the name in inventory of object. found returns key,
427 // not found returns UUID.Zero which will translate to the default particle texture 378 // not found returns UUID.Zero
428 else 379 if (!UUID.TryParse(k, out key))
429 { 380 {
430 return InventoryKey(k); 381 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
382
383 if (item != null)
384 key = item.AssetID;
385 else
386 key = UUID.Zero;
431 } 387 }
388
389 return key;
432 } 390 }
433 391
434 // convert a LSL_Rotation to a Quaternion 392 // convert a LSL_Rotation to a Quaternion
@@ -941,20 +899,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
941 899
942 public void llRegionSayTo(string target, int channel, string msg) 900 public void llRegionSayTo(string target, int channel, string msg)
943 { 901 {
944 string error = String.Empty;
945
946 if (msg.Length > 1023) 902 if (msg.Length > 1023)
947 msg = msg.Substring(0, 1023); 903 msg = msg.Substring(0, 1023);
948 904
949 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
950 906
907 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
908 {
909 return;
910 }
911
951 UUID TargetID; 912 UUID TargetID;
952 UUID.TryParse(target, out TargetID); 913 UUID.TryParse(target, out TargetID);
953 914
954 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 915 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
955 if (wComm != null) 916 if (wComm != null)
956 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error)) 917 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg);
957 LSLError(error);
958 } 918 }
959 919
960 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 920 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -964,7 +924,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
964 UUID.TryParse(ID, out keyID); 924 UUID.TryParse(ID, out keyID);
965 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 925 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
966 if (wComm != null) 926 if (wComm != null)
967 return wComm.Listen(m_localID, m_itemID, m_host.UUID, channelID, name, keyID, msg); 927 return wComm.Listen(m_host.LocalId, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg);
968 else 928 else
969 return -1; 929 return -1;
970 } 930 }
@@ -974,7 +934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
974 m_host.AddScriptLPS(1); 934 m_host.AddScriptLPS(1);
975 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 935 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
976 if (wComm != null) 936 if (wComm != null)
977 wComm.ListenControl(m_itemID, number, active); 937 wComm.ListenControl(m_item.ItemID, number, active);
978 } 938 }
979 939
980 public void llListenRemove(int number) 940 public void llListenRemove(int number)
@@ -982,7 +942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 m_host.AddScriptLPS(1); 942 m_host.AddScriptLPS(1);
983 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 943 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
984 if (wComm != null) 944 if (wComm != null)
985 wComm.ListenRemove(m_itemID, number); 945 wComm.ListenRemove(m_item.ItemID, number);
986 } 946 }
987 947
988 public void llSensor(string name, string id, int type, double range, double arc) 948 public void llSensor(string name, string id, int type, double range, double arc)
@@ -991,7 +951,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
991 UUID keyID = UUID.Zero; 951 UUID keyID = UUID.Zero;
992 UUID.TryParse(id, out keyID); 952 UUID.TryParse(id, out keyID);
993 953
994 AsyncCommands.SensorRepeatPlugin.SenseOnce(m_localID, m_itemID, name, keyID, type, range, arc, m_host); 954 AsyncCommands.SensorRepeatPlugin.SenseOnce(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, m_host);
995 } 955 }
996 956
997 public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) 957 public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate)
@@ -1000,13 +960,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1000 UUID keyID = UUID.Zero; 960 UUID keyID = UUID.Zero;
1001 UUID.TryParse(id, out keyID); 961 UUID.TryParse(id, out keyID);
1002 962
1003 AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_localID, m_itemID, name, keyID, type, range, arc, rate, m_host); 963 AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, rate, m_host);
1004 } 964 }
1005 965
1006 public void llSensorRemove() 966 public void llSensorRemove()
1007 { 967 {
1008 m_host.AddScriptLPS(1); 968 m_host.AddScriptLPS(1);
1009 AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_localID, m_itemID); 969 AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID);
1010 } 970 }
1011 971
1012 public string resolveName(UUID objecUUID) 972 public string resolveName(UUID objecUUID)
@@ -1047,7 +1007,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1047 public LSL_String llDetectedName(int number) 1007 public LSL_String llDetectedName(int number)
1048 { 1008 {
1049 m_host.AddScriptLPS(1); 1009 m_host.AddScriptLPS(1);
1050 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1010 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1051 if (detectedParams == null) 1011 if (detectedParams == null)
1052 return String.Empty; 1012 return String.Empty;
1053 return detectedParams.Name; 1013 return detectedParams.Name;
@@ -1056,7 +1016,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1056 public LSL_String llDetectedKey(int number) 1016 public LSL_String llDetectedKey(int number)
1057 { 1017 {
1058 m_host.AddScriptLPS(1); 1018 m_host.AddScriptLPS(1);
1059 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1019 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1060 if (detectedParams == null) 1020 if (detectedParams == null)
1061 return String.Empty; 1021 return String.Empty;
1062 return detectedParams.Key.ToString(); 1022 return detectedParams.Key.ToString();
@@ -1065,7 +1025,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1065 public LSL_String llDetectedOwner(int number) 1025 public LSL_String llDetectedOwner(int number)
1066 { 1026 {
1067 m_host.AddScriptLPS(1); 1027 m_host.AddScriptLPS(1);
1068 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1028 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1069 if (detectedParams == null) 1029 if (detectedParams == null)
1070 return String.Empty; 1030 return String.Empty;
1071 return detectedParams.Owner.ToString(); 1031 return detectedParams.Owner.ToString();
@@ -1074,7 +1034,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1074 public LSL_Integer llDetectedType(int number) 1034 public LSL_Integer llDetectedType(int number)
1075 { 1035 {
1076 m_host.AddScriptLPS(1); 1036 m_host.AddScriptLPS(1);
1077 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1037 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1078 if (detectedParams == null) 1038 if (detectedParams == null)
1079 return 0; 1039 return 0;
1080 return new LSL_Integer(detectedParams.Type); 1040 return new LSL_Integer(detectedParams.Type);
@@ -1083,7 +1043,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1083 public LSL_Vector llDetectedPos(int number) 1043 public LSL_Vector llDetectedPos(int number)
1084 { 1044 {
1085 m_host.AddScriptLPS(1); 1045 m_host.AddScriptLPS(1);
1086 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1046 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1087 if (detectedParams == null) 1047 if (detectedParams == null)
1088 return new LSL_Vector(); 1048 return new LSL_Vector();
1089 return detectedParams.Position; 1049 return detectedParams.Position;
@@ -1092,7 +1052,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1092 public LSL_Vector llDetectedVel(int number) 1052 public LSL_Vector llDetectedVel(int number)
1093 { 1053 {
1094 m_host.AddScriptLPS(1); 1054 m_host.AddScriptLPS(1);
1095 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1055 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1096 if (detectedParams == null) 1056 if (detectedParams == null)
1097 return new LSL_Vector(); 1057 return new LSL_Vector();
1098 return detectedParams.Velocity; 1058 return detectedParams.Velocity;
@@ -1101,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 public LSL_Vector llDetectedGrab(int number) 1061 public LSL_Vector llDetectedGrab(int number)
1102 { 1062 {
1103 m_host.AddScriptLPS(1); 1063 m_host.AddScriptLPS(1);
1104 DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number); 1064 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1105 if (parms == null) 1065 if (parms == null)
1106 return new LSL_Vector(0, 0, 0); 1066 return new LSL_Vector(0, 0, 0);
1107 1067
@@ -1111,7 +1071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1111 public LSL_Rotation llDetectedRot(int number) 1071 public LSL_Rotation llDetectedRot(int number)
1112 { 1072 {
1113 m_host.AddScriptLPS(1); 1073 m_host.AddScriptLPS(1);
1114 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1074 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1115 if (detectedParams == null) 1075 if (detectedParams == null)
1116 return new LSL_Rotation(); 1076 return new LSL_Rotation();
1117 return detectedParams.Rotation; 1077 return detectedParams.Rotation;
@@ -1120,7 +1080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1120 public LSL_Integer llDetectedGroup(int number) 1080 public LSL_Integer llDetectedGroup(int number)
1121 { 1081 {
1122 m_host.AddScriptLPS(1); 1082 m_host.AddScriptLPS(1);
1123 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number); 1083 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1124 if (detectedParams == null) 1084 if (detectedParams == null)
1125 return new LSL_Integer(0); 1085 return new LSL_Integer(0);
1126 if (m_host.GroupID == detectedParams.Group) 1086 if (m_host.GroupID == detectedParams.Group)
@@ -1131,7 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1131 public LSL_Integer llDetectedLinkNumber(int number) 1091 public LSL_Integer llDetectedLinkNumber(int number)
1132 { 1092 {
1133 m_host.AddScriptLPS(1); 1093 m_host.AddScriptLPS(1);
1134 DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number); 1094 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1135 if (parms == null) 1095 if (parms == null)
1136 return new LSL_Integer(0); 1096 return new LSL_Integer(0);
1137 1097
@@ -1144,7 +1104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1144 public LSL_Vector llDetectedTouchBinormal(int index) 1104 public LSL_Vector llDetectedTouchBinormal(int index)
1145 { 1105 {
1146 m_host.AddScriptLPS(1); 1106 m_host.AddScriptLPS(1);
1147 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1107 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1148 if (detectedParams == null) 1108 if (detectedParams == null)
1149 return new LSL_Vector(); 1109 return new LSL_Vector();
1150 return detectedParams.TouchBinormal; 1110 return detectedParams.TouchBinormal;
@@ -1156,7 +1116,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1156 public LSL_Integer llDetectedTouchFace(int index) 1116 public LSL_Integer llDetectedTouchFace(int index)
1157 { 1117 {
1158 m_host.AddScriptLPS(1); 1118 m_host.AddScriptLPS(1);
1159 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1119 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1160 if (detectedParams == null) 1120 if (detectedParams == null)
1161 return new LSL_Integer(-1); 1121 return new LSL_Integer(-1);
1162 return new LSL_Integer(detectedParams.TouchFace); 1122 return new LSL_Integer(detectedParams.TouchFace);
@@ -1168,7 +1128,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1168 public LSL_Vector llDetectedTouchNormal(int index) 1128 public LSL_Vector llDetectedTouchNormal(int index)
1169 { 1129 {
1170 m_host.AddScriptLPS(1); 1130 m_host.AddScriptLPS(1);
1171 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1131 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1172 if (detectedParams == null) 1132 if (detectedParams == null)
1173 return new LSL_Vector(); 1133 return new LSL_Vector();
1174 return detectedParams.TouchNormal; 1134 return detectedParams.TouchNormal;
@@ -1180,7 +1140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1180 public LSL_Vector llDetectedTouchPos(int index) 1140 public LSL_Vector llDetectedTouchPos(int index)
1181 { 1141 {
1182 m_host.AddScriptLPS(1); 1142 m_host.AddScriptLPS(1);
1183 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1143 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1184 if (detectedParams == null) 1144 if (detectedParams == null)
1185 return new LSL_Vector(); 1145 return new LSL_Vector();
1186 return detectedParams.TouchPos; 1146 return detectedParams.TouchPos;
@@ -1192,7 +1152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1192 public LSL_Vector llDetectedTouchST(int index) 1152 public LSL_Vector llDetectedTouchST(int index)
1193 { 1153 {
1194 m_host.AddScriptLPS(1); 1154 m_host.AddScriptLPS(1);
1195 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1155 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1196 if (detectedParams == null) 1156 if (detectedParams == null)
1197 return new LSL_Vector(-1.0, -1.0, 0.0); 1157 return new LSL_Vector(-1.0, -1.0, 0.0);
1198 return detectedParams.TouchST; 1158 return detectedParams.TouchST;
@@ -1204,7 +1164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1204 public LSL_Vector llDetectedTouchUV(int index) 1164 public LSL_Vector llDetectedTouchUV(int index)
1205 { 1165 {
1206 m_host.AddScriptLPS(1); 1166 m_host.AddScriptLPS(1);
1207 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index); 1167 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1208 if (detectedParams == null) 1168 if (detectedParams == null)
1209 return new LSL_Vector(-1.0, -1.0, 0.0); 1169 return new LSL_Vector(-1.0, -1.0, 0.0);
1210 return detectedParams.TouchUV; 1170 return detectedParams.TouchUV;
@@ -1903,12 +1863,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1903 1863
1904 return rgb; 1864 return rgb;
1905 } 1865 }
1866
1906 if (face >= 0 && face < GetNumberOfSides(part)) 1867 if (face >= 0 && face < GetNumberOfSides(part))
1907 { 1868 {
1908 texcolor = tex.GetFace((uint)face).RGBA; 1869 texcolor = tex.GetFace((uint)face).RGBA;
1909 rgb.x = texcolor.R; 1870 rgb.x = texcolor.R;
1910 rgb.y = texcolor.G; 1871 rgb.y = texcolor.G;
1911 rgb.z = texcolor.B; 1872 rgb.z = texcolor.B;
1873
1912 return rgb; 1874 return rgb;
1913 } 1875 }
1914 else 1876 else
@@ -2948,20 +2910,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2948 2910
2949 public LSL_Integer llGiveMoney(string destination, int amount) 2911 public LSL_Integer llGiveMoney(string destination, int amount)
2950 { 2912 {
2951 UUID invItemID=InventorySelf();
2952 if (invItemID == UUID.Zero)
2953 return 0;
2954
2955 m_host.AddScriptLPS(1); 2913 m_host.AddScriptLPS(1);
2956 2914
2957 m_host.TaskInventory.LockItemsForRead(true); 2915 if (m_item.PermsGranter == UUID.Zero)
2958 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2959 m_host.TaskInventory.LockItemsForRead(false);
2960
2961 if (item.PermsGranter == UUID.Zero)
2962 return 0; 2916 return 0;
2963 2917
2964 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) 2918 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
2965 { 2919 {
2966 LSLError("No permissions to give money"); 2920 LSLError("No permissions to give money");
2967 return 0; 2921 return 0;
@@ -3148,11 +3102,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3148 sec = m_MinTimerInterval; 3102 sec = m_MinTimerInterval;
3149 m_host.AddScriptLPS(1); 3103 m_host.AddScriptLPS(1);
3150 // Setting timer repeat 3104 // Setting timer repeat
3151 AsyncCommands.TimerPlugin.SetTimerEvent(m_localID, m_itemID, sec); 3105 AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec);
3152 } 3106 }
3153 3107
3154 public virtual void llSleep(double sec) 3108 public virtual void llSleep(double sec)
3155 { 3109 {
3110// m_log.Info("llSleep snoozing " + sec + "s.");
3156 m_host.AddScriptLPS(1); 3111 m_host.AddScriptLPS(1);
3157 Thread.Sleep((int)(sec * 1000)); 3112 Thread.Sleep((int)(sec * 1000));
3158 } 3113 }
@@ -3211,29 +3166,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3211 3166
3212 public void llTakeControls(int controls, int accept, int pass_on) 3167 public void llTakeControls(int controls, int accept, int pass_on)
3213 { 3168 {
3214 TaskInventoryItem item; 3169 if (m_item.PermsGranter != UUID.Zero)
3215
3216 m_host.TaskInventory.LockItemsForRead(true);
3217 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3218 { 3170 {
3219 m_host.TaskInventory.LockItemsForRead(false); 3171 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3220 return;
3221 }
3222 else
3223 {
3224 item = m_host.TaskInventory[InventorySelf()];
3225 }
3226 m_host.TaskInventory.LockItemsForRead(false);
3227
3228 if (item.PermsGranter != UUID.Zero)
3229 {
3230 ScenePresence presence = World.GetScenePresence(item.PermsGranter);
3231 3172
3232 if (presence != null) 3173 if (presence != null)
3233 { 3174 {
3234 if ((item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 3175 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
3235 { 3176 {
3236 presence.RegisterControlEventsToScript(controls, accept, pass_on, m_localID, m_itemID); 3177 presence.RegisterControlEventsToScript(controls, accept, pass_on, m_host.LocalId, m_item.ItemID);
3237 } 3178 }
3238 } 3179 }
3239 } 3180 }
@@ -3243,38 +3184,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3243 3184
3244 public void llReleaseControls() 3185 public void llReleaseControls()
3245 { 3186 {
3246 TaskInventoryItem item;
3247
3248 m_host.TaskInventory.LockItemsForRead(true);
3249 lock (m_host.TaskInventory)
3250 {
3251
3252 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3253 {
3254 m_host.TaskInventory.LockItemsForRead(false);
3255 return;
3256 }
3257 else
3258 {
3259 item = m_host.TaskInventory[InventorySelf()];
3260 }
3261 }
3262 m_host.TaskInventory.LockItemsForRead(false);
3263
3264 m_host.AddScriptLPS(1); 3187 m_host.AddScriptLPS(1);
3265 3188
3266 if (item.PermsGranter != UUID.Zero) 3189 if (m_item.PermsGranter != UUID.Zero)
3267 { 3190 {
3268 ScenePresence presence = World.GetScenePresence(item.PermsGranter); 3191 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3269 3192
3270 if (presence != null) 3193 if (presence != null)
3271 { 3194 {
3272 if ((item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 3195 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
3273 { 3196 {
3274 // Unregister controls from Presence 3197 // Unregister controls from Presence
3275 presence.UnRegisterControlEventsToScript(m_localID, m_itemID); 3198 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3276 // Remove Take Control permission. 3199 // Remove Take Control permission.
3277 item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3200 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3278 } 3201 }
3279 } 3202 }
3280 } 3203 }
@@ -3287,86 +3210,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3287 m_UrlModule.ReleaseURL(url); 3210 m_UrlModule.ReleaseURL(url);
3288 } 3211 }
3289 3212
3290 public void llAttachToAvatar(int attachment) 3213 /// <summary>
3214 /// Attach the object containing this script to the avatar that owns it.
3215 /// </summary>
3216 /// <param name='attachment'>The attachment point (e.g. ATTACH_CHEST)</param>
3217 /// <returns>true if the attach suceeded, false if it did not</returns>
3218 public bool AttachToAvatar(int attachmentPoint)
3291 { 3219 {
3292 m_host.AddScriptLPS(1); 3220 SceneObjectGroup grp = m_host.ParentGroup;
3221 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
3293 3222
3294 TaskInventoryItem item; 3223 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3295
3296 m_host.TaskInventory.LockItemsForRead(true);
3297 3224
3298 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3225 if (attachmentsModule != null)
3299 { 3226 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false);
3300 m_host.TaskInventory.LockItemsForRead(false);
3301 return;
3302 }
3303 else 3227 else
3304 { 3228 return false;
3305 item = m_host.TaskInventory[InventorySelf()]; 3229 }
3306 }
3307
3308 m_host.TaskInventory.LockItemsForRead(false);
3309 3230
3310 if (item.PermsGranter != m_host.OwnerID) 3231 /// <summary>
3311 return; 3232 /// Detach the object containing this script from the avatar it is attached to.
3233 /// </summary>
3234 /// <remarks>
3235 /// Nothing happens if the object is not attached.
3236 /// </remarks>
3237 public void DetachFromAvatar()
3238 {
3239 Util.FireAndForget(DetachWrapper, m_host);
3240 }
3312 3241
3313 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 3242 private void DetachWrapper(object o)
3314 { 3243 {
3315 SceneObjectGroup grp = m_host.ParentGroup; 3244 SceneObjectPart host = (SceneObjectPart)o;
3316 3245
3317 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3246 SceneObjectGroup grp = host.ParentGroup;
3247 UUID itemID = grp.FromItemID;
3248 ScenePresence presence = World.GetScenePresence(host.OwnerID);
3318 3249
3319 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3250 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3320 if (attachmentsModule != null) 3251 if (attachmentsModule != null)
3321 attachmentsModule.AttachObject(presence, grp, (uint)attachment, false); 3252 attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
3322 }
3323 } 3253 }
3324 3254
3325 public void llDetachFromAvatar() 3255 public void llAttachToAvatar(int attachmentPoint)
3326 { 3256 {
3327 m_host.AddScriptLPS(1); 3257 m_host.AddScriptLPS(1);
3328 3258
3329 if (m_host.ParentGroup.AttachmentPoint == 0) 3259 if (m_item.PermsGranter != m_host.OwnerID)
3330 return; 3260 return;
3331 3261
3332 TaskInventoryItem item; 3262 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
3263 AttachToAvatar(attachmentPoint);
3264 }
3333 3265
3334 m_host.TaskInventory.LockItemsForRead(true); 3266 public void llDetachFromAvatar()
3267 {
3268 m_host.AddScriptLPS(1);
3335 3269
3336 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3270 if (m_host.ParentGroup.AttachmentPoint == 0)
3337 {
3338 m_host.TaskInventory.LockItemsForRead(false);
3339 return; 3271 return;
3340 }
3341 else
3342 {
3343 item = m_host.TaskInventory[InventorySelf()];
3344 }
3345 m_host.TaskInventory.LockItemsForRead(false);
3346
3347 3272
3348 if (item.PermsGranter != m_host.OwnerID) 3273 if (m_item.PermsGranter != m_host.OwnerID)
3349 return; 3274 return;
3350 3275
3351 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 3276 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
3352 { 3277 DetachFromAvatar();
3353 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3354 if (attachmentsModule != null)
3355 Util.FireAndForget(DetachWrapper, m_host);
3356 }
3357 }
3358
3359 private void DetachWrapper(object o)
3360 {
3361 SceneObjectPart host = (SceneObjectPart)o;
3362
3363 SceneObjectGroup grp = host.ParentGroup;
3364 UUID itemID = grp.FromItemID;
3365 ScenePresence presence = World.GetScenePresence(host.OwnerID);
3366
3367 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3368 if (attachmentsModule != null)
3369 attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
3370 } 3278 }
3371 3279
3372 public void llTakeCamera(string avatar) 3280 public void llTakeCamera(string avatar)
@@ -3487,7 +3395,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3487 } 3395 }
3488 3396
3489 emailModule.SendEmail(m_host.UUID, address, subject, message); 3397 emailModule.SendEmail(m_host.UUID, address, subject, message);
3490 ScriptSleep(15000); 3398 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3491 } 3399 }
3492 3400
3493 public void llGetNextEmail(string address, string subject) 3401 public void llGetNextEmail(string address, string subject)
@@ -3524,6 +3432,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3524 return m_host.UUID.ToString(); 3432 return m_host.UUID.ToString();
3525 } 3433 }
3526 3434
3435 public LSL_Key llGenerateKey()
3436 {
3437 m_host.AddScriptLPS(1);
3438 return UUID.Random().ToString();
3439 }
3440
3527 public void llSetBuoyancy(double buoyancy) 3441 public void llSetBuoyancy(double buoyancy)
3528 { 3442 {
3529 m_host.AddScriptLPS(1); 3443 m_host.AddScriptLPS(1);
@@ -3570,7 +3484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3570 m_host.AddScriptLPS(1); 3484 m_host.AddScriptLPS(1);
3571 try 3485 try
3572 { 3486 {
3573 m_ScriptEngine.SetMinEventDelay(m_itemID, delay); 3487 m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay);
3574 } 3488 }
3575 catch (NotImplementedException) 3489 catch (NotImplementedException)
3576 { 3490 {
@@ -3623,29 +3537,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3623 { 3537 {
3624 m_host.AddScriptLPS(1); 3538 m_host.AddScriptLPS(1);
3625 3539
3626 UUID invItemID = InventorySelf(); 3540 if (m_item.PermsGranter == UUID.Zero)
3627 if (invItemID == UUID.Zero)
3628 return;
3629
3630 TaskInventoryItem item;
3631
3632 m_host.TaskInventory.LockItemsForRead(true);
3633 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3634 {
3635 m_host.TaskInventory.LockItemsForRead(false);
3636 return;
3637 }
3638 else
3639 {
3640 item = m_host.TaskInventory[InventorySelf()];
3641 }
3642 m_host.TaskInventory.LockItemsForRead(false);
3643 if (item.PermsGranter == UUID.Zero)
3644 return; 3541 return;
3645 3542
3646 if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) 3543 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3647 { 3544 {
3648 ScenePresence presence = World.GetScenePresence(item.PermsGranter); 3545 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3649 3546
3650 if (presence != null) 3547 if (presence != null)
3651 { 3548 {
@@ -3663,41 +3560,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3663 { 3560 {
3664 m_host.AddScriptLPS(1); 3561 m_host.AddScriptLPS(1);
3665 3562
3666 UUID invItemID=InventorySelf(); 3563 if (m_item.PermsGranter == UUID.Zero)
3667 if (invItemID == UUID.Zero)
3668 return; 3564 return;
3669 3565
3670 TaskInventoryItem item; 3566 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3671
3672 m_host.TaskInventory.LockItemsForRead(true);
3673 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3674 { 3567 {
3675 m_host.TaskInventory.LockItemsForRead(false); 3568 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3676 return;
3677 }
3678 else
3679 {
3680 item = m_host.TaskInventory[InventorySelf()];
3681 }
3682 m_host.TaskInventory.LockItemsForRead(false);
3683
3684
3685 if (item.PermsGranter == UUID.Zero)
3686 return;
3687
3688 if ((item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3689 {
3690 UUID animID = new UUID();
3691
3692 if (!UUID.TryParse(anim, out animID))
3693 {
3694 animID=InventoryKey(anim);
3695 }
3696
3697 ScenePresence presence = World.GetScenePresence(item.PermsGranter);
3698 3569
3699 if (presence != null) 3570 if (presence != null)
3700 { 3571 {
3572 UUID animID = KeyOrName(anim);
3573
3701 if (animID == UUID.Zero) 3574 if (animID == UUID.Zero)
3702 presence.Animator.RemoveAnimation(anim); 3575 presence.Animator.RemoveAnimation(anim);
3703 else 3576 else
@@ -3730,44 +3603,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3730 public LSL_Integer llGetStartParameter() 3603 public LSL_Integer llGetStartParameter()
3731 { 3604 {
3732 m_host.AddScriptLPS(1); 3605 m_host.AddScriptLPS(1);
3733 return m_ScriptEngine.GetStartParameter(m_itemID); 3606 return m_ScriptEngine.GetStartParameter(m_item.ItemID);
3734 } 3607 }
3735 3608
3736 public void llRequestPermissions(string agent, int perm) 3609 public void llRequestPermissions(string agent, int perm)
3737 { 3610 {
3738 UUID agentID = new UUID(); 3611 UUID agentID;
3739 3612
3740 if (!UUID.TryParse(agent, out agentID)) 3613 if (!UUID.TryParse(agent, out agentID))
3741 return; 3614 return;
3742 3615
3743 UUID invItemID = InventorySelf();
3744
3745 if (invItemID == UUID.Zero)
3746 return; // Not in a prim? How??
3747
3748 TaskInventoryItem item;
3749
3750
3751 m_host.TaskInventory.LockItemsForRead(true);
3752 if (!m_host.TaskInventory.ContainsKey(invItemID))
3753 {
3754 m_host.TaskInventory.LockItemsForRead(false);
3755 return;
3756 }
3757 else
3758 {
3759 item = m_host.TaskInventory[invItemID];
3760 }
3761 m_host.TaskInventory.LockItemsForRead(false);
3762
3763 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3616 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3764 { 3617 {
3765 llReleaseControls(); 3618 llReleaseControls();
3766 3619
3767 item.PermsGranter = UUID.Zero; 3620 m_item.PermsGranter = UUID.Zero;
3768 item.PermsMask = 0; 3621 m_item.PermsMask = 0;
3769 3622
3770 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3623 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3771 "run_time_permissions", new Object[] { 3624 "run_time_permissions", new Object[] {
3772 new LSL_Integer(0) }, 3625 new LSL_Integer(0) },
3773 new DetectParams[0])); 3626 new DetectParams[0]));
@@ -3775,7 +3628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3775 return; 3628 return;
3776 } 3629 }
3777 3630
3778 if (item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3631 if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3779 llReleaseControls(); 3632 llReleaseControls();
3780 3633
3781 m_host.AddScriptLPS(1); 3634 m_host.AddScriptLPS(1);
@@ -3792,11 +3645,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3792 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3645 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3793 { 3646 {
3794 m_host.TaskInventory.LockItemsForWrite(true); 3647 m_host.TaskInventory.LockItemsForWrite(true);
3795 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3648 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3796 m_host.TaskInventory[invItemID].PermsMask = perm; 3649 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3797 m_host.TaskInventory.LockItemsForWrite(false); 3650 m_host.TaskInventory.LockItemsForWrite(false);
3798 3651
3799 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3652 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3800 "run_time_permissions", new Object[] { 3653 "run_time_permissions", new Object[] {
3801 new LSL_Integer(perm) }, 3654 new LSL_Integer(perm) },
3802 new DetectParams[0])); 3655 new DetectParams[0]));
@@ -3831,11 +3684,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3831 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3684 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3832 { 3685 {
3833 m_host.TaskInventory.LockItemsForWrite(true); 3686 m_host.TaskInventory.LockItemsForWrite(true);
3834 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3687 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3835 m_host.TaskInventory[invItemID].PermsMask = perm; 3688 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3836 m_host.TaskInventory.LockItemsForWrite(false); 3689 m_host.TaskInventory.LockItemsForWrite(false);
3837 3690
3838 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3691 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3839 "run_time_permissions", new Object[] { 3692 "run_time_permissions", new Object[] {
3840 new LSL_Integer(perm) }, 3693 new LSL_Integer(perm) },
3841 new DetectParams[0])); 3694 new DetectParams[0]));
@@ -3846,9 +3699,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3846 } 3699 }
3847 3700
3848 ScenePresence presence = World.GetScenePresence(agentID); 3701 ScenePresence presence = World.GetScenePresence(agentID);
3849
3850 if (presence != null) 3702 if (presence != null)
3851 { 3703 {
3704 // If permissions are being requested from an NPC and were not implicitly granted above then
3705 // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner
3706 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
3707 if (npcModule != null && npcModule.IsNPC(agentID, World))
3708 {
3709 if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID)
3710 {
3711 lock (m_host.TaskInventory)
3712 {
3713 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3714 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3715 }
3716
3717 m_ScriptEngine.PostScriptEvent(
3718 m_item.ItemID,
3719 new EventParams(
3720 "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0]));
3721 }
3722
3723 // it is an NPC, exit even if the permissions werent granted above, they are not going to answer
3724 // the question!
3725 return;
3726 }
3727
3852 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID); 3728 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID);
3853 if (ownerName == String.Empty) 3729 if (ownerName == String.Empty)
3854 ownerName = "(hippos)"; 3730 ownerName = "(hippos)";
@@ -3856,8 +3732,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 if (!m_waitingForScriptAnswer) 3732 if (!m_waitingForScriptAnswer)
3857 { 3733 {
3858 m_host.TaskInventory.LockItemsForWrite(true); 3734 m_host.TaskInventory.LockItemsForWrite(true);
3859 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3735 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3860 m_host.TaskInventory[invItemID].PermsMask = 0; 3736 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3861 m_host.TaskInventory.LockItemsForWrite(false); 3737 m_host.TaskInventory.LockItemsForWrite(false);
3862 3738
3863 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3739 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
@@ -3865,16 +3741,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3865 } 3741 }
3866 3742
3867 presence.ControllingClient.SendScriptQuestion( 3743 presence.ControllingClient.SendScriptQuestion(
3868 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, invItemID, perm); 3744 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm);
3869 3745
3870 return; 3746 return;
3871 } 3747 }
3872 3748
3873 // Requested agent is not in range, refuse perms 3749 // Requested agent is not in range, refuse perms
3874 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3750 m_ScriptEngine.PostScriptEvent(
3875 "run_time_permissions", new Object[] { 3751 m_item.ItemID,
3876 new LSL_Integer(0) }, 3752 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0]));
3877 new DetectParams[0]));
3878 } 3753 }
3879 3754
3880 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer) 3755 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer)
@@ -3882,24 +3757,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3882 if (taskID != m_host.UUID) 3757 if (taskID != m_host.UUID)
3883 return; 3758 return;
3884 3759
3885 UUID invItemID = InventorySelf(); 3760 client.OnScriptAnswer -= handleScriptAnswer;
3886 3761 m_waitingForScriptAnswer = false;
3887 if (invItemID == UUID.Zero)
3888 return;
3889
3890 client.OnScriptAnswer-=handleScriptAnswer;
3891 m_waitingForScriptAnswer=false;
3892 3762
3893 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3763 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3894 llReleaseControls(); 3764 llReleaseControls();
3895 3765
3896
3897 m_host.TaskInventory.LockItemsForWrite(true); 3766 m_host.TaskInventory.LockItemsForWrite(true);
3898 m_host.TaskInventory[invItemID].PermsMask = answer; 3767 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3899 m_host.TaskInventory.LockItemsForWrite(false); 3768 m_host.TaskInventory.LockItemsForWrite(false);
3900 3769
3901 3770 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3902 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3903 "run_time_permissions", new Object[] { 3771 "run_time_permissions", new Object[] {
3904 new LSL_Integer(answer) }, 3772 new LSL_Integer(answer) },
3905 new DetectParams[0])); 3773 new DetectParams[0]));
@@ -3909,41 +3777,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3909 { 3777 {
3910 m_host.AddScriptLPS(1); 3778 m_host.AddScriptLPS(1);
3911 3779
3912 m_host.TaskInventory.LockItemsForRead(true); 3780 return m_item.PermsGranter.ToString();
3913
3914 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3915 {
3916 if (item.Type == 10 && item.ItemID == m_itemID)
3917 {
3918 m_host.TaskInventory.LockItemsForRead(false);
3919 return item.PermsGranter.ToString();
3920 }
3921 }
3922 m_host.TaskInventory.LockItemsForRead(false);
3923
3924 return UUID.Zero.ToString();
3925 } 3781 }
3926 3782
3927 public LSL_Integer llGetPermissions() 3783 public LSL_Integer llGetPermissions()
3928 { 3784 {
3929 m_host.AddScriptLPS(1); 3785 m_host.AddScriptLPS(1);
3930 3786
3931 m_host.TaskInventory.LockItemsForRead(true); 3787 int perms = m_item.PermsMask;
3932 3788
3933 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3789 if (m_automaticLinkPermission)
3934 { 3790 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3935 if (item.Type == 10 && item.ItemID == m_itemID)
3936 {
3937 int perms = item.PermsMask;
3938 if (m_automaticLinkPermission)
3939 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3940 m_host.TaskInventory.LockItemsForRead(false);
3941 return perms;
3942 }
3943 }
3944 m_host.TaskInventory.LockItemsForRead(false);
3945 3791
3946 return 0; 3792 return perms;
3947 } 3793 }
3948 3794
3949 public LSL_Integer llGetLinkNumber() 3795 public LSL_Integer llGetLinkNumber()
@@ -3981,18 +3827,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3981 public void llCreateLink(string target, int parent) 3827 public void llCreateLink(string target, int parent)
3982 { 3828 {
3983 m_host.AddScriptLPS(1); 3829 m_host.AddScriptLPS(1);
3984 UUID invItemID = InventorySelf(); 3830
3985 UUID targetID; 3831 UUID targetID;
3986 3832
3987 if (!UUID.TryParse(target, out targetID)) 3833 if (!UUID.TryParse(target, out targetID))
3988 return; 3834 return;
3989 3835
3990 TaskInventoryItem item; 3836 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3991 m_host.TaskInventory.LockItemsForRead(true);
3992 item = m_host.TaskInventory[invItemID];
3993 m_host.TaskInventory.LockItemsForRead(false);
3994
3995 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3996 && !m_automaticLinkPermission) 3837 && !m_automaticLinkPermission)
3997 { 3838 {
3998 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3839 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
@@ -4000,7 +3841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4000 } 3841 }
4001 3842
4002 IClientAPI client = null; 3843 IClientAPI client = null;
4003 ScenePresence sp = World.GetScenePresence(item.PermsGranter); 3844 ScenePresence sp = World.GetScenePresence(m_item.PermsGranter);
4004 if (sp != null) 3845 if (sp != null)
4005 client = sp.ControllingClient; 3846 client = sp.ControllingClient;
4006 3847
@@ -4046,18 +3887,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 public void llBreakLink(int linknum) 3887 public void llBreakLink(int linknum)
4047 { 3888 {
4048 m_host.AddScriptLPS(1); 3889 m_host.AddScriptLPS(1);
4049 UUID invItemID = InventorySelf();
4050 3890
4051 m_host.TaskInventory.LockItemsForRead(true); 3891 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4052 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3892 && !m_automaticLinkPermission)
4053 && !m_automaticLinkPermission) 3893 {
4054 { 3894 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4055 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3895 return;
4056 m_host.TaskInventory.LockItemsForRead(false); 3896 }
4057 return; 3897
4058 }
4059 m_host.TaskInventory.LockItemsForRead(false);
4060
4061 if (linknum < ScriptBaseClass.LINK_THIS) 3898 if (linknum < ScriptBaseClass.LINK_THIS)
4062 return; 3899 return;
4063 3900
@@ -4156,12 +3993,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4156 { 3993 {
4157 m_host.AddScriptLPS(1); 3994 m_host.AddScriptLPS(1);
4158 3995
4159 UUID invItemID = InventorySelf(); 3996 TaskInventoryItem item = m_item;
4160
4161 TaskInventoryItem item;
4162 m_host.TaskInventory.LockItemsForRead(true);
4163 item = m_host.TaskInventory[invItemID];
4164 m_host.TaskInventory.LockItemsForRead(false);
4165 3997
4166 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3998 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4167 && !m_automaticLinkPermission) 3999 && !m_automaticLinkPermission)
@@ -4472,7 +4304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4472 { 4304 {
4473 if (item.Name == name) 4305 if (item.Name == name)
4474 { 4306 {
4475 if (item.ItemID == m_itemID) 4307 if (item.ItemID == m_item.ItemID)
4476 throw new ScriptDeleteException(); 4308 throw new ScriptDeleteException();
4477 else 4309 else
4478 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4310 m_host.Inventory.RemoveInventoryItem(item.ItemID);
@@ -4606,8 +4438,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4606 UUID rq = UUID.Random(); 4438 UUID rq = UUID.Random();
4607 4439
4608 UUID tid = AsyncCommands. 4440 UUID tid = AsyncCommands.
4609 DataserverPlugin.RegisterRequest(m_localID, 4441 DataserverPlugin.RegisterRequest(m_host.LocalId,
4610 m_itemID, rq.ToString()); 4442 m_item.ItemID, rq.ToString());
4611 4443
4612 AsyncCommands. 4444 AsyncCommands.
4613 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4445 DataserverPlugin.DataserverReply(rq.ToString(), reply);
@@ -4634,8 +4466,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4634 if (item.Type == 3 && item.Name == name) 4466 if (item.Type == 3 && item.Name == name)
4635 { 4467 {
4636 UUID tid = AsyncCommands. 4468 UUID tid = AsyncCommands.
4637 DataserverPlugin.RegisterRequest(m_localID, 4469 DataserverPlugin.RegisterRequest(m_host.LocalId,
4638 m_itemID, item.AssetID.ToString()); 4470 m_item.ItemID, item.AssetID.ToString());
4639 4471
4640 Vector3 region = new Vector3( 4472 Vector3 region = new Vector3(
4641 World.RegionInfo.RegionLocX * Constants.RegionSize, 4473 World.RegionInfo.RegionLocX * Constants.RegionSize,
@@ -5040,22 +4872,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5040 4872
5041 public LSL_String llGetScriptName() 4873 public LSL_String llGetScriptName()
5042 { 4874 {
5043 string result = String.Empty;
5044
5045 m_host.AddScriptLPS(1); 4875 m_host.AddScriptLPS(1);
5046 4876
5047 m_host.TaskInventory.LockItemsForRead(true); 4877 return m_item.Name != null ? m_item.Name : String.Empty;
5048 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
5049 {
5050 if (item.Type == 10 && item.ItemID == m_itemID)
5051 {
5052 result = item.Name!=null?item.Name:String.Empty;
5053 break;
5054 }
5055 }
5056 m_host.TaskInventory.LockItemsForRead(false);
5057
5058 return result;
5059 } 4878 }
5060 4879
5061 public LSL_Integer llGetLinkNumberOfSides(int link) 4880 public LSL_Integer llGetLinkNumberOfSides(int link)
@@ -6340,7 +6159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6340 if (m_host.OwnerID == land.LandData.OwnerID) 6159 if (m_host.OwnerID == land.LandData.OwnerID)
6341 { 6160 {
6342 Vector3 pos = World.GetNearestAllowedPosition(presence, land); 6161 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6343 presence.TeleportWithMomentum(pos); 6162 presence.TeleportWithMomentum(pos, null);
6344 presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); 6163 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6345 } 6164 }
6346 } 6165 }
@@ -7287,14 +7106,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7287 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 7106 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7288 if (xmlrpcMod.IsEnabled()) 7107 if (xmlrpcMod.IsEnabled())
7289 { 7108 {
7290 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_itemID, UUID.Zero); 7109 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero);
7291 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); 7110 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
7292 if (xmlRpcRouter != null) 7111 if (xmlRpcRouter != null)
7293 { 7112 {
7294 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName; 7113 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName;
7295 7114
7296 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID, 7115 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID,
7297 m_itemID, String.Format("http://{0}:{1}/", ExternalHostName, 7116 m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName,
7298 xmlrpcMod.Port.ToString())); 7117 xmlrpcMod.Port.ToString()));
7299 } 7118 }
7300 object[] resobj = new object[] 7119 object[] resobj = new object[]
@@ -7306,7 +7125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7306 new LSL_Integer(0), 7125 new LSL_Integer(0),
7307 new LSL_String(String.Empty) 7126 new LSL_String(String.Empty)
7308 }; 7127 };
7309 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj, 7128 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj,
7310 new DetectParams[0])); 7129 new DetectParams[0]));
7311 } 7130 }
7312 ScriptSleep(1000); 7131 ScriptSleep(1000);
@@ -7317,7 +7136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7317 m_host.AddScriptLPS(1); 7136 m_host.AddScriptLPS(1);
7318 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 7137 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7319 ScriptSleep(3000); 7138 ScriptSleep(3000);
7320 return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString(); 7139 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString();
7321 } 7140 }
7322 7141
7323 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) 7142 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
@@ -8156,7 +7975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8156 return; 7975 return;
8157 face = (int)rules.GetLSLIntegerItem(idx++); 7976 face = (int)rules.GetLSLIntegerItem(idx++);
8158 int shiny = (int)rules.GetLSLIntegerItem(idx++); 7977 int shiny = (int)rules.GetLSLIntegerItem(idx++);
8159 Bumpiness bump = (Bumpiness)Convert.ToByte((int)rules.GetLSLIntegerItem(idx++)); 7978 Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
8160 7979
8161 SetShiny(part, face, shiny, bump); 7980 SetShiny(part, face, shiny, bump);
8162 7981
@@ -9621,7 +9440,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9621 public LSL_String llGetSimulatorHostname() 9440 public LSL_String llGetSimulatorHostname()
9622 { 9441 {
9623 m_host.AddScriptLPS(1); 9442 m_host.AddScriptLPS(1);
9624 return System.Environment.MachineName; 9443 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
9444 return UrlModule.ExternalHostNameForLSL;
9625 } 9445 }
9626 9446
9627 // <summary> 9447 // <summary>
@@ -9960,13 +9780,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9960 { 9780 {
9961 m_host.AddScriptLPS(1); 9781 m_host.AddScriptLPS(1);
9962 if (m_UrlModule != null) 9782 if (m_UrlModule != null)
9963 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_itemID).ToString(); 9783 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
9964 return UUID.Zero.ToString(); 9784 return UUID.Zero.ToString();
9965 } 9785 }
9966 9786
9967 public LSL_String llRequestSimulatorData(string simulator, int data) 9787 public LSL_String llRequestSimulatorData(string simulator, int data)
9968 { 9788 {
9969 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 9789 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
9970 9790
9971 try 9791 try
9972 { 9792 {
@@ -9976,7 +9796,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9976 9796
9977 GridRegion info; 9797 GridRegion info;
9978 9798
9979 if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) 9799 if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) //Det data for this simulator?
9800
9980 info = new GridRegion(m_ScriptEngine.World.RegionInfo); 9801 info = new GridRegion(m_ScriptEngine.World.RegionInfo);
9981 else 9802 else
9982 info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 9803 info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
@@ -9989,10 +9810,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9989 ScriptSleep(1000); 9810 ScriptSleep(1000);
9990 return UUID.Zero.ToString(); 9811 return UUID.Zero.ToString();
9991 } 9812 }
9992 reply = new LSL_Vector( 9813 if (m_ScriptEngine.World.RegionInfo.RegionName != simulator)
9993 info.RegionLocX, 9814 {
9994 info.RegionLocY, 9815 //Hypergrid Region co-ordinates
9995 0).ToString(); 9816 uint rx = 0, ry = 0;
9817 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry);
9818
9819 reply = new LSL_Vector(
9820 rx,
9821 ry,
9822 0).ToString();
9823 }
9824 else
9825 {
9826 //Local-cooridnates
9827 reply = new LSL_Vector(
9828 info.RegionLocX,
9829 info.RegionLocY,
9830 0).ToString();
9831 }
9996 break; 9832 break;
9997 case ScriptBaseClass.DATA_SIM_STATUS: 9833 case ScriptBaseClass.DATA_SIM_STATUS:
9998 if (info != null) 9834 if (info != null)
@@ -10028,7 +9864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10028 UUID rq = UUID.Random(); 9864 UUID rq = UUID.Random();
10029 9865
10030 UUID tid = AsyncCommands. 9866 UUID tid = AsyncCommands.
10031 DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); 9867 DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
10032 9868
10033 AsyncCommands. 9869 AsyncCommands.
10034 DataserverPlugin.DataserverReply(rq.ToString(), reply); 9870 DataserverPlugin.DataserverReply(rq.ToString(), reply);
@@ -10047,7 +9883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10047 m_host.AddScriptLPS(1); 9883 m_host.AddScriptLPS(1);
10048 9884
10049 if (m_UrlModule != null) 9885 if (m_UrlModule != null)
10050 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_itemID).ToString(); 9886 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
10051 return UUID.Zero.ToString(); 9887 return UUID.Zero.ToString();
10052 } 9888 }
10053 9889
@@ -10083,7 +9919,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10083 // child agents have a mass of 1.0 9919 // child agents have a mass of 1.0
10084 return 1; 9920 return 1;
10085 else 9921 else
10086 return avatar.GetMass(); 9922 return (double)avatar.GetMass();
10087 } 9923 }
10088 catch (KeyNotFoundException) 9924 catch (KeyNotFoundException)
10089 { 9925 {
@@ -10526,32 +10362,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10526 public LSL_Vector llGetCameraPos() 10362 public LSL_Vector llGetCameraPos()
10527 { 10363 {
10528 m_host.AddScriptLPS(1); 10364 m_host.AddScriptLPS(1);
10529 UUID invItemID = InventorySelf();
10530
10531 if (invItemID == UUID.Zero)
10532 return new LSL_Vector();
10533
10534 m_host.TaskInventory.LockItemsForRead(true);
10535
10536 UUID agentID = m_host.TaskInventory[invItemID].PermsGranter;
10537 10365
10538// if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10366 if (m_item.PermsGranter == UUID.Zero)
10539 if (agentID == UUID.Zero) 10367 return new LSL_Vector();
10540 {
10541 m_host.TaskInventory.LockItemsForRead(false);
10542 return new LSL_Vector();
10543 }
10544 10368
10545 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10369 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10546 { 10370 {
10547 ShoutError("No permissions to track the camera"); 10371 ShoutError("No permissions to track the camera");
10548 m_host.TaskInventory.LockItemsForRead(false);
10549 return new LSL_Vector(); 10372 return new LSL_Vector();
10550 } 10373 }
10551 m_host.TaskInventory.LockItemsForRead(false); 10374 m_host.TaskInventory.LockItemsForRead(false);
10552 10375
10553// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10376// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10554 ScenePresence presence = World.GetScenePresence(agentID); 10377 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10555 if (presence != null) 10378 if (presence != null)
10556 { 10379 {
10557 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10380 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -10563,30 +10386,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10563 public LSL_Rotation llGetCameraRot() 10386 public LSL_Rotation llGetCameraRot()
10564 { 10387 {
10565 m_host.AddScriptLPS(1); 10388 m_host.AddScriptLPS(1);
10566 UUID invItemID = InventorySelf();
10567 if (invItemID == UUID.Zero)
10568 return new LSL_Rotation();
10569
10570 m_host.TaskInventory.LockItemsForRead(true);
10571 10389
10572 UUID agentID = m_host.TaskInventory[invItemID].PermsGranter; 10390 if (m_item.PermsGranter == UUID.Zero)
10391 return new LSL_Rotation();
10573 10392
10574// if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10393 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10575 if (agentID == UUID.Zero)
10576 {
10577 m_host.TaskInventory.LockItemsForRead(false);
10578 return new LSL_Rotation();
10579 }
10580 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10581 { 10394 {
10582 ShoutError("No permissions to track the camera"); 10395 ShoutError("No permissions to track the camera");
10583 m_host.TaskInventory.LockItemsForRead(false);
10584 return new LSL_Rotation(); 10396 return new LSL_Rotation();
10585 } 10397 }
10586 m_host.TaskInventory.LockItemsForRead(false); 10398 m_host.TaskInventory.LockItemsForRead(false);
10587 10399
10588// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10400// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10589 ScenePresence presence = World.GetScenePresence(agentID); 10401 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10590 if (presence != null) 10402 if (presence != null)
10591 { 10403 {
10592 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10404 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10645,7 +10457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10645 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) 10457 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt)
10646 { 10458 {
10647 m_host.AddScriptLPS(1); 10459 m_host.AddScriptLPS(1);
10648 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10460 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10649 if (detectedParams == null) 10461 if (detectedParams == null)
10650 { 10462 {
10651 if (m_host.ParentGroup.IsAttachment == true) 10463 if (m_host.ParentGroup.IsAttachment == true)
@@ -10769,30 +10581,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10769 { 10581 {
10770 m_host.AddScriptLPS(1); 10582 m_host.AddScriptLPS(1);
10771 10583
10772 // our key in the object we are in
10773 UUID invItemID = InventorySelf();
10774 if (invItemID == UUID.Zero) return;
10775
10776 // the object we are in 10584 // the object we are in
10777 UUID objectID = m_host.ParentUUID; 10585 UUID objectID = m_host.ParentUUID;
10778 if (objectID == UUID.Zero) return; 10586 if (objectID == UUID.Zero)
10587 return;
10779 10588
10780 UUID agentID;
10781 m_host.TaskInventory.LockItemsForRead(true);
10782 // we need the permission first, to know which avatar we want to set the camera for 10589 // we need the permission first, to know which avatar we want to set the camera for
10783 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10590 UUID agentID = m_item.PermsGranter;
10784 10591
10785 if (agentID == UUID.Zero) 10592 if (agentID == UUID.Zero)
10786 {
10787 m_host.TaskInventory.LockItemsForRead(false);
10788 return; 10593 return;
10789 } 10594
10790 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10595 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10791 {
10792 m_host.TaskInventory.LockItemsForRead(false);
10793 return; 10596 return;
10794 }
10795 m_host.TaskInventory.LockItemsForRead(false);
10796 10597
10797 ScenePresence presence = World.GetScenePresence(agentID); 10598 ScenePresence presence = World.GetScenePresence(agentID);
10798 10599
@@ -10834,34 +10635,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10834 { 10635 {
10835 m_host.AddScriptLPS(1); 10636 m_host.AddScriptLPS(1);
10836 10637
10837 // our key in the object we are in
10838 UUID invItemID=InventorySelf();
10839 if (invItemID == UUID.Zero) return;
10840
10841 // the object we are in 10638 // the object we are in
10842 UUID objectID = m_host.ParentUUID; 10639 UUID objectID = m_host.ParentUUID;
10843 if (objectID == UUID.Zero) return; 10640 if (objectID == UUID.Zero)
10641 return;
10844 10642
10845 // we need the permission first, to know which avatar we want to clear the camera for 10643 // we need the permission first, to know which avatar we want to clear the camera for
10846 UUID agentID; 10644 UUID agentID = m_item.PermsGranter;
10847 m_host.TaskInventory.LockItemsForRead(true); 10645
10848 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10849 if (agentID == UUID.Zero) 10646 if (agentID == UUID.Zero)
10850 {
10851 m_host.TaskInventory.LockItemsForRead(false);
10852 return; 10647 return;
10853 } 10648
10854 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10649 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10855 {
10856 m_host.TaskInventory.LockItemsForRead(false);
10857 return; 10650 return;
10858 }
10859 m_host.TaskInventory.LockItemsForRead(false);
10860 10651
10861 ScenePresence presence = World.GetScenePresence(agentID); 10652 ScenePresence presence = World.GetScenePresence(agentID);
10862 10653
10863 // we are not interested in child-agents 10654 // we are not interested in child-agents
10864 if (presence.IsChildAgent) return; 10655 if (presence.IsChildAgent)
10656 return;
10865 10657
10866 presence.ControllingClient.SendClearFollowCamProperties(objectID); 10658 presence.ControllingClient.SendClearFollowCamProperties(objectID);
10867 } 10659 }
@@ -11052,8 +10844,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11052 } 10844 }
11053 } 10845 }
11054 10846
11055 UUID reqID = httpScriptMod. 10847 UUID reqID
11056 StartHttpRequest(m_localID, m_itemID, url, param, httpHeaders, body); 10848 = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body);
11057 10849
11058 if (reqID != UUID.Zero) 10850 if (reqID != UUID.Zero)
11059 return reqID.ToString(); 10851 return reqID.ToString();
@@ -11285,19 +11077,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11285 break; 11077 break;
11286 // For the following 8 see the Object version below 11078 // For the following 8 see the Object version below
11287 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 11079 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
11288 ret.Add(new LSL_Integer(0)); 11080 ret.Add(new LSL_Integer(av.RunningScriptCount()));
11289 break; 11081 break;
11290 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11082 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11291 ret.Add(new LSL_Integer(0)); 11083 ret.Add(new LSL_Integer(av.ScriptCount()));
11292 break; 11084 break;
11293 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11085 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11294 ret.Add(new LSL_Integer(0)); 11086 ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384));
11295 break; 11087 break;
11296 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11088 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11297 ret.Add(new LSL_Float(0)); 11089 ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f));
11298 break; 11090 break;
11299 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11091 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11300 ret.Add(new LSL_Integer(0)); 11092 ret.Add(new LSL_Integer(1));
11301 break; 11093 break;
11302 case ScriptBaseClass.OBJECT_SERVER_COST: 11094 case ScriptBaseClass.OBJECT_SERVER_COST:
11303 ret.Add(new LSL_Float(0)); 11095 ret.Add(new LSL_Float(0));
@@ -11349,43 +11141,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11349 case ScriptBaseClass.OBJECT_CREATOR: 11141 case ScriptBaseClass.OBJECT_CREATOR:
11350 ret.Add(new LSL_String(obj.CreatorID.ToString())); 11142 ret.Add(new LSL_String(obj.CreatorID.ToString()));
11351 break; 11143 break;
11352 // The following 8 I have intentionaly coded to return zero. They are part of
11353 // "Land Impact" calculations. These calculations are probably not applicable
11354 // to OpenSim, required figures (cpu/memory usage) are not currently tracked
11355 // I have intentionally left these all at zero rather than return possibly
11356 // missleading numbers
11357 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 11144 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
11358 // in SL this currently includes crashed scripts 11145 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount()));
11359 ret.Add(new LSL_Integer(0));
11360 break; 11146 break;
11361 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11147 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11362 ret.Add(new LSL_Integer(0)); 11148 ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount()));
11363 break; 11149 break;
11364 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11150 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11365 // The value returned in SL for mono scripts is 65536 * number of active scripts 11151 // The value returned in SL for mono scripts is 65536 * number of active scripts
11366 ret.Add(new LSL_Integer(0)); 11152 // and 16384 * number of active scripts for LSO. since llGetFreememory
11153 // is coded to give the LSO value use it here
11154 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384));
11367 break; 11155 break;
11368 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11156 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11369 // Average cpu time per simulator frame expended on all scripts in the objetc 11157 // Average cpu time in seconds per simulator frame expended on all scripts in the object
11370 ret.Add(new LSL_Float(0)); 11158 ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f));
11371 break; 11159 break;
11372 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11160 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11373 // according to the SL wiki A prim or linkset will have prim 11161 // according to the SL wiki A prim or linkset will have prim
11374 // equivalent of the number of prims in a linkset if it does not 11162 // equivalent of the number of prims in a linkset if it does not
11375 // contain a mesh anywhere in the link set or is not a normal prim 11163 // contain a mesh anywhere in the link set or is not a normal prim
11376 // The value returned in SL for normal prims is prim count 11164 // The value returned in SL for normal prims is prim count
11377 ret.Add(new LSL_Integer(0)); 11165 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11378 break; 11166 break;
11167 // The following 3 costs I have intentionaly coded to return zero. They are part of
11168 // "Land Impact" calculations. These calculations are probably not applicable
11169 // to OpenSim and are not yet complete in SL
11379 case ScriptBaseClass.OBJECT_SERVER_COST: 11170 case ScriptBaseClass.OBJECT_SERVER_COST:
11380 // The value returned in SL for normal prims is prim count 11171 // The linden calculation is here
11172 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
11173 // The value returned in SL for normal prims looks like the prim count
11381 ret.Add(new LSL_Float(0)); 11174 ret.Add(new LSL_Float(0));
11382 break; 11175 break;
11383 case ScriptBaseClass.OBJECT_STREAMING_COST: 11176 case ScriptBaseClass.OBJECT_STREAMING_COST:
11384 // The value returned in SL for normal prims is prim count * 0.06 11177 // The linden calculation is here
11178 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost
11179 // The value returned in SL for normal prims looks like the prim count * 0.06
11385 ret.Add(new LSL_Float(0)); 11180 ret.Add(new LSL_Float(0));
11386 break; 11181 break;
11387 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11182 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11388 // The value returned in SL for normal prims is prim count 11183 // The linden calculation is here
11184 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics
11185 // The value returned in SL for normal prims looks like the prim count
11389 ret.Add(new LSL_Float(0)); 11186 ret.Add(new LSL_Float(0));
11390 break; 11187 break;
11391 default: 11188 default:
@@ -11483,7 +11280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11483 } 11280 }
11484 11281
11485 // was: UUID tid = tid = AsyncCommands. 11282 // was: UUID tid = tid = AsyncCommands.
11486 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, assetID.ToString()); 11283 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString());
11487 11284
11488 if (NotecardCache.IsCached(assetID)) 11285 if (NotecardCache.IsCached(assetID))
11489 { 11286 {
@@ -11546,7 +11343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11546 } 11343 }
11547 11344
11548 // was: UUID tid = tid = AsyncCommands. 11345 // was: UUID tid = tid = AsyncCommands.
11549 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, assetID.ToString()); 11346 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString());
11550 11347
11551 if (NotecardCache.IsCached(assetID)) 11348 if (NotecardCache.IsCached(assetID))
11552 { 11349 {
@@ -11630,7 +11427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11630 { 11427 {
11631 UUID rq = UUID.Random(); 11428 UUID rq = UUID.Random();
11632 11429
11633 AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); 11430 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11634 11431
11635 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); 11432 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
11636 11433
@@ -11646,7 +11443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11646 { 11443 {
11647 UUID rq = UUID.Random(); 11444 UUID rq = UUID.Random();
11648 11445
11649 AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString()); 11446 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11650 11447
11651 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); 11448 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
11652 11449
@@ -12140,7 +11937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12140 bool isAccount = false; 11937 bool isAccount = false;
12141 bool isGroup = false; 11938 bool isGroup = false;
12142 11939
12143 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID)) 11940 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID))
12144 return 0; 11941 return 0;
12145 11942
12146 UUID id = new UUID(); 11943 UUID id = new UUID();
@@ -12202,35 +11999,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12202 return 1; 11999 return 1;
12203 } 12000 }
12204 12001
12205 #region Not Implemented 12002 public LSL_Integer llGetMemoryLimit()
12206 // 12003 {
12207 // Listing the unimplemented lsl functions here, please move 12004 m_host.AddScriptLPS(1);
12208 // them from this region as they are completed 12005 // The value returned for LSO scripts in SL
12209 // 12006 return 16384;
12007 }
12210 12008
12211 public void llGetEnv(LSL_String name) 12009 public LSL_Integer llSetMemoryLimit(LSL_Integer limit)
12212 { 12010 {
12213 m_host.AddScriptLPS(1); 12011 m_host.AddScriptLPS(1);
12214 NotImplemented("llGetEnv"); 12012 // Treat as an LSO script
12013 return ScriptBaseClass.FALSE;
12215 } 12014 }
12216 12015
12217 public void llGetSPMaxMemory() 12016 public LSL_Integer llGetSPMaxMemory()
12218 { 12017 {
12219 m_host.AddScriptLPS(1); 12018 m_host.AddScriptLPS(1);
12220 NotImplemented("llGetSPMaxMemory"); 12019 // The value returned for LSO scripts in SL
12020 return 16384;
12221 } 12021 }
12222 12022
12223 public virtual LSL_Integer llGetUsedMemory() 12023 public virtual LSL_Integer llGetUsedMemory()
12224 { 12024 {
12225 m_host.AddScriptLPS(1); 12025 m_host.AddScriptLPS(1);
12226 NotImplemented("llGetUsedMemory"); 12026 // The value returned for LSO scripts in SL
12227 return 0; 12027 return 16384;
12228 } 12028 }
12229 12029
12230 public void llScriptProfiler(LSL_Integer flags) 12030 public void llScriptProfiler(LSL_Integer flags)
12231 { 12031 {
12232 m_host.AddScriptLPS(1); 12032 m_host.AddScriptLPS(1);
12233 //NotImplemented("llScriptProfiler"); 12033 // This does nothing for LSO scripts in SL
12034 }
12035
12036 #region Not Implemented
12037 //
12038 // Listing the unimplemented lsl functions here, please move
12039 // them from this region as they are completed
12040 //
12041
12042 public void llGetEnv(LSL_String name)
12043 {
12044 m_host.AddScriptLPS(1);
12045 NotImplemented("llGetEnv");
12234 } 12046 }
12235 12047
12236 public void llSetSoundQueueing(int queue) 12048 public void llSetSoundQueueing(int queue)
@@ -12310,8 +12122,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12310 12122
12311 try 12123 try
12312 { 12124 {
12313 UUID invItemID=InventorySelf(); 12125 TaskInventoryItem item = m_item;
12314 if (invItemID == UUID.Zero) 12126 if (item == null)
12315 { 12127 {
12316 replydata = "SERVICE_ERROR"; 12128 replydata = "SERVICE_ERROR";
12317 return; 12129 return;
@@ -12319,10 +12131,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12319 12131
12320 m_host.AddScriptLPS(1); 12132 m_host.AddScriptLPS(1);
12321 12133
12322 m_host.TaskInventory.LockItemsForRead(true);
12323 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12324 m_host.TaskInventory.LockItemsForRead(false);
12325
12326 if (item.PermsGranter == UUID.Zero) 12134 if (item.PermsGranter == UUID.Zero)
12327 { 12135 {
12328 replydata = "MISSING_PERMISSION_DEBIT"; 12136 replydata = "MISSING_PERMISSION_DEBIT";
@@ -12364,7 +12172,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12364 } 12172 }
12365 finally 12173 finally
12366 { 12174 {
12367 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 12175 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12368 "transaction_result", new Object[] { 12176 "transaction_result", new Object[] {
12369 new LSL_String(txn.ToString()), 12177 new LSL_String(txn.ToString()),
12370 new LSL_Integer(replycode), 12178 new LSL_Integer(replycode),
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 77a784d..795de80 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -58,17 +58,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
58 { 58 {
59 internal IScriptEngine m_ScriptEngine; 59 internal IScriptEngine m_ScriptEngine;
60 internal SceneObjectPart m_host; 60 internal SceneObjectPart m_host;
61 internal uint m_localID;
62 internal UUID m_itemID;
63 internal bool m_LSFunctionsEnabled = false; 61 internal bool m_LSFunctionsEnabled = false;
64 internal IScriptModuleComms m_comms = null; 62 internal IScriptModuleComms m_comms = null;
65 63
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 64 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
67 { 65 {
68 m_ScriptEngine = ScriptEngine; 66 m_ScriptEngine = ScriptEngine;
69 m_host = host; 67 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72 68
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 69 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 70 m_LSFunctionsEnabled = true;
@@ -449,7 +445,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
449 LSShoutError("LightShare functions are not enabled."); 445 LSShoutError("LightShare functions are not enabled.");
450 return 0; 446 return 0;
451 } 447 }
452 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 448 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
453 { 449 {
454 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 450 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
455 return 0; 451 return 0;
@@ -477,7 +473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
477 LSShoutError("LightShare functions are not enabled."); 473 LSShoutError("LightShare functions are not enabled.");
478 return; 474 return;
479 } 475 }
480 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 476 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
481 { 477 {
482 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 478 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
483 return; 479 return;
@@ -500,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
500 LSShoutError("LightShare functions are not enabled."); 496 LSShoutError("LightShare functions are not enabled.");
501 return 0; 497 return 0;
502 } 498 }
503 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 499 if (!World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
504 { 500 {
505 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 501 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
506 return 0; 502 return 0;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 7c07e15..4bd3dff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -57,17 +57,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
57 { 57 {
58 internal IScriptEngine m_ScriptEngine; 58 internal IScriptEngine m_ScriptEngine;
59 internal SceneObjectPart m_host; 59 internal SceneObjectPart m_host;
60 internal uint m_localID; 60 internal TaskInventoryItem m_item;
61 internal UUID m_itemID;
62 internal bool m_MODFunctionsEnabled = false; 61 internal bool m_MODFunctionsEnabled = false;
63 internal IScriptModuleComms m_comms = null; 62 internal IScriptModuleComms m_comms = null;
64 63
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 64 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 { 65 {
67 m_ScriptEngine = ScriptEngine; 66 m_ScriptEngine = ScriptEngine;
68 m_host = host; 67 m_host = host;
69 m_localID = localID; 68 m_item = item;
70 m_itemID = itemID;
71 69
72 if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) 70 if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false))
73 m_MODFunctionsEnabled = true; 71 m_MODFunctionsEnabled = true;
@@ -252,7 +250,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
252 // non-null but don't trust it completely 250 // non-null but don't trust it completely
253 try 251 try
254 { 252 {
255 object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms); 253 object result = m_comms.InvokeOperation(m_host.UUID, m_item.ItemID, fname, convertedParms);
256 if (result != null) 254 if (result != null)
257 return result; 255 return result;
258 256
@@ -279,7 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
279 277
280 UUID req = UUID.Random(); 278 UUID req = UUID.Random();
281 279
282 m_comms.RaiseEvent(m_itemID, req.ToString(), module, command, k); 280 m_comms.RaiseEvent(m_item.ItemID, req.ToString(), module, command, k);
283 281
284 return req.ToString(); 282 return req.ToString();
285 } 283 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 0dc2aa2..8237b60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -128,11 +128,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
128 { 128 {
129// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 129// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
130 130
131 public const string GridInfoServiceConfigSectionName = "GridInfoService";
132
131 internal IScriptEngine m_ScriptEngine; 133 internal IScriptEngine m_ScriptEngine;
132 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there 134 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there
133 internal SceneObjectPart m_host; 135 internal SceneObjectPart m_host;
134 internal uint m_localID; 136 internal TaskInventoryItem m_item;
135 internal UUID m_itemID;
136 internal bool m_OSFunctionsEnabled = false; 137 internal bool m_OSFunctionsEnabled = false;
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
@@ -140,12 +141,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 internal bool m_debuggerSafe = false; 141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
144 { 145 {
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_localID = localID; 148 m_item = item;
148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 150
151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
@@ -218,12 +218,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
218 } 218 }
219 } 219 }
220 220
221 /// <summary>
222 /// Initialize the LSL interface.
223 /// </summary>
224 /// <remarks>
225 /// FIXME: This is an abomination. We should be able to set this up earlier but currently we have no
226 /// guarantee the interface is present on Initialize(). There needs to be another post initialize call from
227 /// ScriptInstance.
228 /// </remarks>
221 private void InitLSL() 229 private void InitLSL()
222 { 230 {
223 if (m_LSL_Api != null) 231 if (m_LSL_Api != null)
224 return; 232 return;
225 233
226 m_LSL_Api = (ILSL_Api)m_ScriptEngine.GetApi(m_itemID, "LSL"); 234 m_LSL_Api = (ILSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "LSL");
227 } 235 }
228 236
229 // 237 //
@@ -342,22 +350,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 return; 350 return;
343 } 351 }
344 352
345 TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); 353 UUID ownerID = m_item.OwnerID;
346 if (ti == null)
347 {
348 OSSLError(
349 String.Format("{0} permission error. Can't find script in prim inventory.",
350 function));
351 }
352
353 UUID ownerID = ti.OwnerID;
354 354
355 //OSSL only may be used if objet is in the same group as the parcel 355 //OSSL only may be used if object is in the same group as the parcel
356 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER")) 356 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER"))
357 { 357 {
358 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 358 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
359 359
360 if (land.LandData.GroupID == ti.GroupID && land.LandData.GroupID != UUID.Zero) 360 if (land.LandData.GroupID == m_item.GroupID && land.LandData.GroupID != UUID.Zero)
361 { 361 {
362 return; 362 return;
363 } 363 }
@@ -378,7 +378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
378 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_MANAGER")) 378 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_MANAGER"))
379 { 379 {
380 //Only Estate Managers may use the function 380 //Only Estate Managers may use the function
381 if (World.RegionInfo.EstateSettings.IsEstateManager(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID) 381 if (World.RegionInfo.EstateSettings.IsEstateManagerOrOwner(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
382 { 382 {
383 return; 383 return;
384 } 384 }
@@ -393,13 +393,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
393 } 393 }
394 } 394 }
395 395
396 if (!m_FunctionPerms[function].AllowedCreators.Contains(ti.CreatorID)) 396 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
397 OSSLError( 397 OSSLError(
398 String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", 398 String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.",
399 function)); 399 function));
400 if (ti.CreatorID != ownerID) 400
401 if (m_item.CreatorID != ownerID)
401 { 402 {
402 if ((ti.CurrentPermissions & (uint)PermissionMask.Modify) != 0) 403 if ((m_item.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
403 OSSLError( 404 OSSLError(
404 String.Format("{0} permission denied. Script permissions error.", 405 String.Format("{0} permission denied. Script permissions error.",
405 function)); 406 function));
@@ -730,11 +731,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
730 731
731 m_host.AddScriptLPS(1); 732 m_host.AddScriptLPS(1);
732 733
734 // For safety, we add another permission check here, and don't rely only on the standard OSSL permissions
733 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 735 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
734 { 736 {
735 MainConsole.Instance.RunCommand(command); 737 MainConsole.Instance.RunCommand(command);
736 return true; 738 return true;
737 } 739 }
740
738 return false; 741 return false;
739 } 742 }
740 743
@@ -957,21 +960,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
957 UUID avatarID = (UUID)avatar; 960 UUID avatarID = (UUID)avatar;
958 961
959 m_host.AddScriptLPS(1); 962 m_host.AddScriptLPS(1);
963
964 // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common
965 // method (though see that doesn't do the is animation check, which is probably a bug) and have both
966 // these functions call that common code. However, this does mean navigating the brain-dead requirement
967 // of calling InitLSL()
960 if (World.Entities.ContainsKey(avatarID) && World.Entities[avatarID] is ScenePresence) 968 if (World.Entities.ContainsKey(avatarID) && World.Entities[avatarID] is ScenePresence)
961 { 969 {
962 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 970 ScenePresence target = (ScenePresence)World.Entities[avatarID];
963 if (target != null) 971 if (target != null)
964 { 972 {
965 UUID animID = UUID.Zero; 973 UUID animID;
966 m_host.TaskInventory.LockItemsForRead(true); 974
967 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 975 if (!UUID.TryParse(animation, out animID))
968 { 976 {
969 if (inv.Value.Name == animation) 977 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(animation);
970 { 978 if (item != null && item.Type == (int)AssetType.Animation)
971 if (inv.Value.Type == (int)AssetType.Animation) 979 animID = item.AssetID;
972 animID = inv.Value.AssetID; 980 else
973 continue; 981 animID = UUID.Zero;
974 }
975 } 982 }
976 m_host.TaskInventory.LockItemsForRead(false); 983 m_host.TaskInventory.LockItemsForRead(false);
977 984
@@ -1178,7 +1185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1178 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents"); 1185 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
1179 m_host.AddScriptLPS(1); 1186 m_host.AddScriptLPS(1);
1180 1187
1181 m_host.SetScriptEvents(m_itemID, events); 1188 m_host.SetScriptEvents(m_item.ItemID, events);
1182 } 1189 }
1183 1190
1184 public void osSetRegionWaterHeight(double height) 1191 public void osSetRegionWaterHeight(double height)
@@ -1186,12 +1193,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1186 CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight"); 1193 CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight");
1187 1194
1188 m_host.AddScriptLPS(1); 1195 m_host.AddScriptLPS(1);
1189 //Check to make sure that the script's owner is the estate manager/master 1196
1190 //World.Permissions.GenericEstatePermission( 1197 World.EventManager.TriggerRequestChangeWaterHeight((float)height);
1191 if (World.Permissions.IsGod(m_host.OwnerID))
1192 {
1193 World.EventManager.TriggerRequestChangeWaterHeight((float)height);
1194 }
1195 } 1198 }
1196 1199
1197 /// <summary> 1200 /// <summary>
@@ -1202,27 +1205,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1202 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param> 1205 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param>
1203 public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour) 1206 public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour)
1204 { 1207 {
1205 CheckThreatLevel(ThreatLevel.Nuisance, "osSetRegionSunSettings"); 1208 CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings");
1206 1209
1207 m_host.AddScriptLPS(1); 1210 m_host.AddScriptLPS(1);
1208 //Check to make sure that the script's owner is the estate manager/master
1209 //World.Permissions.GenericEstatePermission(
1210 if (World.Permissions.IsGod(m_host.OwnerID))
1211 {
1212 while (sunHour > 24.0)
1213 sunHour -= 24.0;
1214 1211
1215 while (sunHour < 0) 1212 while (sunHour > 24.0)
1216 sunHour += 24.0; 1213 sunHour -= 24.0;
1217 1214
1215 while (sunHour < 0)
1216 sunHour += 24.0;
1218 1217
1219 World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun; 1218 World.RegionInfo.RegionSettings.UseEstateSun = useEstateSun;
1220 World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30 1219 World.RegionInfo.RegionSettings.SunPosition = sunHour + 6; // LL Region Sun Hour is 6 to 30
1221 World.RegionInfo.RegionSettings.FixedSun = sunFixed; 1220 World.RegionInfo.RegionSettings.FixedSun = sunFixed;
1222 World.RegionInfo.RegionSettings.Save(); 1221 World.RegionInfo.RegionSettings.Save();
1223 1222
1224 World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour); 1223 World.EventManager.TriggerEstateToolsSunUpdate(
1225 } 1224 World.RegionInfo.RegionHandle, sunFixed, useEstateSun, (float)sunHour);
1226 } 1225 }
1227 1226
1228 /// <summary> 1227 /// <summary>
@@ -1232,26 +1231,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1232 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param> 1231 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param>
1233 public void osSetEstateSunSettings(bool sunFixed, double sunHour) 1232 public void osSetEstateSunSettings(bool sunFixed, double sunHour)
1234 { 1233 {
1235 CheckThreatLevel(ThreatLevel.Nuisance, "osSetEstateSunSettings"); 1234 CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings");
1236 1235
1237 m_host.AddScriptLPS(1); 1236 m_host.AddScriptLPS(1);
1238 //Check to make sure that the script's owner is the estate manager/master
1239 //World.Permissions.GenericEstatePermission(
1240 if (World.Permissions.IsGod(m_host.OwnerID))
1241 {
1242 while (sunHour > 24.0)
1243 sunHour -= 24.0;
1244 1237
1245 while (sunHour < 0) 1238 while (sunHour > 24.0)
1246 sunHour += 24.0; 1239 sunHour -= 24.0;
1247 1240
1248 World.RegionInfo.EstateSettings.UseGlobalTime = !sunFixed; 1241 while (sunHour < 0)
1249 World.RegionInfo.EstateSettings.SunPosition = sunHour; 1242 sunHour += 24.0;
1250 World.RegionInfo.EstateSettings.FixedSun = sunFixed;
1251 World.RegionInfo.EstateSettings.Save();
1252 1243
1253 World.EventManager.TriggerEstateToolsSunUpdate(World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour); 1244 World.RegionInfo.EstateSettings.UseGlobalTime = !sunFixed;
1254 } 1245 World.RegionInfo.EstateSettings.SunPosition = sunHour;
1246 World.RegionInfo.EstateSettings.FixedSun = sunFixed;
1247 World.RegionInfo.EstateSettings.Save();
1248
1249 World.EventManager.TriggerEstateToolsSunUpdate(
1250 World.RegionInfo.RegionHandle, sunFixed, World.RegionInfo.RegionSettings.UseEstateSun, (float)sunHour);
1255 } 1251 }
1256 1252
1257 /// <summary> 1253 /// <summary>
@@ -1627,7 +1623,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 1623
1628 public Object osParseJSONNew(string JSON) 1624 public Object osParseJSONNew(string JSON)
1629 { 1625 {
1630 CheckThreatLevel(ThreatLevel.None, "osParseJSON"); 1626 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1631 1627
1632 m_host.AddScriptLPS(1); 1628 m_host.AddScriptLPS(1);
1633 1629
@@ -2042,8 +2038,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2042 string nick = String.Empty; 2038 string nick = String.Empty;
2043 IConfigSource config = m_ScriptEngine.ConfigSource; 2039 IConfigSource config = m_ScriptEngine.ConfigSource;
2044 2040
2045 if (config.Configs["GridInfo"] != null) 2041 if (config.Configs[GridInfoServiceConfigSectionName] != null)
2046 nick = config.Configs["GridInfo"].GetString("gridnick", nick); 2042 nick = config.Configs[GridInfoServiceConfigSectionName].GetString("gridnick", nick);
2047 2043
2048 if (String.IsNullOrEmpty(nick)) 2044 if (String.IsNullOrEmpty(nick))
2049 nick = GridUserInfo(InfoType.Nick); 2045 nick = GridUserInfo(InfoType.Nick);
@@ -2059,8 +2055,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2059 string name = String.Empty; 2055 string name = String.Empty;
2060 IConfigSource config = m_ScriptEngine.ConfigSource; 2056 IConfigSource config = m_ScriptEngine.ConfigSource;
2061 2057
2062 if (config.Configs["GridInfo"] != null) 2058 if (config.Configs[GridInfoServiceConfigSectionName] != null)
2063 name = config.Configs["GridInfo"].GetString("gridname", name); 2059 name = config.Configs[GridInfoServiceConfigSectionName].GetString("gridname", name);
2064 2060
2065 if (String.IsNullOrEmpty(name)) 2061 if (String.IsNullOrEmpty(name))
2066 name = GridUserInfo(InfoType.Name); 2062 name = GridUserInfo(InfoType.Name);
@@ -2076,8 +2072,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2076 string loginURI = String.Empty; 2072 string loginURI = String.Empty;
2077 IConfigSource config = m_ScriptEngine.ConfigSource; 2073 IConfigSource config = m_ScriptEngine.ConfigSource;
2078 2074
2079 if (config.Configs["GridInfo"] != null) 2075 if (config.Configs[GridInfoServiceConfigSectionName] != null)
2080 loginURI = config.Configs["GridInfo"].GetString("login", loginURI); 2076 loginURI = config.Configs[GridInfoServiceConfigSectionName].GetString("login", loginURI);
2081 2077
2082 if (String.IsNullOrEmpty(loginURI)) 2078 if (String.IsNullOrEmpty(loginURI))
2083 loginURI = GridUserInfo(InfoType.Login); 2079 loginURI = GridUserInfo(InfoType.Login);
@@ -2124,8 +2120,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2124 string retval = String.Empty; 2120 string retval = String.Empty;
2125 IConfigSource config = m_ScriptEngine.ConfigSource; 2121 IConfigSource config = m_ScriptEngine.ConfigSource;
2126 2122
2127 if (config.Configs["GridInfo"] != null) 2123 if (config.Configs[GridInfoServiceConfigSectionName] != null)
2128 retval = config.Configs["GridInfo"].GetString(key, retval); 2124 retval = config.Configs[GridInfoServiceConfigSectionName].GetString(key, retval);
2129 2125
2130 if (String.IsNullOrEmpty(retval)) 2126 if (String.IsNullOrEmpty(retval))
2131 retval = GridUserInfo(InfoType.Custom, key); 2127 retval = GridUserInfo(InfoType.Custom, key);
@@ -2480,7 +2476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2480 return; 2476 return;
2481 2477
2482 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2478 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2483 module.MoveToTarget(npcId, World, pos, false, true); 2479 module.MoveToTarget(npcId, World, pos, false, true, false);
2484 } 2480 }
2485 } 2481 }
2486 2482
@@ -2505,7 +2501,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2505 World, 2501 World,
2506 pos, 2502 pos,
2507 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, 2503 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2508 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0); 2504 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
2505 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
2509 } 2506 }
2510 } 2507 }
2511 2508
@@ -2555,7 +2552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2555 2552
2556 public void osNpcStopMoveToTarget(LSL_Key npc) 2553 public void osNpcStopMoveToTarget(LSL_Key npc)
2557 { 2554 {
2558 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); 2555 CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget");
2559 m_host.AddScriptLPS(1); 2556 m_host.AddScriptLPS(1);
2560 2557
2561 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2558 INPCModule module = World.RequestModuleInterface<INPCModule>();
@@ -2572,6 +2569,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2572 2569
2573 public void osNpcSay(LSL_Key npc, string message) 2570 public void osNpcSay(LSL_Key npc, string message)
2574 { 2571 {
2572 osNpcSay(npc, 0, message);
2573 }
2574
2575 public void osNpcSay(LSL_Key npc, int channel, string message)
2576 {
2575 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2577 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
2576 m_host.AddScriptLPS(1); 2578 m_host.AddScriptLPS(1);
2577 2579
@@ -2583,7 +2585,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2583 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2585 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2584 return; 2586 return;
2585 2587
2586 module.Say(npcId, World, message); 2588 module.Say(npcId, World, message, channel);
2589 }
2590 }
2591
2592 public void osNpcShout(LSL_Key npc, int channel, string message)
2593 {
2594 CheckThreatLevel(ThreatLevel.High, "osNpcShout");
2595 m_host.AddScriptLPS(1);
2596
2597 INPCModule module = World.RequestModuleInterface<INPCModule>();
2598 if (module != null)
2599 {
2600 UUID npcId = new UUID(npc.m_string);
2601
2602 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2603 return;
2604
2605 module.Shout(npcId, World, message, channel);
2587 } 2606 }
2588 } 2607 }
2589 2608
@@ -2684,6 +2703,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2684 } 2703 }
2685 } 2704 }
2686 2705
2706 public void osNpcWhisper(LSL_Key npc, int channel, string message)
2707 {
2708 CheckThreatLevel(ThreatLevel.High, "osNpcWhisper");
2709 m_host.AddScriptLPS(1);
2710
2711 INPCModule module = World.RequestModuleInterface<INPCModule>();
2712 if (module != null)
2713 {
2714 UUID npcId = new UUID(npc.m_string);
2715
2716 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2717 return;
2718
2719 module.Whisper(npcId, World, message, channel);
2720 }
2721 }
2722
2687 /// <summary> 2723 /// <summary>
2688 /// Save the current appearance of the script owner permanently to the named notecard. 2724 /// Save the current appearance of the script owner permanently to the named notecard.
2689 /// </summary> 2725 /// </summary>
@@ -2835,21 +2871,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2835 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2871 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2836 m_host.AddScriptLPS(1); 2872 m_host.AddScriptLPS(1);
2837 2873
2838 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 2874 World.ForEachRootScenePresence(delegate(ScenePresence sp)
2839 { 2875 {
2840 World.ForEachRootScenePresence(delegate(ScenePresence sp) 2876 if (sp.Firstname == FirstName && sp.Lastname == SurName)
2841 { 2877 {
2842 if (sp.Firstname == FirstName && sp.Lastname == SurName) 2878 // kick client...
2843 { 2879 if (alert != null)
2844 // kick client... 2880 sp.ControllingClient.Kick(alert);
2845 if (alert != null)
2846 sp.ControllingClient.Kick(alert);
2847 2881
2848 // ...and close on our side 2882 // ...and close on our side
2849 sp.Scene.IncomingCloseAgent(sp.UUID); 2883 sp.Scene.IncomingCloseAgent(sp.UUID);
2850 } 2884 }
2851 }); 2885 });
2852 }
2853 } 2886 }
2854 2887
2855 public void osCauseDamage(string avatar, double damage) 2888 public void osCauseDamage(string avatar, double damage)
@@ -3095,5 +3128,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3095 3128
3096 return ScriptBaseClass.TRUE; 3129 return ScriptBaseClass.TRUE;
3097 } 3130 }
3131
3132 /// <summary>
3133 /// Sets terrain estate texture
3134 /// </summary>
3135 /// <param name="level"></param>
3136 /// <param name="texture"></param>
3137 /// <returns></returns>
3138 public void osSetTerrainTexture(int level, LSL_Key texture)
3139 {
3140 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture");
3141
3142 m_host.AddScriptLPS(1);
3143 //Check to make sure that the script's owner is the estate manager/master
3144 //World.Permissions.GenericEstatePermission(
3145 if (World.Permissions.IsGod(m_host.OwnerID))
3146 {
3147 if (level < 0 || level > 3)
3148 return;
3149
3150 UUID textureID = new UUID();
3151 if (!UUID.TryParse(texture, out textureID))
3152 return;
3153
3154 // estate module is required
3155 IEstateModule estate = World.RequestModuleInterface<IEstateModule>();
3156 if (estate != null)
3157 estate.setEstateTerrainBaseTexture(level, textureID);
3158 }
3159 }
3160
3161 /// <summary>
3162 /// Sets terrain heights of estate
3163 /// </summary>
3164 /// <param name="corner"></param>
3165 /// <param name="low"></param>
3166 /// <param name="high"></param>
3167 /// <returns></returns>
3168 public void osSetTerrainTextureHeight(int corner, double low, double high)
3169 {
3170 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight");
3171
3172 m_host.AddScriptLPS(1);
3173 //Check to make sure that the script's owner is the estate manager/master
3174 //World.Permissions.GenericEstatePermission(
3175 if (World.Permissions.IsGod(m_host.OwnerID))
3176 {
3177 if (corner < 0 || corner > 3)
3178 return;
3179
3180 // estate module is required
3181 IEstateModule estate = World.RequestModuleInterface<IEstateModule>();
3182 if (estate != null)
3183 estate.setEstateTerrainTextureHeights(corner, (float)low, (float)high);
3184 }
3185 }
3186
3187 public void osForceAttachToAvatar(int attachmentPoint)
3188 {
3189 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
3190
3191 m_host.AddScriptLPS(1);
3192
3193 InitLSL();
3194 ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint);
3195 }
3196
3197 public void osForceDetachFromAvatar()
3198 {
3199 CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar");
3200
3201 m_host.AddScriptLPS(1);
3202
3203 InitLSL();
3204 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3205 }
3098 } 3206 }
3099} 3207}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 1373971..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -308,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
308 } 308 }
309 SceneObjectPart SensePoint = ts.host; 309 SceneObjectPart SensePoint = ts.host;
310 310
311 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 311 Vector3 fromRegionPos = SensePoint.GetWorldPosition();
312 312
313 // pre define some things to avoid repeated definitions in the loop body 313 // pre define some things to avoid repeated definitions in the loop body
314 Vector3 toRegionPos; 314 Vector3 toRegionPos;
@@ -323,13 +323,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation! 323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
324 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
325 { 325 {
326 // In attachments, the sensor cone always orients with the 326 // In attachments, rotate the sensor cone with the
327 // avatar rotation. This may include a nonzero elevation if 327 // avatar rotation. This may include a nonzero elevation if
328 // in mouselook. 328 // in mouselook.
329 // This will not include the rotation and position of the
330 // attachment point (e.g. your head when a sensor is in your
331 // hair attached to your scull. Your hair will turn with
332 // your head but the sensor will stay with your (global)
333 // avatar rotation and position.
334 // Position of a sensor in a child prim attached to an avatar
335 // will be still wrong.
329 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
330 fromRegionPos = avatar.AbsolutePosition; 337 fromRegionPos = avatar.AbsolutePosition;
331 q = avatar.Rotation; 338 q = avatar.Rotation;
332 } 339 }
340
333 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
334 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 342 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
335 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 343 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
@@ -441,14 +449,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
441 return sensedEntities; 449 return sensedEntities;
442 450
443 SceneObjectPart SensePoint = ts.host; 451 SceneObjectPart SensePoint = ts.host;
444 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 452 Vector3 fromRegionPos = SensePoint.GetWorldPosition();
445 453
446 Quaternion q = SensePoint.RotationOffset; 454 Quaternion q = SensePoint.GetWorldRotation();
447 if (SensePoint.ParentGroup.IsAttachment) 455 if (SensePoint.ParentGroup.IsAttachment)
448 { 456 {
449 // In attachments, the sensor cone always orients with the 457 // In attachments, rotate the sensor cone with the
450 // avatar rotation. This may include a nonzero elevation if 458 // avatar rotation. This may include a nonzero elevation if
451 // in mouselook. 459 // in mouselook.
460 // This will not include the rotation and position of the
461 // attachment point (e.g. your head when a sensor is in your
462 // hair attached to your scull. Your hair will turn with
463 // your head but the sensor will stay with your (global)
464 // avatar rotation and position.
465 // Position of a sensor in a child prim attached to an avatar
466 // will be still wrong.
452 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
453 if (avatar == null) 468 if (avatar == null)
454 return sensedEntities; 469 return sensedEntities;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index be5740e..048124d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -105,6 +105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
105 LSL_Integer llFloor(double f); 105 LSL_Integer llFloor(double f);
106 void llForceMouselook(int mouselook); 106 void llForceMouselook(int mouselook);
107 LSL_Float llFrand(double mag); 107 LSL_Float llFrand(double mag);
108 LSL_Key llGenerateKey();
108 LSL_Vector llGetAccel(); 109 LSL_Vector llGetAccel();
109 LSL_Integer llGetAgentInfo(string id); 110 LSL_Integer llGetAgentInfo(string id);
110 LSL_String llGetAgentLanguage(string id); 111 LSL_String llGetAgentLanguage(string id);
@@ -150,7 +151,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
152 LSL_Float llGetMassMKS(); 153 LSL_Float llGetMassMKS();
153 void llGetNextEmail(string address, string subject); 154 LSL_Integer llGetMemoryLimit();
155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
155 LSL_Key llGetNumberOfNotecardLines(string name); 157 LSL_Key llGetNumberOfNotecardLines(string name);
156 LSL_Integer llGetNumberOfPrims(); 158 LSL_Integer llGetNumberOfPrims();
@@ -188,6 +190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
188 LSL_String llGetScriptName(); 190 LSL_String llGetScriptName();
189 LSL_Integer llGetScriptState(string name); 191 LSL_Integer llGetScriptState(string name);
190 LSL_String llGetSimulatorHostname(); 192 LSL_String llGetSimulatorHostname();
193 LSL_Integer llGetSPMaxMemory();
191 LSL_Integer llGetStartParameter(); 194 LSL_Integer llGetStartParameter();
192 LSL_Integer llGetStatus(int status); 195 LSL_Integer llGetStatus(int status);
193 LSL_String llGetSubString(string src, int start, int end); 196 LSL_String llGetSubString(string src, int start, int end);
@@ -323,6 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
323 void llSay(int channelID, string text); 326 void llSay(int channelID, string text);
324 void llScaleTexture(double u, double v, int face); 327 void llScaleTexture(double u, double v, int face);
325 LSL_Integer llScriptDanger(LSL_Vector pos); 328 LSL_Integer llScriptDanger(LSL_Vector pos);
329 void llScriptProfiler(LSL_Integer flag);
326 LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata); 330 LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata);
327 void llSensor(string name, string id, int type, double range, double arc); 331 void llSensor(string name, string id, int type, double range, double arc);
328 void llSensorRemove(); 332 void llSensorRemove();
@@ -346,6 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
346 void llSetLinkTexture(int linknumber, string texture, int face); 350 void llSetLinkTexture(int linknumber, string texture, int face);
347 void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate); 351 void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate);
348 void llSetLocalRot(LSL_Rotation rot); 352 void llSetLocalRot(LSL_Rotation rot);
353 LSL_Integer llSetMemoryLimit(LSL_Integer limit);
349 void llSetObjectDesc(string desc); 354 void llSetObjectDesc(string desc);
350 void llSetObjectName(string name); 355 void llSetObjectName(string name);
351 void llSetObjectPermMask(int mask, int value); 356 void llSetObjectPermMask(int mask, int value);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 444a681..7382495 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -98,6 +98,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
98 void osAvatarPlayAnimation(string avatar, string animation); 98 void osAvatarPlayAnimation(string avatar, string animation);
99 void osAvatarStopAnimation(string avatar, string animation); 99 void osAvatarStopAnimation(string avatar, string animation);
100 100
101 // Attachment commands
102
103 /// <summary>
104 /// Attach the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH
105 /// </summary>
106 /// <param name='attachment'>The attachment point. For example, ATTACH_CHEST</param>
107 void osForceAttachToAvatar(int attachment);
108
109 /// <summary>
110 /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH
111 /// </summary>
112 /// <remarks>Nothing happens if the object is not attached.</remarks>
113 void osForceDetachFromAvatar();
114
101 //texture draw functions 115 //texture draw functions
102 string osMovePen(string drawList, int x, int y); 116 string osMovePen(string drawList, int x, int y);
103 string osDrawLine(string drawList, int startX, int startY, int endX, int endY); 117 string osDrawLine(string drawList, int startX, int startY, int endX, int endY);
@@ -203,11 +217,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
203 void osNpcSetRot(LSL_Key npc, rotation rot); 217 void osNpcSetRot(LSL_Key npc, rotation rot);
204 void osNpcStopMoveToTarget(LSL_Key npc); 218 void osNpcStopMoveToTarget(LSL_Key npc);
205 void osNpcSay(key npc, string message); 219 void osNpcSay(key npc, string message);
220 void osNpcSay(key npc, int channel, string message);
221 void osNpcShout(key npc, int channel, string message);
206 void osNpcSit(key npc, key target, int options); 222 void osNpcSit(key npc, key target, int options);
207 void osNpcStand(LSL_Key npc); 223 void osNpcStand(LSL_Key npc);
208 void osNpcRemove(key npc); 224 void osNpcRemove(key npc);
209 void osNpcPlayAnimation(LSL_Key npc, string animation); 225 void osNpcPlayAnimation(LSL_Key npc, string animation);
210 void osNpcStopAnimation(LSL_Key npc, string animation); 226 void osNpcStopAnimation(LSL_Key npc, string animation);
227 void osNpcWhisper(key npc, int channel, string message);
211 228
212 LSL_Key osOwnerSaveAppearance(string notecard); 229 LSL_Key osOwnerSaveAppearance(string notecard);
213 LSL_Key osAgentSaveAppearance(key agentId, string notecard); 230 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
@@ -234,5 +251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
234 251
235 LSL_Integer osInviteToGroup(LSL_Key agentId); 252 LSL_Integer osInviteToGroup(LSL_Key agentId);
236 LSL_Integer osEjectFromGroup(LSL_Key agentId); 253 LSL_Integer osEjectFromGroup(LSL_Key agentId);
254
255 void osSetTerrainTexture(int level, LSL_Key texture);
256 void osSetTerrainTextureHeight(int corner, double low, double high);
237 } 257 }
238} 258}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 278f74e..5c6ad8a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -383,6 +383,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
383 public const int PRIM_SCULPT_FLAG_INVERT = 64; 383 public const int PRIM_SCULPT_FLAG_INVERT = 64;
384 public const int PRIM_SCULPT_FLAG_MIRROR = 128; 384 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
385 385
386 public const int PROFILE_NONE = 0;
387 public const int PROFILE_SCRIPT_MEMORY = 1;
388
386 public const int MASK_BASE = 0; 389 public const int MASK_BASE = 0;
387 public const int MASK_OWNER = 1; 390 public const int MASK_OWNER = 1;
388 public const int MASK_GROUP = 2; 391 public const int MASK_GROUP = 2;
@@ -641,6 +644,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
641 public const int OS_NPC_FLY = 0; 644 public const int OS_NPC_FLY = 0;
642 public const int OS_NPC_NO_FLY = 1; 645 public const int OS_NPC_NO_FLY = 1;
643 public const int OS_NPC_LAND_AT_TARGET = 2; 646 public const int OS_NPC_LAND_AT_TARGET = 2;
647 public const int OS_NPC_RUNNING = 4;
644 648
645 public const int OS_NPC_SIT_NOW = 0; 649 public const int OS_NPC_SIT_NOW = 0;
646 650
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 9ba9561..2d23d30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -376,6 +376,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
376 return m_LSL_Functions.llFrand(mag); 376 return m_LSL_Functions.llFrand(mag);
377 } 377 }
378 378
379 public LSL_Key llGenerateKey()
380 {
381 return m_LSL_Functions.llGenerateKey();
382 }
383
379 public LSL_Vector llGetAccel() 384 public LSL_Vector llGetAccel()
380 { 385 {
381 return m_LSL_Functions.llGetAccel(); 386 return m_LSL_Functions.llGetAccel();
@@ -591,6 +596,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
591 return m_LSL_Functions.llGetMassMKS(); 596 return m_LSL_Functions.llGetMassMKS();
592 } 597 }
593 598
599 public LSL_Integer llGetMemoryLimit()
600 {
601 return m_LSL_Functions.llGetMemoryLimit();
602 }
603
594 public void llGetNextEmail(string address, string subject) 604 public void llGetNextEmail(string address, string subject)
595 { 605 {
596 m_LSL_Functions.llGetNextEmail(address, subject); 606 m_LSL_Functions.llGetNextEmail(address, subject);
@@ -781,6 +791,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
781 return m_LSL_Functions.llGetSimulatorHostname(); 791 return m_LSL_Functions.llGetSimulatorHostname();
782 } 792 }
783 793
794 public LSL_Integer llGetSPMaxMemory()
795 {
796 return m_LSL_Functions.llGetSPMaxMemory();
797 }
798
784 public LSL_Integer llGetStartParameter() 799 public LSL_Integer llGetStartParameter()
785 { 800 {
786 return m_LSL_Functions.llGetStartParameter(); 801 return m_LSL_Functions.llGetStartParameter();
@@ -1450,6 +1465,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1450 return m_LSL_Functions.llScriptDanger(pos); 1465 return m_LSL_Functions.llScriptDanger(pos);
1451 } 1466 }
1452 1467
1468 public void llScriptProfiler(LSL_Integer flags)
1469 {
1470 m_LSL_Functions.llScriptProfiler(flags);
1471 }
1472
1453 public LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata) 1473 public LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata)
1454 { 1474 {
1455 return m_LSL_Functions.llSendRemoteData(channel, dest, idata, sdata); 1475 return m_LSL_Functions.llSendRemoteData(channel, dest, idata, sdata);
@@ -1560,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1560 m_LSL_Functions.llSetLocalRot(rot); 1580 m_LSL_Functions.llSetLocalRot(rot);
1561 } 1581 }
1562 1582
1583 public LSL_Integer llSetMemoryLimit(LSL_Integer limit)
1584 {
1585 return m_LSL_Functions.llSetMemoryLimit(limit);
1586 }
1587
1563 public void llSetObjectDesc(string desc) 1588 public void llSetObjectDesc(string desc)
1564 { 1589 {
1565 m_LSL_Functions.llSetObjectDesc(desc); 1590 m_LSL_Functions.llSetObjectDesc(desc);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 680cefb4..d230662 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -289,8 +289,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation); 289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation);
290 } 290 }
291 291
292 // Avatar functions
292 293
293 //Texture Draw functions 294 public void osForceAttachToAvatar(int attachmentPoint)
295 {
296 m_OSSL_Functions.osForceAttachToAvatar(attachmentPoint);
297 }
298
299 public void osForceDetachFromAvatar()
300 {
301 m_OSSL_Functions.osForceDetachFromAvatar();
302 }
303
304 // Texture Draw functions
294 305
295 public string osMovePen(string drawList, int x, int y) 306 public string osMovePen(string drawList, int x, int y)
296 { 307 {
@@ -569,6 +580,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
569 m_OSSL_Functions.osNpcSay(npc, message); 580 m_OSSL_Functions.osNpcSay(npc, message);
570 } 581 }
571 582
583 public void osNpcSay(key npc, int channel, string message)
584 {
585 m_OSSL_Functions.osNpcSay(npc, channel, message);
586 }
587
588
589 public void osNpcShout(key npc, int channel, string message)
590 {
591 m_OSSL_Functions.osNpcShout(npc, channel, message);
592 }
593
572 public void osNpcSit(LSL_Key npc, LSL_Key target, int options) 594 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
573 { 595 {
574 m_OSSL_Functions.osNpcSit(npc, target, options); 596 m_OSSL_Functions.osNpcSit(npc, target, options);
@@ -594,6 +616,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
594 m_OSSL_Functions.osNpcStopAnimation(npc, animation); 616 m_OSSL_Functions.osNpcStopAnimation(npc, animation);
595 } 617 }
596 618
619 public void osNpcWhisper(key npc, int channel, string message)
620 {
621 m_OSSL_Functions.osNpcWhisper(npc, channel, message);
622 }
623
597 public LSL_Key osOwnerSaveAppearance(string notecard) 624 public LSL_Key osOwnerSaveAppearance(string notecard)
598 { 625 {
599 return m_OSSL_Functions.osOwnerSaveAppearance(notecard); 626 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
@@ -878,5 +905,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
878 { 905 {
879 return m_OSSL_Functions.osEjectFromGroup(agentId); 906 return m_OSSL_Functions.osEjectFromGroup(agentId);
880 } 907 }
908
909 public void osSetTerrainTexture(int level, LSL_Key texture)
910 {
911 m_OSSL_Functions.osSetTerrainTexture(level, texture);
912 }
913
914 public void osSetTerrainTextureHeight(int corner, double low, double high)
915 {
916 m_OSSL_Functions.osSetTerrainTextureHeight(corner, low, high);
917 }
881 } 918 }
882} 919}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5e68d69..1c59d45 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -232,7 +232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
232 foreach (string api in am.GetApis()) 232 foreach (string api in am.GetApis())
233 { 233 {
234 m_Apis[api] = am.CreateApi(api); 234 m_Apis[api] = am.CreateApi(api);
235 m_Apis[api].Initialize(engine, part, LocalID, itemID); 235 m_Apis[api].Initialize(engine, part, ScriptTask);
236 } 236 }
237 237
238 try 238 try
@@ -966,7 +966,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
966 public IScriptApi GetApi(string name) 966 public IScriptApi GetApi(string name)
967 { 967 {
968 if (m_Apis.ContainsKey(name)) 968 if (m_Apis.ContainsKey(name))
969 {
970// m_log.DebugFormat("[SCRIPT INSTANCE]: Found api {0} in {1}@{2}", name, ScriptName, PrimName);
971
969 return m_Apis[name]; 972 return m_Apis[name];
973 }
974
975// m_log.DebugFormat("[SCRIPT INSTANCE]: Did not find api {0} in {1}@{2}", name, ScriptName, PrimName);
976
970 return null; 977 return null;
971 } 978 }
972 979
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
index e2d0db2..c73e22f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
@@ -63,7 +63,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
63 IConfig config = initConfigSource.AddConfig("XEngine"); 63 IConfig config = initConfigSource.AddConfig("XEngine");
64 config.Set("Enabled", "true"); 64 config.Set("Enabled", "true");
65 65
66 m_scene = SceneHelpers.SetupScene(); 66 m_scene = new SceneHelpers().SetupScene();
67 SceneHelpers.SetupSceneModules(m_scene, initConfigSource); 67 SceneHelpers.SetupSceneModules(m_scene, initConfigSource);
68 68
69 m_engine = new XEngine.XEngine(); 69 m_engine = new XEngine.XEngine();
@@ -91,7 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
91 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId); 91 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId);
92 92
93 LSL_Api api = new LSL_Api(); 93 LSL_Api api = new LSL_Api();
94 api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID); 94 api.Initialize(m_engine, so1.RootPart, null);
95 95
96 // Create a second object 96 // Create a second object
97 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100); 97 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100);
@@ -124,7 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
124 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10); 124 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10);
125 m_scene.AddSceneObject(so1); 125 m_scene.AddSceneObject(so1);
126 LSL_Api api = new LSL_Api(); 126 LSL_Api api = new LSL_Api();
127 api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID); 127 api.Initialize(m_engine, so1.RootPart, null);
128 128
129 // Create an object embedded inside the first 129 // Create an object embedded inside the first
130 UUID itemId = TestHelpers.ParseTail(0x20); 130 UUID itemId = TestHelpers.ParseTail(0x20);
@@ -134,7 +134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
134 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100); 134 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100);
135 m_scene.AddSceneObject(so2); 135 m_scene.AddSceneObject(so2);
136 LSL_Api api2 = new LSL_Api(); 136 LSL_Api api2 = new LSL_Api();
137 api2.Initialize(m_engine, so2.RootPart, so2.RootPart.LocalId, so2.RootPart.UUID); 137 api2.Initialize(m_engine, so2.RootPart, null);
138 138
139 // *** Firstly, we test where llAllowInventoryDrop() has not been called. *** 139 // *** Firstly, we test where llAllowInventoryDrop() has not been called. ***
140 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName); 140 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
new file mode 100644
index 0000000..bc3b790
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiLinkingTests.cs
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.ScriptEngine.Shared.Tests
50{
51 /// <summary>
52 /// Tests for linking functions in LSL
53 /// </summary>
54 /// <remarks>
55 /// This relates to LSL. Actual linking functionality should be tested in the main
56 /// OpenSim.Region.Framework.Scenes.Tests.SceneObjectLinkingTests.
57 /// </remarks>
58 [TestFixture]
59 public class LSL_ApiLinkingTests
60 {
61 protected Scene m_scene;
62 protected XEngine.XEngine m_engine;
63
64 [SetUp]
65 public void SetUp()
66 {
67 IConfigSource initConfigSource = new IniConfigSource();
68 IConfig config = initConfigSource.AddConfig("XEngine");
69 config.Set("Enabled", "true");
70
71 m_scene = new SceneHelpers().SetupScene();
72 SceneHelpers.SetupSceneModules(m_scene, initConfigSource);
73
74 m_engine = new XEngine.XEngine();
75 m_engine.Initialise(initConfigSource);
76 m_engine.AddRegion(m_scene);
77 }
78
79 [Test]
80 public void TestllCreateLink()
81 {
82 TestHelpers.InMethod();
83
84 UUID ownerId = TestHelpers.ParseTail(0x1);
85
86 SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10);
87 grp1.AbsolutePosition = new Vector3(10, 10, 10);
88 m_scene.AddSceneObject(grp1);
89
90 // FIXME: This should really be a script item (with accompanying script)
91 TaskInventoryItem grp1Item
92 = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart);
93 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
94
95 SceneObjectGroup grp2 = SceneHelpers.CreateSceneObject(2, ownerId, "grp2-", 0x20);
96 grp2.AbsolutePosition = new Vector3(20, 20, 20);
97
98 // <180,0,0>
99 grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0));
100
101 m_scene.AddSceneObject(grp2);
102
103 LSL_Api apiGrp1 = new LSL_Api();
104 apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item);
105
106 apiGrp1.llCreateLink(grp2.UUID.ToString(), ScriptBaseClass.TRUE);
107
108 Assert.That(grp1.Parts.Length, Is.EqualTo(4));
109 Assert.That(grp2.IsDeleted, Is.True);
110 }
111
112 [Test]
113 public void TestllBreakLink()
114 {
115 TestHelpers.InMethod();
116
117 UUID ownerId = TestHelpers.ParseTail(0x1);
118
119 SceneObjectGroup grp1 = SceneHelpers.CreateSceneObject(2, ownerId, "grp1-", 0x10);
120 grp1.AbsolutePosition = new Vector3(10, 10, 10);
121 m_scene.AddSceneObject(grp1);
122
123 // FIXME: This should really be a script item (with accompanying script)
124 TaskInventoryItem grp1Item
125 = TaskInventoryHelpers.AddNotecard(m_scene, grp1.RootPart);
126 grp1Item.PermsMask |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
127
128 LSL_Api apiGrp1 = new LSL_Api();
129 apiGrp1.Initialize(m_engine, grp1.RootPart, grp1Item);
130
131 apiGrp1.llBreakLink(2);
132
133 Assert.That(grp1.Parts.Length, Is.EqualTo(1));
134
135 SceneObjectGroup grp2 = m_scene.GetSceneObjectGroup("grp1-Part1");
136 Assert.That(grp2, Is.Not.Null);
137 }
138 }
139} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 9cf9258..f96a156 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -58,7 +58,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
58 IConfig config = initConfigSource.AddConfig("XEngine"); 58 IConfig config = initConfigSource.AddConfig("XEngine");
59 config.Set("Enabled", "true"); 59 config.Set("Enabled", "true");
60 60
61 Scene scene = SceneHelpers.SetupScene(); 61 Scene scene = new SceneHelpers().SetupScene();
62 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 62 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
63 63
64 XEngine.XEngine engine = new XEngine.XEngine(); 64 XEngine.XEngine engine = new XEngine.XEngine();
@@ -66,8 +66,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
66 engine.AddRegion(scene); 66 engine.AddRegion(scene);
67 67
68 m_lslApi = new LSL_Api(); 68 m_lslApi = new LSL_Api();
69 m_lslApi.Initialize(engine, part, part.LocalId, part.UUID); 69 m_lslApi.Initialize(engine, part, null);
70
71 } 70 }
72 71
73 [Test] 72 [Test]
@@ -261,7 +260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
261 TestHelpers.InMethod(); 260 TestHelpers.InMethod();
262 261
263 // Create Prim1. 262 // Create Prim1.
264 Scene scene = SceneHelpers.SetupScene(); 263 Scene scene = new SceneHelpers().SetupScene();
265 string obj1Name = "Prim1"; 264 string obj1Name = "Prim1";
266 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); 265 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
267 SceneObjectPart part1 = 266 SceneObjectPart part1 =
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index 7573dff..3965734 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
67 config = initConfigSource.AddConfig("NPC"); 67 config = initConfigSource.AddConfig("NPC");
68 config.Set("Enabled", "true"); 68 config.Set("Enabled", "true");
69 69
70 m_scene = SceneHelpers.SetupScene(); 70 m_scene = new SceneHelpers().SetupScene();
71 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); 71 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
72 72
73 m_engine = new XEngine.XEngine(); 73 m_engine = new XEngine.XEngine();
@@ -95,7 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
95 m_scene.AddSceneObject(so); 95 m_scene.AddSceneObject(so);
96 96
97 OSSL_Api osslApi = new OSSL_Api(); 97 OSSL_Api osslApi = new OSSL_Api();
98 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 98 osslApi.Initialize(m_engine, part, null);
99 99
100 string notecardName = "appearanceNc"; 100 string notecardName = "appearanceNc";
101 osslApi.osOwnerSaveAppearance(notecardName); 101 osslApi.osOwnerSaveAppearance(notecardName);
@@ -130,7 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
130 m_scene.AddSceneObject(so); 130 m_scene.AddSceneObject(so);
131 131
132 OSSL_Api osslApi = new OSSL_Api(); 132 OSSL_Api osslApi = new OSSL_Api();
133 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 133 osslApi.Initialize(m_engine, part, null);
134 134
135 string notecardName = "appearanceNc"; 135 string notecardName = "appearanceNc";
136 osslApi.osOwnerSaveAppearance(notecardName); 136 osslApi.osOwnerSaveAppearance(notecardName);
@@ -161,7 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
161 m_scene.AddSceneObject(so); 161 m_scene.AddSceneObject(so);
162 162
163 OSSL_Api osslApi = new OSSL_Api(); 163 OSSL_Api osslApi = new OSSL_Api();
164 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 164 osslApi.Initialize(m_engine, part, null);
165 165
166 string notecardName = "appearanceNc"; 166 string notecardName = "appearanceNc";
167 167
@@ -202,7 +202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
202 m_scene.AddSceneObject(so); 202 m_scene.AddSceneObject(so);
203 203
204 OSSL_Api osslApi = new OSSL_Api(); 204 OSSL_Api osslApi = new OSSL_Api();
205 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 205 osslApi.Initialize(m_engine, part, null);
206 206
207 string notecardName = "appearanceNc"; 207 string notecardName = "appearanceNc";
208 208
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 9d9fc51..0ccd889 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
68 config = initConfigSource.AddConfig("NPC"); 68 config = initConfigSource.AddConfig("NPC");
69 config.Set("Enabled", "true"); 69 config.Set("Enabled", "true");
70 70
71 m_scene = SceneHelpers.SetupScene(); 71 m_scene = new SceneHelpers().SetupScene();
72 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); 72 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
73 73
74 m_engine = new XEngine.XEngine(); 74 m_engine = new XEngine.XEngine();
@@ -104,10 +104,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
104 m_scene.AddSceneObject(otherSo); 104 m_scene.AddSceneObject(otherSo);
105 105
106 OSSL_Api osslApi = new OSSL_Api(); 106 OSSL_Api osslApi = new OSSL_Api();
107 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 107 osslApi.Initialize(m_engine, part, null);
108 108
109 OSSL_Api otherOsslApi = new OSSL_Api(); 109 OSSL_Api otherOsslApi = new OSSL_Api();
110 otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, otherPart.UUID); 110 otherOsslApi.Initialize(m_engine, otherPart, null);
111 111
112 string notecardName = "appearanceNc"; 112 string notecardName = "appearanceNc";
113 osslApi.osOwnerSaveAppearance(notecardName); 113 osslApi.osOwnerSaveAppearance(notecardName);
@@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
151 m_scene.AddSceneObject(so); 151 m_scene.AddSceneObject(so);
152 152
153 OSSL_Api osslApi = new OSSL_Api(); 153 OSSL_Api osslApi = new OSSL_Api();
154 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID); 154 osslApi.Initialize(m_engine, part, null);
155 155
156 string notecardName = "appearanceNc"; 156 string notecardName = "appearanceNc";
157 osslApi.osOwnerSaveAppearance(notecardName); 157 osslApi.osOwnerSaveAppearance(notecardName);
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
index 7d7bd82..a3f848c 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine.Tests
73 // to AssemblyResolver.OnAssemblyResolve fails. 73 // to AssemblyResolver.OnAssemblyResolve fails.
74 xEngineConfig.Set("AppDomainLoading", "false"); 74 xEngineConfig.Set("AppDomainLoading", "false");
75 75
76 m_scene = SceneHelpers.SetupScene("My Test", UUID.Random(), 1000, 1000, null, configSource); 76 m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource);
77 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); 77 SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule);
78 m_scene.StartScripts(); 78 m_scene.StartScripts();
79 } 79 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 1e0f01f..eeb125e 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1089,11 +1089,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1089 1089
1090 AppDomain sandbox; 1090 AppDomain sandbox;
1091 if (m_AppDomainLoading) 1091 if (m_AppDomainLoading)
1092 {
1092 sandbox = AppDomain.CreateDomain( 1093 sandbox = AppDomain.CreateDomain(
1093 m_Scene.RegionInfo.RegionID.ToString(), 1094 m_Scene.RegionInfo.RegionID.ToString(),
1094 evidence, appSetup); 1095 evidence, appSetup);
1096 m_AppDomains[appDomain].AssemblyResolve +=
1097 new ResolveEventHandler(
1098 AssemblyResolver.OnAssemblyResolve);
1099 }
1095 else 1100 else
1101 {
1096 sandbox = AppDomain.CurrentDomain; 1102 sandbox = AppDomain.CurrentDomain;
1103 }
1097 1104
1098 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1105 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1099 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1106 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
@@ -1105,9 +1112,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1105 1112
1106 m_AppDomains[appDomain] = sandbox; 1113 m_AppDomains[appDomain] = sandbox;
1107 1114
1108 m_AppDomains[appDomain].AssemblyResolve +=
1109 new ResolveEventHandler(
1110 AssemblyResolver.OnAssemblyResolve);
1111 m_DomainScripts[appDomain] = new List<UUID>(); 1115 m_DomainScripts[appDomain] = new List<UUID>();
1112 } 1116 }
1113 catch (Exception e) 1117 catch (Exception e)
@@ -1898,9 +1902,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1898 // if there already exists a file at that location, it may be locked. 1902 // if there already exists a file at that location, it may be locked.
1899 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", path, ex.Message); 1903 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", path, ex.Message);
1900 } 1904 }
1905
1906 string textpath = path + ".text";
1901 try 1907 try
1902 { 1908 {
1903 using (FileStream fs = File.Create(path + ".text")) 1909 using (FileStream fs = File.Create(textpath))
1904 { 1910 {
1905 using (StreamWriter sw = new StreamWriter(fs)) 1911 using (StreamWriter sw = new StreamWriter(fs))
1906 { 1912 {
@@ -1913,7 +1919,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1913 catch (IOException ex) 1919 catch (IOException ex)
1914 { 1920 {
1915 // if there already exists a file at that location, it may be locked. 1921 // if there already exists a file at that location, it may be locked.
1916 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", path, ex.Message); 1922 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", textpath, ex.Message);
1917 } 1923 }
1918 } 1924 }
1919 } 1925 }
@@ -1962,7 +1968,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1962 catch (IOException ex) 1968 catch (IOException ex)
1963 { 1969 {
1964 // if there already exists a file at that location, it may be locked. 1970 // if there already exists a file at that location, it may be locked.
1965 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", statepath, ex.Message); 1971 m_log.ErrorFormat("[XEngine]: File {0} already exists! {1}", mappath, ex.Message);
1966 } 1972 }
1967 } 1973 }
1968 1974
@@ -1997,45 +2003,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1997 if (!topScripts.ContainsKey(si.LocalID)) 2003 if (!topScripts.ContainsKey(si.LocalID))
1998 topScripts[si.RootLocalID] = 0; 2004 topScripts[si.RootLocalID] = 0;
1999 2005
2000// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; 2006 topScripts[si.RootLocalID] += CalculateAdjustedExectionTime(si, tickNow);
2001// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); 2007 }
2002 2008 }
2003 // Execution time of the script adjusted by it's measurement period to make scripts started at
2004 // different times comparable.
2005// float adjustedExecutionTime
2006// = (float)si.MeasurementPeriodExecutionTime
2007// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
2008// / TimeSpan.TicksPerMillisecond;
2009
2010 long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
2011
2012 // Avoid divide by zerp
2013 if (ticksElapsed == 0)
2014 ticksElapsed = 1;
2015 2009
2016 // Scale execution time to the ideal 55 fps frame time for these reasons. 2010 return topScripts;
2017 // 2011 }
2018 // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
2019 // 'script execution time per frame', which is the original purpose of this value.
2020 //
2021 // 2) Giving the raw execution times is misleading since scripts start at different times, making
2022 // it impossible to compare scripts.
2023 //
2024 // 3) Scaling the raw execution time to the time that the script has been running is better but
2025 // is still misleading since a script that has just been rezzed may appear to have been running
2026 // for much longer.
2027 //
2028 // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
2029 // since the figure does not represent actual execution time and very hard running scripts will
2030 // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
2031 float adjustedExecutionTime
2032 = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
2033 2012
2034 topScripts[si.RootLocalID] += adjustedExecutionTime; 2013 public float GetScriptExecutionTime(List<UUID> itemIDs)
2014 {
2015 if (itemIDs == null|| itemIDs.Count == 0)
2016 {
2017 return 0.0f;
2018 }
2019 float time = 0.0f;
2020 long tickNow = Util.EnvironmentTickCount();
2021 IScriptInstance si;
2022 // Calculate the time for all scripts that this engine is executing
2023 // Ignore any others
2024 foreach (UUID id in itemIDs)
2025 {
2026 si = GetInstance(id);
2027 if (si != null && si.Running)
2028 {
2029 time += CalculateAdjustedExectionTime(si, tickNow);
2035 } 2030 }
2036 } 2031 }
2032 return time;
2033 }
2037 2034
2038 return topScripts; 2035 private float CalculateAdjustedExectionTime(IScriptInstance si, long tickNow)
2036 {
2037 long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
2038
2039 // Avoid divide by zero
2040 if (ticksElapsed == 0)
2041 ticksElapsed = 1;
2042
2043 // Scale execution time to the ideal 55 fps frame time for these reasons.
2044 //
2045 // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
2046 // 'script execution time per frame', which is the original purpose of this value.
2047 //
2048 // 2) Giving the raw execution times is misleading since scripts start at different times, making
2049 // it impossible to compare scripts.
2050 //
2051 // 3) Scaling the raw execution time to the time that the script has been running is better but
2052 // is still misleading since a script that has just been rezzed may appear to have been running
2053 // for much longer.
2054 //
2055 // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
2056 // since the figure does not represent actual execution time and very hard running scripts will
2057 // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
2058 return ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
2039 } 2059 }
2040 2060
2041 public void SuspendScript(UUID itemID) 2061 public void SuspendScript(UUID itemID)
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs
index b9ba4bc..faf746f 100644
--- a/OpenSim/Region/UserStatistics/WebStatsModule.cs
+++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs
@@ -90,7 +90,7 @@ namespace OpenSim.Region.UserStatistics
90 90
91 dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3"); 91 dbConn = new SqliteConnection("URI=file:LocalUserStatistics.db,version=3");
92 dbConn.Open(); 92 dbConn.Open();
93 CheckAndUpdateDatabase(dbConn); 93 CreateTables(dbConn);
94 94
95 Prototype_distributor protodep = new Prototype_distributor(); 95 Prototype_distributor protodep = new Prototype_distributor();
96 Updater_distributor updatedep = new Updater_distributor(); 96 Updater_distributor updatedep = new Updater_distributor();
@@ -131,7 +131,7 @@ namespace OpenSim.Region.UserStatistics
131 } 131 }
132 } 132 }
133 133
134 public void ReceiveClassicSimStatsPacket(SimStats stats) 134 private void ReceiveClassicSimStatsPacket(SimStats stats)
135 { 135 {
136 if (!enabled) 136 if (!enabled)
137 { 137 {
@@ -163,7 +163,7 @@ namespace OpenSim.Region.UserStatistics
163 } 163 }
164 } 164 }
165 165
166 public Hashtable HandleUnknownCAPSRequest(Hashtable request) 166 private Hashtable HandleUnknownCAPSRequest(Hashtable request)
167 { 167 {
168 //string regpath = request["uri"].ToString(); 168 //string regpath = request["uri"].ToString();
169 int response_code = 200; 169 int response_code = 200;
@@ -178,7 +178,7 @@ namespace OpenSim.Region.UserStatistics
178 return responsedata; 178 return responsedata;
179 } 179 }
180 180
181 public Hashtable HandleStatsRequest(Hashtable request) 181 private Hashtable HandleStatsRequest(Hashtable request)
182 { 182 {
183 lastHit = System.Environment.TickCount; 183 lastHit = System.Environment.TickCount;
184 Hashtable responsedata = new Hashtable(); 184 Hashtable responsedata = new Hashtable();
@@ -237,36 +237,12 @@ namespace OpenSim.Region.UserStatistics
237 237
238 return responsedata; 238 return responsedata;
239 } 239 }
240
241 public void CheckAndUpdateDatabase(SqliteConnection db)
242 {
243 lock (db)
244 {
245 // TODO: FIXME: implement stats migrations
246 const string SQL = @"SELECT * FROM migrations LIMIT 1";
247
248 using (SqliteCommand cmd = new SqliteCommand(SQL, db))
249 {
250 try
251 {
252 cmd.ExecuteNonQuery();
253 }
254 catch (SqliteSyntaxException)
255 {
256 CreateTables(db);
257 }
258 }
259 }
260 }
261 240
262 public void CreateTables(SqliteConnection db) 241 private void CreateTables(SqliteConnection db)
263 { 242 {
264 using (SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db)) 243 using (SqliteCommand createcmd = new SqliteCommand(SQL_STATS_TABLE_CREATE, db))
265 { 244 {
266 createcmd.ExecuteNonQuery(); 245 createcmd.ExecuteNonQuery();
267
268 createcmd.CommandText = SQL_MIGRA_TABLE_CREATE;
269 createcmd.ExecuteNonQuery();
270 } 246 }
271 } 247 }
272 248
@@ -301,22 +277,23 @@ namespace OpenSim.Region.UserStatistics
301 get { return true; } 277 get { return true; }
302 } 278 }
303 279
304 public void OnRegisterCaps(UUID agentID, Caps caps) 280 private void OnRegisterCaps(UUID agentID, Caps caps)
305 { 281 {
306// m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); 282// m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
307 283
308 string capsPath = "/CAPS/VS/" + UUID.Random(); 284 string capsPath = "/CAPS/VS/" + UUID.Random();
309 caps.RegisterHandler("ViewerStats", 285 caps.RegisterHandler(
310 new RestStreamHandler("POST", capsPath, 286 "ViewerStats",
311 delegate(string request, string path, string param, 287 new RestStreamHandler(
312 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 288 "POST",
313 { 289 capsPath,
314 return ViewerStatsReport(request, path, param, 290 (request, path, param, httpRequest, httpResponse)
315 agentID, caps); 291 => ViewerStatsReport(request, path, param, agentID, caps),
316 })); 292 "ViewerStats",
293 agentID.ToString()));
317 } 294 }
318 295
319 public void OnDeRegisterCaps(UUID agentID, Caps caps) 296 private void OnDeRegisterCaps(UUID agentID, Caps caps)
320 { 297 {
321 } 298 }
322 299
@@ -336,7 +313,7 @@ namespace OpenSim.Region.UserStatistics
336 } 313 }
337 } 314 }
338 315
339 public void OnMakeRootAgent(ScenePresence agent) 316 private void OnMakeRootAgent(ScenePresence agent)
340 { 317 {
341 UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle); 318 UUID regionUUID = GetRegionUUIDFromHandle(agent.RegionHandle);
342 319
@@ -365,11 +342,11 @@ namespace OpenSim.Region.UserStatistics
365 } 342 }
366 } 343 }
367 344
368 public void OnMakeChildAgent(ScenePresence agent) 345 private void OnMakeChildAgent(ScenePresence agent)
369 { 346 {
370 } 347 }
371 348
372 public void OnClientClosed(UUID agentID, Scene scene) 349 private void OnClientClosed(UUID agentID, Scene scene)
373 { 350 {
374 lock (m_sessions) 351 lock (m_sessions)
375 { 352 {
@@ -380,7 +357,7 @@ namespace OpenSim.Region.UserStatistics
380 } 357 }
381 } 358 }
382 359
383 public string readLogLines(int amount) 360 private string readLogLines(int amount)
384 { 361 {
385 Encoding encoding = Encoding.ASCII; 362 Encoding encoding = Encoding.ASCII;
386 int sizeOfChar = encoding.GetByteCount("\n"); 363 int sizeOfChar = encoding.GetByteCount("\n");
@@ -418,7 +395,7 @@ namespace OpenSim.Region.UserStatistics
418 return encoding.GetString(buffer); 395 return encoding.GetString(buffer);
419 } 396 }
420 397
421 public UUID GetRegionUUIDFromHandle(ulong regionhandle) 398 private UUID GetRegionUUIDFromHandle(ulong regionhandle)
422 { 399 {
423 lock (m_scenes) 400 lock (m_scenes)
424 { 401 {
@@ -441,17 +418,17 @@ namespace OpenSim.Region.UserStatistics
441 /// <param name="agentID"></param> 418 /// <param name="agentID"></param>
442 /// <param name="caps"></param> 419 /// <param name="caps"></param>
443 /// <returns></returns> 420 /// <returns></returns>
444 public string ViewerStatsReport(string request, string path, string param, 421 private string ViewerStatsReport(string request, string path, string param,
445 UUID agentID, Caps caps) 422 UUID agentID, Caps caps)
446 { 423 {
447// m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID); 424// m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID);
448 425
449 UpdateUserStats(ParseViewerStats(request,agentID), dbConn); 426 UpdateUserStats(ParseViewerStats(request, agentID), dbConn);
450 427
451 return String.Empty; 428 return String.Empty;
452 } 429 }
453 430
454 public UserSessionID ParseViewerStats(string request, UUID agentID) 431 private UserSessionID ParseViewerStats(string request, UUID agentID)
455 { 432 {
456 UserSessionID uid = new UserSessionID(); 433 UserSessionID uid = new UserSessionID();
457 UserSessionData usd; 434 UserSessionData usd;
@@ -592,14 +569,14 @@ namespace OpenSim.Region.UserStatistics
592 return uid; 569 return uid;
593 } 570 }
594 571
595 public void UpdateUserStats(UserSessionID uid, SqliteConnection db) 572 private void UpdateUserStats(UserSessionID uid, SqliteConnection db)
596 { 573 {
597 if (uid.session_id == UUID.Zero) 574 if (uid.session_id == UUID.Zero)
598 return; 575 return;
599 576
600 lock (db) 577 lock (db)
601 { 578 {
602 using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_UPDATE, db)) 579 using (SqliteCommand updatecmd = new SqliteCommand(SQL_STATS_TABLE_INSERT, db))
603 { 580 {
604 updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString())); 581 updatecmd.Parameters.Add(new SqliteParameter(":session_id", uid.session_data.session_id.ToString()));
605 updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString())); 582 updatecmd.Parameters.Add(new SqliteParameter(":agent_id", uid.session_data.agent_id.ToString()));
@@ -648,44 +625,26 @@ namespace OpenSim.Region.UserStatistics
648 updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped)); 625 updatecmd.Parameters.Add(new SqliteParameter(":f_dropped", uid.session_data.f_dropped));
649 updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends)); 626 updatecmd.Parameters.Add(new SqliteParameter(":f_failed_resends", uid.session_data.f_failed_resends));
650 updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid)); 627 updatecmd.Parameters.Add(new SqliteParameter(":f_invalid", uid.session_data.f_invalid));
651
652 updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit)); 628 updatecmd.Parameters.Add(new SqliteParameter(":f_off_circuit", uid.session_data.f_off_circuit));
653 updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent)); 629 updatecmd.Parameters.Add(new SqliteParameter(":f_resent", uid.session_data.f_resent));
654 updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet)); 630 updatecmd.Parameters.Add(new SqliteParameter(":f_send_packet", uid.session_data.f_send_packet));
655
656 updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString()));
657 updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString()));
658 updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString()));
659 631
660// m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id); 632// StringBuilder parameters = new StringBuilder();
661 633// SqliteParameterCollection spc = updatecmd.Parameters;
662 int result = updatecmd.ExecuteNonQuery(); 634// foreach (SqliteParameter sp in spc)
663 635// parameters.AppendFormat("{0}={1},", sp.ParameterName, sp.Value);
664 if (result == 0) 636//
665 { 637// m_log.DebugFormat("[WEB STATS MODULE]: Parameters {0}", parameters);
666// m_log.DebugFormat("[WEB STATS MODULE]: Database stats insert for {0}", uid.session_data.agent_id);
667 638
668 updatecmd.CommandText = SQL_STATS_TABLE_INSERT; 639// m_log.DebugFormat("[WEB STATS MODULE]: Database stats update for {0}", uid.session_data.agent_id);
669 640
670 try 641 updatecmd.ExecuteNonQuery();
671 {
672 updatecmd.ExecuteNonQuery();
673 }
674 catch (Exception e)
675 {
676 m_log.WarnFormat(
677 "[WEB STATS MODULE]: failed to write stats for {0}, storage Execution Exception {1}{2}",
678 uid.session_data.agent_id, e.Message, e.StackTrace);
679 }
680 }
681 } 642 }
682 } 643 }
683 } 644 }
684 645
685 #region SQL 646 #region SQL
686 private const string SQL_MIGRA_TABLE_CREATE = @"create table migrations(name varchar(100), version int)"; 647 private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE IF NOT EXISTS stats_session_data (
687
688 private const string SQL_STATS_TABLE_CREATE = @"CREATE TABLE stats_session_data (
689 session_id VARCHAR(36) NOT NULL PRIMARY KEY, 648 session_id VARCHAR(36) NOT NULL PRIMARY KEY,
690 agent_id VARCHAR(36) NOT NULL DEFAULT '', 649 agent_id VARCHAR(36) NOT NULL DEFAULT '',
691 region_id VARCHAR(36) NOT NULL DEFAULT '', 650 region_id VARCHAR(36) NOT NULL DEFAULT '',
@@ -735,11 +694,11 @@ namespace OpenSim.Region.UserStatistics
735 f_send_packet INT NOT NULL DEFAULT '0' 694 f_send_packet INT NOT NULL DEFAULT '0'
736 );"; 695 );";
737 696
738 private const string SQL_STATS_TABLE_INSERT = @"INSERT INTO stats_session_data ( 697 private const string SQL_STATS_TABLE_INSERT = @"INSERT OR REPLACE INTO stats_session_data (
739session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view, 698session_id, agent_id, region_id, last_updated, remote_ip, name_f, name_l, avg_agents_in_view, min_agents_in_view, max_agents_in_view,
740mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping, 699mode_agents_in_view, avg_fps, min_fps, max_fps, mode_fps, a_language, mem_use, meters_traveled, avg_ping, min_ping, max_ping, mode_ping,
741regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram, 700regions_visited, run_time, avg_sim_fps, min_sim_fps, max_sim_fps, mode_sim_fps, start_time, client_version, s_cpu, s_gpu, s_os, s_ram,
742d_object_kb, d_texture_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_invalid, f_off_circuit, 701d_object_kb, d_texture_kb, d_world_kb, n_in_kb, n_in_pk, n_out_kb, n_out_pk, f_dropped, f_failed_resends, f_invalid, f_off_circuit,
743f_resent, f_send_packet 702f_resent, f_send_packet
744) 703)
745VALUES 704VALUES
@@ -747,62 +706,13 @@ VALUES
747:session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view, 706:session_id, :agent_id, :region_id, :last_updated, :remote_ip, :name_f, :name_l, :avg_agents_in_view, :min_agents_in_view, :max_agents_in_view,
748:mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping, 707:mode_agents_in_view, :avg_fps, :min_fps, :max_fps, :mode_fps, :a_language, :mem_use, :meters_traveled, :avg_ping, :min_ping, :max_ping, :mode_ping,
749:regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram, 708:regions_visited, :run_time, :avg_sim_fps, :min_sim_fps, :max_sim_fps, :mode_sim_fps, :start_time, :client_version, :s_cpu, :s_gpu, :s_os, :s_ram,
750:d_object_kb, :d_texture_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_invalid, :f_off_circuit, 709:d_object_kb, :d_texture_kb, :d_world_kb, :n_in_kb, :n_in_pk, :n_out_kb, :n_out_pk, :f_dropped, :f_failed_resends, :f_invalid, :f_off_circuit,
751:f_resent, :f_send_packet 710:f_resent, :f_send_packet
752) 711)
753"; 712";
754 713
755 private const string SQL_STATS_TABLE_UPDATE = @" 714 #endregion
756UPDATE stats_session_data 715
757set session_id=:session_id,
758 agent_id=:agent_id,
759 region_id=:region_id,
760 last_updated=:last_updated,
761 remote_ip=:remote_ip,
762 name_f=:name_f,
763 name_l=:name_l,
764 avg_agents_in_view=:avg_agents_in_view,
765 min_agents_in_view=:min_agents_in_view,
766 max_agents_in_view=:max_agents_in_view,
767 mode_agents_in_view=:mode_agents_in_view,
768 avg_fps=:avg_fps,
769 min_fps=:min_fps,
770 max_fps=:max_fps,
771 mode_fps=:mode_fps,
772 a_language=:a_language,
773 mem_use=:mem_use,
774 meters_traveled=:meters_traveled,
775 avg_ping=:avg_ping,
776 min_ping=:min_ping,
777 max_ping=:max_ping,
778 mode_ping=:mode_ping,
779 regions_visited=:regions_visited,
780 run_time=:run_time,
781 avg_sim_fps=:avg_sim_fps,
782 min_sim_fps=:min_sim_fps,
783 max_sim_fps=:max_sim_fps,
784 mode_sim_fps=:mode_sim_fps,
785 start_time=:start_time,
786 client_version=:client_version,
787 s_cpu=:s_cpu,
788 s_gpu=:s_gpu,
789 s_os=:s_os,
790 s_ram=:s_ram,
791 d_object_kb=:d_object_kb,
792 d_texture_kb=:d_texture_kb,
793 d_world_kb=:d_world_kb,
794 n_in_kb=:n_in_kb,
795 n_in_pk=:n_in_pk,
796 n_out_kb=:n_out_kb,
797 n_out_pk=:n_out_pk,
798 f_dropped=:f_dropped,
799 f_failed_resends=:f_failed_resends,
800 f_invalid=:f_invalid,
801 f_off_circuit=:f_off_circuit,
802 f_resent=:f_resent,
803 f_send_packet=:f_send_packet
804WHERE session_id=:session_key AND agent_id=:agent_key AND region_id=:region_key";
805 #endregion
806 } 716 }
807 717
808 public static class UserSessionUtil 718 public static class UserSessionUtil