aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/IXAssetDataPlugin.cs (renamed from OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs)44
-rw-r--r--OpenSim/Region/Application/OpenSim.cs127
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs239
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs32
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs330
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs69
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs161
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs7
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs124
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs38
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs34
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs59
-rw-r--r--OpenSim/Region/CoreModules/World/Access/AccessModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs47
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs156
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs33
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Sun/SunModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs76
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/WindModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs36
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
-rw-r--r--OpenSim/Region/DataSnapshot/DataRequestHandler.cs52
-rw-r--r--OpenSim/Region/DataSnapshot/DataSnapshotManager.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs11
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs12
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/IWorldComm.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs108
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs53
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs710
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs55
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs97
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs60
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs14
-rw-r--r--OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs10
-rwxr-xr-xOpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs34
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs15
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs174
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs8
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs20
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs149
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs41
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs35
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs133
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs19
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs21
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs26
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs13
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs42
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs249
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs48
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs33
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs419
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs168
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs74
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs42
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs116
120 files changed, 4095 insertions, 1849 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs b/OpenSim/Data/IXAssetDataPlugin.cs
index 659c3a5..74ad6f4 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs
+++ b/OpenSim/Data/IXAssetDataPlugin.cs
@@ -26,38 +26,22 @@
26 */ 26 */
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Xml;
30using OpenMetaverse; 29using OpenMetaverse;
30using OpenSim.Framework;
31 31
32namespace OpenSim.Region.Framework.Scenes.Animation 32namespace OpenSim.Data
33{ 33{
34 public class AvatarAnimations 34 /// <summary>
35 /// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
36 /// for now.
37 /// </summary>
38 public interface IXAssetDataPlugin : IPlugin
35 { 39 {
36 public Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>(); 40 AssetBase GetAsset(UUID uuid);
37 public Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>(); 41 void StoreAsset(AssetBase asset);
38 public Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>(); 42 bool ExistsAsset(UUID uuid);
39 43 List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
40 public AvatarAnimations() 44 void Initialise(string connect);
41 { 45 bool Delete(string id);
42 using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
43 {
44 XmlDocument doc = new XmlDocument();
45 doc.Load(reader);
46 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
47 {
48 if (nod.Attributes["name"] != null)
49 {
50 string name = (string)nod.Attributes["name"].Value;
51 UUID id = (UUID)nod.InnerText;
52 string animState = (string)nod.Attributes["state"].Value;
53
54 AnimsUUID.Add(name, id);
55 AnimsNames.Add(id, name);
56 if (animState != "")
57 AnimStateNames.Add(id, animState);
58 }
59 }
60 }
61 }
62 } 46 }
63} 47} \ No newline at end of file
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 145875b..59b6b21 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -225,12 +225,12 @@ namespace OpenSim
225 /// </summary> 225 /// </summary>
226 private void RegisterConsoleCommands() 226 private void RegisterConsoleCommands()
227 { 227 {
228 m_console.Commands.AddCommand("region", false, "force update", 228 m_console.Commands.AddCommand("Regions", 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);
232 232
233 m_console.Commands.AddCommand("region", false, "debug packet", 233 m_console.Commands.AddCommand("Comms", false, "debug packet",
234 "debug packet <level> [<avatar-first-name> <avatar-last-name>]", 234 "debug packet <level> [<avatar-first-name> <avatar-last-name>]",
235 "Turn on packet debugging", 235 "Turn on packet debugging",
236 "If level > 255 then all incoming and outgoing packets are logged.\n" 236 "If level > 255 then all incoming and outgoing packets are logged.\n"
@@ -242,7 +242,7 @@ namespace OpenSim
242 + "If an avatar name is given then only packets from that avatar are logged", 242 + "If an avatar name is given then only packets from that avatar are logged",
243 Debug); 243 Debug);
244 244
245 m_console.Commands.AddCommand("region", false, "debug http", 245 m_console.Commands.AddCommand("Comms", false, "debug http",
246 "debug http <level>", 246 "debug http <level>",
247 "Turn on inbound http request debugging for everything except the event queue (see debug eq).", 247 "Turn on inbound http request debugging for everything except the event queue (see debug eq).",
248 "If level >= 2 then the handler used to service the request is logged.\n" 248 "If level >= 2 then the handler used to service the request is logged.\n"
@@ -250,37 +250,37 @@ namespace OpenSim
250 + "If level <= 0 then no extra http logging is done.\n", 250 + "If level <= 0 then no extra http logging is done.\n",
251 Debug); 251 Debug);
252 252
253 m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); 253 m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
254 254
255 m_console.Commands.AddCommand("region", false, "debug scene", 255 m_console.Commands.AddCommand("Regions", false, "debug scene",
256 "debug scene <scripting> <collisions> <physics>", 256 "debug scene <scripting> <collisions> <physics>",
257 "Turn on scene debugging", Debug); 257 "Turn on scene debugging", Debug);
258 258
259 m_console.Commands.AddCommand("region", false, "change region", 259 m_console.Commands.AddCommand("General", false, "change region",
260 "change region <region name>", 260 "change region <region name>",
261 "Change current console region", ChangeSelectedRegion); 261 "Change current console region", ChangeSelectedRegion);
262 262
263 m_console.Commands.AddCommand("region", false, "save xml", 263 m_console.Commands.AddCommand("Archiving", false, "save xml",
264 "save xml", 264 "save xml",
265 "Save a region's data in XML format", SaveXml); 265 "Save a region's data in XML format", SaveXml);
266 266
267 m_console.Commands.AddCommand("region", false, "save xml2", 267 m_console.Commands.AddCommand("Archiving", false, "save xml2",
268 "save xml2", 268 "save xml2",
269 "Save a region's data in XML2 format", SaveXml2); 269 "Save a region's data in XML2 format", SaveXml2);
270 270
271 m_console.Commands.AddCommand("region", false, "load xml", 271 m_console.Commands.AddCommand("Archiving", false, "load xml",
272 "load xml [-newIDs [<x> <y> <z>]]", 272 "load xml [-newIDs [<x> <y> <z>]]",
273 "Load a region's data from XML format", LoadXml); 273 "Load a region's data from XML format", LoadXml);
274 274
275 m_console.Commands.AddCommand("region", false, "load xml2", 275 m_console.Commands.AddCommand("Archiving", false, "load xml2",
276 "load xml2", 276 "load xml2",
277 "Load a region's data from XML2 format", LoadXml2); 277 "Load a region's data from XML2 format", LoadXml2);
278 278
279 m_console.Commands.AddCommand("region", false, "save prims xml2", 279 m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
280 "save prims xml2 [<prim name> <file name>]", 280 "save prims xml2 [<prim name> <file name>]",
281 "Save named prim to XML2", SavePrimsXml2); 281 "Save named prim to XML2", SavePrimsXml2);
282 282
283 m_console.Commands.AddCommand("region", false, "load oar", 283 m_console.Commands.AddCommand("Archiving", false, "load oar",
284 "load oar [--merge] [--skip-assets] [<OAR path>]", 284 "load oar [--merge] [--skip-assets] [<OAR path>]",
285 "Load a region's data from an OAR archive.", 285 "Load a region's data from an OAR archive.",
286 "--merge will merge the OAR with the existing scene." + Environment.NewLine 286 "--merge will merge the OAR with the existing scene." + Environment.NewLine
@@ -289,7 +289,7 @@ namespace OpenSim
289 + " If this is not given then the command looks for an OAR named region.oar in the current directory.", 289 + " If this is not given then the command looks for an OAR named region.oar in the current directory.",
290 LoadOar); 290 LoadOar);
291 291
292 m_console.Commands.AddCommand("region", false, "save oar", 292 m_console.Commands.AddCommand("Archiving", false, "save oar",
293 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 293 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
294 "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]", 294 "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
295 "Save a region's data to an OAR archive.", 295 "Save a region's data to an OAR archive.",
@@ -306,54 +306,54 @@ 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("region", false, "edit scale", 309 m_console.Commands.AddCommand("Regions", 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
313 m_console.Commands.AddCommand("region", false, "kick user", 313 m_console.Commands.AddCommand("Users", false, "kick user",
314 "kick user <first> <last> [message]", 314 "kick user <first> <last> [message]",
315 "Kick a user off the simulator", KickUserCommand); 315 "Kick a user off the simulator", KickUserCommand);
316 316
317 m_console.Commands.AddCommand("region", false, "show users", 317 m_console.Commands.AddCommand("Users", false, "show users",
318 "show users [full]", 318 "show users [full]",
319 "Show user data for users currently on the region", 319 "Show user data for users currently on the region",
320 "Without the 'full' option, only users actually on the region are shown." 320 "Without the 'full' option, only users actually on the region are shown."
321 + " With the 'full' option child agents of users in neighbouring regions are also shown.", 321 + " With the 'full' option child agents of users in neighbouring regions are also shown.",
322 HandleShow); 322 HandleShow);
323 323
324 m_console.Commands.AddCommand("region", false, "show connections", 324 m_console.Commands.AddCommand("Comms", false, "show connections",
325 "show connections", 325 "show connections",
326 "Show connection data", HandleShow); 326 "Show connection data", HandleShow);
327 327
328 m_console.Commands.AddCommand("region", false, "show circuits", 328 m_console.Commands.AddCommand("Comms", false, "show circuits",
329 "show circuits", 329 "show circuits",
330 "Show agent circuit data", HandleShow); 330 "Show agent circuit data", HandleShow);
331 331
332 m_console.Commands.AddCommand("region", false, "show http-handlers", 332 m_console.Commands.AddCommand("Comms", false, "show http-handlers",
333 "show http-handlers", 333 "show http-handlers",
334 "Show all registered http handlers", HandleShow); 334 "Show all registered http handlers", HandleShow);
335 335
336 m_console.Commands.AddCommand("region", false, "show pending-objects", 336 m_console.Commands.AddCommand("Comms", false, "show pending-objects",
337 "show pending-objects", 337 "show pending-objects",
338 "Show # of objects on the pending queues of all scene viewers", HandleShow); 338 "Show # of objects on the pending queues of all scene viewers", HandleShow);
339 339
340 m_console.Commands.AddCommand("region", false, "show modules", 340 m_console.Commands.AddCommand("General", false, "show modules",
341 "show modules", 341 "show modules",
342 "Show module data", HandleShow); 342 "Show module data", HandleShow);
343 343
344 m_console.Commands.AddCommand("region", false, "show regions", 344 m_console.Commands.AddCommand("Regions", false, "show regions",
345 "show regions", 345 "show regions",
346 "Show region data", HandleShow); 346 "Show region data", HandleShow);
347 347
348 m_console.Commands.AddCommand("region", false, "show ratings", 348 m_console.Commands.AddCommand("Regions", false, "show ratings",
349 "show ratings", 349 "show ratings",
350 "Show rating data", HandleShow); 350 "Show rating data", HandleShow);
351 351
352 m_console.Commands.AddCommand("region", false, "backup", 352 m_console.Commands.AddCommand("Regions", 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
356 m_console.Commands.AddCommand("region", false, "create region", 356 m_console.Commands.AddCommand("Regions", false, "create region",
357 "create region [\"region name\"] <region_file.ini>", 357 "create region [\"region name\"] <region_file.ini>",
358 "Create a new region.", 358 "Create a new region.",
359 "The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given." 359 "The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
@@ -362,62 +362,57 @@ namespace OpenSim
362 + "If <region_file.ini> does not exist, it will be created.", 362 + "If <region_file.ini> does not exist, it will be created.",
363 HandleCreateRegion); 363 HandleCreateRegion);
364 364
365 m_console.Commands.AddCommand("region", false, "restart", 365 m_console.Commands.AddCommand("Regions", false, "restart",
366 "restart", 366 "restart",
367 "Restart all sims in this instance", RunCommand); 367 "Restart all sims in this instance", RunCommand);
368 368
369 m_console.Commands.AddCommand("region", false, "config set", 369 m_console.Commands.AddCommand("General", false, "config set",
370 "config set <section> <key> <value>", 370 "config set <section> <key> <value>",
371 "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig); 371 "Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
372 372
373 m_console.Commands.AddCommand("region", false, "config get", 373 m_console.Commands.AddCommand("General", false, "config get",
374 "config get [<section>] [<key>]", 374 "config get [<section>] [<key>]",
375 "Synonym for config show", 375 "Synonym for config show",
376 HandleConfig); 376 HandleConfig);
377 377
378 m_console.Commands.AddCommand("region", false, "config show", 378 m_console.Commands.AddCommand("General", false, "config show",
379 "config show [<section>] [<key>]", 379 "config show [<section>] [<key>]",
380 "Show config information", 380 "Show config information",
381 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine 381 "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
382 + "If a section is given but not a field, then all fields in that section are printed.", 382 + "If a section is given but not a field, then all fields in that section are printed.",
383 HandleConfig); 383 HandleConfig);
384 384
385 m_console.Commands.AddCommand("region", false, "config save", 385 m_console.Commands.AddCommand("General", false, "config save",
386 "config save <path>", 386 "config save <path>",
387 "Save current configuration to a file at the given path", HandleConfig); 387 "Save current configuration to a file at the given path", HandleConfig);
388 388
389 m_console.Commands.AddCommand("region", false, "command-script", 389 m_console.Commands.AddCommand("General", false, "command-script",
390 "command-script <script>", 390 "command-script <script>",
391 "Run a command script from file", RunCommand); 391 "Run a command script from file", RunCommand);
392 392
393 m_console.Commands.AddCommand("region", false, "remove-region", 393 m_console.Commands.AddCommand("Regions", false, "remove-region",
394 "remove-region <name>", 394 "remove-region <name>",
395 "Remove a region from this simulator", RunCommand); 395 "Remove a region from this simulator", RunCommand);
396 396
397 m_console.Commands.AddCommand("region", false, "delete-region", 397 m_console.Commands.AddCommand("Regions", false, "delete-region",
398 "delete-region <name>", 398 "delete-region <name>",
399 "Delete a region from disk", RunCommand); 399 "Delete a region from disk", RunCommand);
400 400
401 m_console.Commands.AddCommand("region", false, "modules list", 401 m_console.Commands.AddCommand("General", false, "modules list",
402 "modules list", 402 "modules list",
403 "List modules", HandleModules); 403 "List modules", HandleModules);
404 404
405 m_console.Commands.AddCommand("region", false, "modules load", 405 m_console.Commands.AddCommand("General", false, "modules load",
406 "modules load <name>", 406 "modules load <name>",
407 "Load a module", HandleModules); 407 "Load a module", HandleModules);
408 408
409 m_console.Commands.AddCommand("region", false, "modules unload", 409 m_console.Commands.AddCommand("General", false, "modules unload",
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("region", false, "Add-InventoryHost", 413 m_console.Commands.AddCommand("Regions", false, "kill uuid",
414 "Add-InventoryHost <host>",
415 String.Empty, RunCommand);
416
417 m_console.Commands.AddCommand("region", false, "kill uuid",
418 "kill uuid <UUID>", 414 "kill uuid <UUID>",
419 "Kill an object by UUID", KillUUID); 415 "Kill an object by UUID", KillUUID);
420
421 } 416 }
422 417
423 public override void ShutdownSpecific() 418 public override void ShutdownSpecific()
@@ -508,7 +503,11 @@ namespace OpenSim
508 string currentCommand; 503 string currentCommand;
509 while ((currentCommand = readFile.ReadLine()) != null) 504 while ((currentCommand = readFile.ReadLine()) != null)
510 { 505 {
511 if (currentCommand != String.Empty) 506 currentCommand = currentCommand.Trim();
507 if (!(currentCommand == ""
508 || currentCommand.StartsWith(";")
509 || currentCommand.StartsWith("//")
510 || currentCommand.StartsWith("#")))
512 { 511 {
513 m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'"); 512 m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
514 m_console.RunCommand(currentCommand); 513 m_console.RunCommand(currentCommand);
@@ -829,14 +828,6 @@ namespace OpenSim
829 case "restart": 828 case "restart":
830 m_sceneManager.RestartCurrentScene(); 829 m_sceneManager.RestartCurrentScene();
831 break; 830 break;
832
833 case "Add-InventoryHost":
834 if (cmdparams.Length > 0)
835 {
836 MainConsole.Instance.Output("Not implemented.");
837 }
838 break;
839
840 } 831 }
841 } 832 }
842 833
@@ -928,7 +919,7 @@ namespace OpenSim
928 break; 919 break;
929 920
930 case "scene": 921 case "scene":
931 if (args.Length == 5) 922 if (args.Length == 4)
932 { 923 {
933 if (m_sceneManager.CurrentScene == null) 924 if (m_sceneManager.CurrentScene == null)
934 { 925 {
@@ -936,39 +927,21 @@ namespace OpenSim
936 } 927 }
937 else 928 else
938 { 929 {
939 bool scriptingOn = !Convert.ToBoolean(args[2]); 930 string key = args[2];
940 bool collisionsOn = !Convert.ToBoolean(args[3]); 931 string value = args[3];
941 bool physicsOn = !Convert.ToBoolean(args[4]); 932 m_sceneManager.CurrentScene.SetSceneCoreDebug(
942 m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn); 933 new Dictionary<string, string>() { { key, value } });
943 934
944 MainConsole.Instance.Output( 935 MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
945 String.Format(
946 "Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
947 !scriptingOn, !collisionsOn, !physicsOn));
948 } 936 }
949 } 937 }
950 else 938 else
951 { 939 {
952 MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)"); 940 MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
953 } 941 }
954 942
955 break; 943 break;
956 944
957 case "teleport":
958 foreach(Scene s in m_sceneManager.Scenes)
959 {
960 if (s.DEBUG)
961 {
962 s.DEBUG = false;
963 MainConsole.Instance.Output("Teleport debugging is disabled!");
964 }
965 else{
966 s.DEBUG = true;
967 MainConsole.Instance.Output("Teleport debugging is enabled!");
968 }
969 }
970 break;
971
972 default: 945 default:
973 MainConsole.Instance.Output("Unknown debug command"); 946 MainConsole.Instance.Output("Unknown debug command");
974 break; 947 break;
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index f482d8f..5de3f25 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Linq;
31using System.Net; 32using System.Net;
32using System.Reflection; 33using System.Reflection;
33using System.Text; 34using System.Text;
@@ -67,6 +68,9 @@ namespace OpenSim
67 private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache"; 68 private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache";
68 private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient"; 69 private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient";
69 70
71 // OpenSim.ini Section name for ESTATES Settings
72 public const string ESTATE_SECTION_NAME = "Estates";
73
70 protected string proxyUrl; 74 protected string proxyUrl;
71 protected int proxyOffset = 0; 75 protected int proxyOffset = 0;
72 76
@@ -242,15 +246,18 @@ namespace OpenSim
242 246
243 foreach (string topic in topics) 247 foreach (string topic in topics)
244 { 248 {
245 m_console.Commands.AddCommand("plugin", false, "help " + topic, 249 string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
246 "help " + topic, 250
251 // This is a hack to allow the user to enter the help command in upper or lowercase. This will go
252 // away at some point.
253 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
254 "help " + capitalizedTopic,
255 "Get help on plugin command '" + topic + "'",
256 HandleCommanderHelp);
257 m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
258 "help " + capitalizedTopic,
247 "Get help on plugin command '" + topic + "'", 259 "Get help on plugin command '" + topic + "'",
248 HandleCommanderHelp); 260 HandleCommanderHelp);
249
250 m_console.Commands.AddCommand("plugin", false, topic,
251 topic,
252 "Execute subcommand for plugin '" + topic + "'",
253 null);
254 261
255 ICommander commander = null; 262 ICommander commander = null;
256 263
@@ -267,7 +274,7 @@ namespace OpenSim
267 274
268 foreach (string command in commander.Commands.Keys) 275 foreach (string command in commander.Commands.Keys)
269 { 276 {
270 m_console.Commands.AddCommand(topic, false, 277 m_console.Commands.AddCommand(capitalizedTopic, false,
271 topic + " " + command, 278 topic + " " + command,
272 topic + " " + commander.Commands[command].ShortHelp(), 279 topic + " " + commander.Commands[command].ShortHelp(),
273 String.Empty, HandleCommanderCommand); 280 String.Empty, HandleCommanderCommand);
@@ -286,7 +293,7 @@ namespace OpenSim
286 // Only safe for the interactive console, since it won't 293 // Only safe for the interactive console, since it won't
287 // let us come here unless both scene and commander exist 294 // let us come here unless both scene and commander exist
288 // 295 //
289 ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]); 296 ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
290 if (moduleCommander != null) 297 if (moduleCommander != null)
291 m_console.Output(moduleCommander.Help); 298 m_console.Output(moduleCommander.Help);
292 } 299 }
@@ -424,7 +431,7 @@ namespace OpenSim
424 431
425 mscene = scene; 432 mscene = scene;
426 433
427 scene.StartTimer(); 434 scene.Start();
428 435
429 scene.StartScripts(); 436 scene.StartScripts();
430 437
@@ -443,12 +450,42 @@ namespace OpenSim
443 { 450 {
444 RegionInfo regionInfo = scene.RegionInfo; 451 RegionInfo regionInfo = scene.RegionInfo;
445 452
453 string estateOwnerFirstName = null;
454 string estateOwnerLastName = null;
455 string estateOwnerEMail = null;
456 string estateOwnerPassword = null;
457 string rawEstateOwnerUuid = null;
458
459 if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
460 {
461 string defaultEstateOwnerName
462 = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
463 string[] ownerNames = defaultEstateOwnerName.Split(' ');
464
465 if (ownerNames.Length >= 2)
466 {
467 estateOwnerFirstName = ownerNames[0];
468 estateOwnerLastName = ownerNames[1];
469 }
470
471 // Info to be used only on Standalone Mode
472 rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
473 estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
474 estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
475 }
476
446 MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName); 477 MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
447 List<char> excluded = new List<char>(new char[1]{' '}); 478 List<char> excluded = new List<char>(new char[1]{' '});
448 string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
449 string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
450 479
451 UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last); 480
481 if (estateOwnerFirstName == null || estateOwnerLastName == null)
482 {
483 estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
484 estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
485 }
486
487 UserAccount account
488 = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName);
452 489
453 if (account == null) 490 if (account == null)
454 { 491 {
@@ -467,23 +504,35 @@ namespace OpenSim
467 504
468 if (scene.UserAccountService is UserAccountService) 505 if (scene.UserAccountService is UserAccountService)
469 { 506 {
470 string password = MainConsole.Instance.PasswdPrompt("Password"); 507 if (estateOwnerPassword == null)
471 string email = MainConsole.Instance.CmdPrompt("Email", ""); 508 estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password");
472 509
473 string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString()); 510 if (estateOwnerEMail == null)
511 estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email");
512
513 if (rawEstateOwnerUuid == null)
514 rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
474 515
475 UUID principalId = UUID.Zero; 516 UUID estateOwnerUuid = UUID.Zero;
476 if (!UUID.TryParse(rawPrincipalId, out principalId)) 517 if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid))
477 { 518 {
478 m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId); 519 m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid);
479 return; 520 return;
480 } 521 }
481 522
523 // If we've been given a zero uuid then this signals that we should use a random user id
524 if (estateOwnerUuid == UUID.Zero)
525 estateOwnerUuid = UUID.Random();
526
482 account 527 account
483 = ((UserAccountService)scene.UserAccountService).CreateUser( 528 = ((UserAccountService)scene.UserAccountService).CreateUser(
484 regionInfo.ScopeID, principalId, first, last, password, email); 529 regionInfo.ScopeID,
530 estateOwnerUuid,
531 estateOwnerFirstName,
532 estateOwnerLastName,
533 estateOwnerPassword,
534 estateOwnerEMail);
485 } 535 }
486// }
487 } 536 }
488 537
489 if (account == null) 538 if (account == null)
@@ -883,15 +932,21 @@ namespace OpenSim
883 /// This method doesn't allow an estate to be created with the same name as existing estates. 932 /// This method doesn't allow an estate to be created with the same name as existing estates.
884 /// </remarks> 933 /// </remarks>
885 /// <param name="regInfo"></param> 934 /// <param name="regInfo"></param>
886 /// <param name="existingName">A list of estate names that already exist.</param> 935 /// <param name="estatesByName">A list of estate names that already exist.</param>
936 /// <param name="estateName">Estate name to create if already known</param>
887 /// <returns>true if the estate was created, false otherwise</returns> 937 /// <returns>true if the estate was created, false otherwise</returns>
888 public bool CreateEstate(RegionInfo regInfo, List<string> existingNames) 938 public bool CreateEstate(RegionInfo regInfo, Dictionary<string, EstateSettings> estatesByName, string estateName)
889 { 939 {
890 // Create a new estate 940 // Create a new estate
891 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true); 941 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
892 string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
893 942
894 if (existingNames.Contains(newName)) 943 string newName;
944 if (estateName != null && estateName != "")
945 newName = estateName;
946 else
947 newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
948
949 if (estatesByName.ContainsKey(newName))
895 { 950 {
896 MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName); 951 MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
897 return false; 952 return false;
@@ -918,66 +973,102 @@ namespace OpenSim
918 if (EstateDataService != null) 973 if (EstateDataService != null)
919 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false); 974 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
920 975
921 if (regInfo.EstateSettings.EstateID == 0) // No record at all 976 if (regInfo.EstateSettings.EstateID != 0)
977 return;
978
979 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
980
981 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
982 Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
983
984 foreach (EstateSettings estate in estates)
985 estatesByName[estate.EstateName] = estate;
986
987 string defaultEstateName = null;
988
989 if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
922 { 990 {
923 m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); 991 defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
924 992
925 List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll(); 993 if (defaultEstateName != null)
926 List<string> estateNames = new List<string>();
927 foreach (EstateSettings estate in estates)
928 estateNames.Add(estate.EstateName);
929
930 while (true)
931 { 994 {
932 if (estates.Count == 0) 995 EstateSettings defaultEstate;
933 { 996 bool defaultEstateJoined = false;
934 m_log.Info("[ESTATE] No existing estates found. You must create a new one."); 997
935 998 if (estatesByName.ContainsKey(defaultEstateName))
936 if (CreateEstate(regInfo, estateNames)) 999 {
937 break; 1000 defaultEstate = estatesByName[defaultEstateName];
1001
1002 if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID))
1003 defaultEstateJoined = true;
1004 }
1005 else
1006 {
1007 if (CreateEstate(regInfo, estatesByName, defaultEstateName))
1008 defaultEstateJoined = true;
1009 }
1010
1011 if (defaultEstateJoined)
1012 return;
1013 else
1014 m_log.ErrorFormat(
1015 "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
1016 }
1017 }
1018
1019 // If we have no default estate or creation of the default estate failed then ask the user.
1020 while (true)
1021 {
1022 if (estates.Count == 0)
1023 {
1024 m_log.Info("[ESTATE]: No existing estates found. You must create a new one.");
1025
1026 if (CreateEstate(regInfo, estatesByName, null))
1027 break;
1028 else
1029 continue;
1030 }
1031 else
1032 {
1033 string response
1034 = MainConsole.Instance.CmdPrompt(
1035 string.Format(
1036 "Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
1037 "yes",
1038 new List<string>() { "yes", "no" });
1039
1040 if (response == "no")
1041 {
1042 if (CreateEstate(regInfo, estatesByName, null))
1043 break;
938 else 1044 else
939 continue; 1045 continue;
940 } 1046 }
941 else 1047 else
942 { 1048 {
943 string response 1049 string[] estateNames = estatesByName.Keys.ToArray();
1050 response
944 = MainConsole.Instance.CmdPrompt( 1051 = MainConsole.Instance.CmdPrompt(
945 string.Format( 1052 string.Format(
946 "Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName), 1053 "Name of estate to join. Existing estate names are ({0})",
947 "yes", 1054 string.Join(", ", estateNames)),
948 new List<string>() { "yes", "no" }); 1055 estateNames[0]);
949 1056
950 if (response == "no") 1057 List<int> estateIDs = EstateDataService.GetEstates(response);
1058 if (estateIDs.Count < 1)
951 { 1059 {
952 if (CreateEstate(regInfo, estateNames)) 1060 MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
953 break; 1061 continue;
954 else
955 continue;
956 }
957 else
958 {
959 response
960 = MainConsole.Instance.CmdPrompt(
961 string.Format(
962 "Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
963 estateNames[0]);
964
965 List<int> estateIDs = EstateDataService.GetEstates(response);
966 if (estateIDs.Count < 1)
967 {
968 MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
969 continue;
970 }
971
972 int estateID = estateIDs[0];
973
974 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
975
976 if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
977 break;
978
979 MainConsole.Instance.Output("Joining the estate failed. Please try again.");
980 } 1062 }
1063
1064 int estateID = estateIDs[0];
1065
1066 regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
1067
1068 if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
1069 break;
1070
1071 MainConsole.Instance.Output("Joining the estate failed. Please try again.");
981 } 1072 }
982 } 1073 }
983 } 1074 }
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index be699db..ed3430a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -262,7 +262,7 @@ namespace OpenSim.Region.ClientStack.Linden
262 { 262 {
263 try 263 try
264 { 264 {
265 m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName); 265// m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
266 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param); 266 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
267 267
268 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); 268 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
@@ -761,7 +761,7 @@ namespace OpenSim.Region.ClientStack.Linden
761 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID); 761 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
762 if (part != null) 762 if (part != null)
763 { 763 {
764 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID); 764// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
765 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID)) 765 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
766 { 766 {
767 return LLSDHelpers.SerialiseLLSDReply(response); 767 return LLSDHelpers.SerialiseLLSDReply(response);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 8ba6f61..7c07c56 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
106 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 106 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
107 107
108 MainConsole.Instance.Commands.AddCommand( 108 MainConsole.Instance.Commands.AddCommand(
109 "event queue", 109 "Comms",
110 false, 110 false,
111 "debug eq", 111 "debug eq",
112 "debug eq [0|1]", 112 "debug eq [0|1]",
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d98ff68..68aae14 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -317,7 +317,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
317 protected readonly UUID m_agentId; 317 protected readonly UUID m_agentId;
318 private readonly uint m_circuitCode; 318 private readonly uint m_circuitCode;
319 private readonly byte[] m_channelVersion = Utils.EmptyBytes; 319 private readonly byte[] m_channelVersion = Utils.EmptyBytes;
320 private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
321 private readonly IGroupsModule m_GroupsModule; 320 private readonly IGroupsModule m_GroupsModule;
322 321
323 private int m_cachedTextureSerial; 322 private int m_cachedTextureSerial;
@@ -452,10 +451,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
452 RegisterInterface<IClientChat>(this); 451 RegisterInterface<IClientChat>(this);
453 RegisterInterface<IClientIPEndpoint>(this); 452 RegisterInterface<IClientIPEndpoint>(this);
454 453
455 InitDefaultAnimations();
456
457 m_scene = scene; 454 m_scene = scene;
458
459 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 455 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
460 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 456 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
461 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 457 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
@@ -11206,36 +11202,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11206 scriptQuestion.Data.Questions = question; 11202 scriptQuestion.Data.Questions = question;
11207 scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName); 11203 scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
11208 scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName); 11204 scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
11209 11205
11210 OutPacket(scriptQuestion, ThrottleOutPacketType.Task); 11206 OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
11211 } 11207 }
11212 11208
11213 private void InitDefaultAnimations()
11214 {
11215 using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
11216 {
11217 XmlDocument doc = new XmlDocument();
11218 doc.Load(reader);
11219 if (doc.DocumentElement != null)
11220 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
11221 {
11222 if (nod.Attributes["name"] != null)
11223 {
11224 string name = nod.Attributes["name"].Value.ToLower();
11225 string id = nod.InnerText;
11226 m_defaultAnimations.Add(name, (UUID)id);
11227 }
11228 }
11229 }
11230 }
11231
11232 public UUID GetDefaultAnimation(string name)
11233 {
11234 if (m_defaultAnimations.ContainsKey(name))
11235 return m_defaultAnimations[name];
11236 return UUID.Zero;
11237 }
11238
11239 /// <summary> 11209 /// <summary>
11240 /// Handler called when we receive a logout packet. 11210 /// Handler called when we receive a logout packet.
11241 /// </summary> 11211 /// </summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
index fb94355..d76927b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
50 m_regStatus = RegionStatus.Up; 50 m_regStatus = RegionStatus.Up;
51 } 51 }
52 52
53 public override void Update() {} 53 public override void Update(int frames) {}
54 public override void LoadWorldMap() {} 54 public override void LoadWorldMap() {}
55 55
56 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 56 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 22c301b..389fb7b 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
203 m_CacheDirectoryTierLen = 4; 203 m_CacheDirectoryTierLen = 4;
204 } 204 }
205 205
206 MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); 206 MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
207 MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand); 207 MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
208 MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); 208 MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
209 MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); 209 MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
210 } 210 }
211 } 211 }
212 } 212 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index ffe7718..325067c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
51 m_scene.RegisterModuleInterface<IDialogModule>(this); 51 m_scene.RegisterModuleInterface<IDialogModule>(this);
52 52
53 m_scene.AddCommand( 53 m_scene.AddCommand(
54 this, "alert", "alert <message>", 54 "Users", this, "alert", "alert <message>",
55 "Send an alert to everyone", 55 "Send an alert to everyone",
56 HandleAlertConsoleCommand); 56 HandleAlertConsoleCommand);
57 57
58 m_scene.AddCommand( 58 m_scene.AddCommand(
59 this, "alert-user", "alert-user <first> <last> <message>", 59 "Users", this, "alert-user", "alert-user <first> <last> <message>",
60 "Send an alert to a user", 60 "Send an alert to a user",
61 HandleAlertConsoleCommand); 61 HandleAlertConsoleCommand);
62 } 62 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index c266fe5..be767c4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
212 scene.EventManager.OnClientLogin += OnClientLogin; 212 scene.EventManager.OnClientLogin += OnClientLogin;
213 } 213 }
214 214
215 public void RegionLoaded(Scene scene) 215 public virtual void RegionLoaded(Scene scene)
216 { 216 {
217 } 217 }
218 218
@@ -550,7 +550,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
550 UUID principalID = new UUID(im.fromAgentID); 550 UUID principalID = new UUID(im.fromAgentID);
551 UUID friendID = new UUID(im.toAgentID); 551 UUID friendID = new UUID(im.toAgentID);
552 552
553 m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID); 553 m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
554
555 // Check that the friendship doesn't exist yet
556 FriendInfo[] finfos = GetFriends(principalID);
557 if (finfos != null)
558 {
559 FriendInfo f = GetFriend(finfos, friendID);
560 if (f != null)
561 {
562 client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
563 return;
564 }
565 }
554 566
555 // This user wants to be friends with the other user. 567 // This user wants to be friends with the other user.
556 // Let's add the relation backwards, in case the other is not online 568 // Let's add the relation backwards, in case the other is not online
@@ -561,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
561 } 573 }
562 } 574 }
563 575
564 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) 576 protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
565 { 577 {
566 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 578 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
567 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 579 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
@@ -570,7 +582,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
570 582
571 // Try the local sim 583 // Try the local sim
572 if (LocalFriendshipOffered(friendID, im)) 584 if (LocalFriendshipOffered(friendID, im))
573 return; 585 return true;
574 586
575 // The prospective friend is not here [as root]. Let's forward. 587 // The prospective friend is not here [as root]. Let's forward.
576 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 588 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -581,9 +593,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
581 { 593 {
582 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 594 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
583 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); 595 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
596 return true;
584 } 597 }
585 } 598 }
586 // If the prospective friend is not online, he'll get the message upon login. 599 // If the prospective friend is not online, he'll get the message upon login.
600 return false;
587 } 601 }
588 602
589 protected virtual string GetFriendshipRequesterName(UUID agentID) 603 protected virtual string GetFriendshipRequesterName(UUID agentID)
@@ -592,7 +606,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
592 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; 606 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
593 } 607 }
594 608
595 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 609 protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
596 { 610 {
597 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); 611 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
598 612
@@ -603,7 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
603 { 617 {
604 StoreFriendships(client.AgentId, friendID); 618 StoreFriendships(client.AgentId, friendID);
605 619
606 // Update the local cache 620 // Update the local cache.
607 RecacheFriends(client); 621 RecacheFriends(client);
608 622
609 // 623 //
@@ -756,7 +770,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
756 770
757 #region Local 771 #region Local
758 772
759 public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) 773 public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
760 { 774 {
761 IClientAPI friendClient = LocateClientObject(toID); 775 IClientAPI friendClient = LocateClientObject(toID);
762 if (friendClient != null) 776 if (friendClient != null)
@@ -912,7 +926,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
912 return FriendsService.GetFriends(client.AgentId); 926 return FriendsService.GetFriends(client.AgentId);
913 } 927 }
914 928
915 private void RecacheFriends(IClientAPI client) 929 protected void RecacheFriends(IClientAPI client)
916 { 930 {
917 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event 931 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
918 // is on the critical path for transferring an avatar from one region to another. 932 // is on the critical path for transferring an avatar from one region to another.
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 9c53fc4..e50a84a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
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 IUserManagement m_uMan; 53 IUserManagement m_uMan;
54 IUserManagement UserManagementModule 54 public IUserManagement UserManagementModule
55 { 55 {
56 get 56 get
57 { 57 {
@@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
61 } 61 }
62 } 62 }
63 63
64 protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
65 protected HGStatusNotifier m_StatusNotifier;
66
64 #region ISharedRegionModule 67 #region ISharedRegionModule
65 public override string Name 68 public override string Name
66 { 69 {
@@ -76,6 +79,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
76 scene.RegisterModuleInterface<IFriendsSimConnector>(this); 79 scene.RegisterModuleInterface<IFriendsSimConnector>(this);
77 } 80 }
78 81
82 public override void RegionLoaded(Scene scene)
83 {
84 if (!m_Enabled)
85 return;
86 if (m_StatusNotifier == null)
87 m_StatusNotifier = new HGStatusNotifier(this);
88 }
89
79 #endregion 90 #endregion
80 91
81 #region IFriendsSimConnector 92 #region IFriendsSimConnector
@@ -94,6 +105,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
94 105
95 #endregion 106 #endregion
96 107
108 protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
109 {
110 // Update the local cache. Yes, we need to do it right here
111 // because the HGFriendsService placed something on the DB
112 // from under the sim
113 base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders);
114 }
115
97 protected override bool CacheFriends(IClientAPI client) 116 protected override bool CacheFriends(IClientAPI client)
98 { 117 {
99// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); 118// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
@@ -183,91 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
183// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); 202// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
184 } 203 }
185 204
186 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
187 //{
188 // // Let's single out the UUIs
189 // List<string> localFriends = new List<string>();
190 // List<string> foreignFriends = new List<string>();
191 // string tmp = string.Empty;
192
193 // foreach (string s in friendList)
194 // {
195 // UUID id;
196 // if (UUID.TryParse(s, out id))
197 // localFriends.Add(s);
198 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
199 // {
200 // foreignFriends.Add(s);
201 // // add it here too, who knows maybe the foreign friends happens to be on this grid
202 // localFriends.Add(id.ToString());
203 // }
204 // }
205
206 // // OK, see who's present on this grid
207 // List<string> toBeRemoved = new List<string>();
208 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
209 // foreach (PresenceInfo pi in presence)
210 // {
211 // UUID presenceID;
212 // if (UUID.TryParse(pi.UserID, out presenceID))
213 // {
214 // online.Add(presenceID);
215 // foreach (string s in foreignFriends)
216 // if (s.StartsWith(pi.UserID))
217 // toBeRemoved.Add(s);
218 // }
219 // }
220
221 // foreach (string s in toBeRemoved)
222 // foreignFriends.Remove(s);
223
224 // // OK, let's send this up the stack, and leave a closure here
225 // // collecting online friends in other grids
226 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
227
228 //}
229
230 //private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
231 //{
232 // // let's divide the friends on a per-domain basis
233 // Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
234 // foreach (string friend in foreignFriends)
235 // {
236 // UUID friendID;
237 // if (!UUID.TryParse(friend, out friendID))
238 // {
239 // // it's a foreign friend
240 // string url = string.Empty, tmp = string.Empty;
241 // if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
242 // {
243 // if (!friendsPerDomain.ContainsKey(url))
244 // friendsPerDomain[url] = new List<string>();
245 // friendsPerDomain[url].Add(friend);
246 // }
247 // }
248 // }
249
250 // // Now, call those worlds
251
252 // foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
253 // {
254 // List<string> ids = new List<string>();
255 // foreach (string f in kvp.Value)
256 // ids.Add(f);
257 // UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
258 // List<UUID> online = uConn.GetOnlineFriends(userID, ids);
259 // // Finally send the notifications to the user
260 // // this whole process may take a while, so let's check at every
261 // // iteration that the user is still here
262 // IClientAPI client = LocateClientObject(userID);
263 // if (client != null)
264 // client.SendAgentOnline(online.ToArray());
265 // else
266 // break;
267 // }
268
269 //}
270
271 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) 205 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
272 { 206 {
273// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); 207// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
@@ -305,25 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
305 if (friendsPerDomain.ContainsKey("local")) 239 if (friendsPerDomain.ContainsKey("local"))
306 base.StatusNotify(friendsPerDomain["local"], userID, online); 240 base.StatusNotify(friendsPerDomain["local"], userID, online);
307 241
308 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain) 242 m_StatusNotifier.Notify(userID, friendsPerDomain, online);
309 {
310 if (kvp.Key != "local")
311 {
312 // For the others, call the user agent service
313 List<string> ids = new List<string>();
314 foreach (FriendInfo f in kvp.Value)
315 ids.Add(f.Friend);
316 UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
317 List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
318
319 if (online && friendsOnline.Count > 0)
320 {
321 IClientAPI client = LocateClientObject(userID);
322 if (client != null)
323 client.SendAgentOnline(friendsOnline.ToArray());
324 }
325 }
326 }
327 243
328// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID); 244// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
329 } 245 }
@@ -335,26 +251,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
335 return true; 251 return true;
336 252
337 // fid is not a UUID... 253 // fid is not a UUID...
338 string url = string.Empty, tmp = string.Empty; 254 string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
339 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) 255 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
340 { 256 {
341 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 257 if (!agentID.Equals(UUID.Zero))
342 userMan.AddUser(agentID, first, last, url); 258 {
259 m_uMan.AddUser(agentID, f, l, url);
343 260
344 return true; 261 string name = m_uMan.GetUserName(agentID);
262 string[] parts = name.Trim().Split(new char[] { ' ' });
263 if (parts.Length == 2)
264 {
265 first = parts[0];
266 last = parts[1];
267 }
268 else
269 {
270 first = f;
271 last = l;
272 }
273 return true;
274 }
345 } 275 }
346 return false; 276 return false;
347 } 277 }
348 278
349 protected override string GetFriendshipRequesterName(UUID agentID) 279 protected override string GetFriendshipRequesterName(UUID agentID)
350 { 280 {
351 // For the time being we assume that HG friendship requests can only happen 281 return m_uMan.GetUserName(agentID);
352 // when avies are on the same region.
353 IClientAPI client = LocateClientObject(agentID);
354 if (client != null)
355 return client.FirstName + " " + client.LastName;
356 else
357 return base.GetFriendshipRequesterName(agentID);
358 } 282 }
359 283
360 protected override string FriendshipMessage(string friendID) 284 protected override string FriendshipMessage(string friendID)
@@ -392,10 +316,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
392 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); 316 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
393 if (agentClientCircuit != null) 317 if (agentClientCircuit != null)
394 { 318 {
395 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 319 //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
396 320
397 finfos = FriendsService.GetFriends(agentUUI); 321 finfos = FriendsService.GetFriends(client.AgentId.ToString());
398 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); 322 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
399 } 323 }
400 324
401// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); 325// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
@@ -454,16 +378,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
454 friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); 378 friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
455 } 379 }
456 380
457 // Are they both local users? 381 // Is the requester a local user?
458 if (agentIsLocal && friendIsLocal) 382 if (agentIsLocal)
459 { 383 {
460 // local grid users 384 // local grid users
461 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); 385 m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
386
462 base.StoreBackwards(friendID, agentID); 387 base.StoreBackwards(friendID, agentID);
463 return; 388 return;
464 } 389 }
465 390
466 // no provision for this temporary friendship state 391 // no provision for this temporary friendship state when user is not local
467 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); 392 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
468 } 393 }
469 394
@@ -501,12 +426,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
501 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); 426 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
502 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 427 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
503 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 428 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
429 RecacheFriends(agentClient);
504 } 430 }
505 if (friendClient != null) 431 if (friendClient != null)
506 { 432 {
507 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); 433 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
508 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); 434 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
509 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 435 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
436 RecacheFriends(friendClient);
510 } 437 }
511 438
512 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", 439 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@@ -515,14 +442,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
515 // Generate a random 8-character hex number that will sign this friendship 442 // Generate a random 8-character hex number that will sign this friendship
516 string secret = UUID.Random().ToString().Substring(0, 8); 443 string secret = UUID.Random().ToString().Substring(0, 8);
517 444
445 string theFriendUUID = friendUUI + ";" + secret;
446 string agentUUID = agentUUI + ";" + secret;
447
518 if (agentIsLocal) // agent is local, 'friend' is foreigner 448 if (agentIsLocal) // agent is local, 'friend' is foreigner
519 { 449 {
520 // This may happen when the agent returned home, in which case the friend is not there 450 // This may happen when the agent returned home, in which case the friend is not there
521 // We need to look for its information in the friends list itself 451 // We need to look for its information in the friends list itself
452 FriendInfo[] finfos = null;
522 bool confirming = false; 453 bool confirming = false;
523 if (friendUUI == string.Empty) 454 if (friendUUI == string.Empty)
524 { 455 {
525 FriendInfo[] finfos = GetFriends(agentID); 456 finfos = GetFriends(agentID);
526 foreach (FriendInfo finfo in finfos) 457 foreach (FriendInfo finfo in finfos)
527 { 458 {
528 if (finfo.TheirFlags == -1) 459 if (finfo.TheirFlags == -1)
@@ -530,29 +461,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
530 if (finfo.Friend.StartsWith(friendID.ToString())) 461 if (finfo.Friend.StartsWith(friendID.ToString()))
531 { 462 {
532 friendUUI = finfo.Friend; 463 friendUUI = finfo.Friend;
464 theFriendUUID = friendUUI;
465 UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
466 // If it's confirming the friendship, we already have the full UUI with the secret
467 if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
468 {
469 agentUUID = agentUUI + ";" + secret;
470 m_uMan.AddUser(utmp, first, last, url);
471 }
533 confirming = true; 472 confirming = true;
473 break;
534 } 474 }
535 } 475 }
536 } 476 }
537 } 477 if (!confirming)
478 {
479 friendUUI = m_uMan.GetUserUUI(friendID);
480 theFriendUUID = friendUUI + ";" + secret;
481 }
482
483 friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
484
485 // m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
486 // agentUUI, friendUUI, agentFriendService, friendFriendService);
538 487
539 // If it's confirming the friendship, we already have the full friendUUI with the secret 488 }
540 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; 489
490 // Delete any previous friendship relations
491 DeletePreviousRelations(agentID, friendID);
541 492
542 // store in the local friends service a reference to the foreign friend 493 // store in the local friends service a reference to the foreign friend
543 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); 494 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
544 // and also the converse 495 // and also the converse
545 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); 496 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
546 497
547 if (!confirming && friendClientCircuit != null) 498 //if (!confirming)
548 { 499 //{
549 // store in the foreign friends service a reference to the local agent 500 // store in the foreign friends service a reference to the local agent
550 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 501 HGFriendsServicesConnector friendsConn = null;
551 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); 502 if (friendClientCircuit != null) // the friend is here, validate session
552 } 503 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
504 else // the friend is not here, he initiated the request in his home world
505 friendsConn = new HGFriendsServicesConnector(friendFriendService);
506
507 friendsConn.NewFriendship(friendID, agentUUID);
508 //}
553 } 509 }
554 else if (friendIsLocal) // 'friend' is local, agent is foreigner 510 else if (friendIsLocal) // 'friend' is local, agent is foreigner
555 { 511 {
512 // Delete any previous friendship relations
513 DeletePreviousRelations(agentID, friendID);
514
556 // store in the local friends service a reference to the foreign agent 515 // store in the local friends service a reference to the foreign agent
557 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); 516 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
558 // and also the converse 517 // and also the converse
@@ -582,6 +541,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
582 // my brain hurts now 541 // my brain hurts now
583 } 542 }
584 543
544 private void DeletePreviousRelations(UUID a1, UUID a2)
545 {
546 // Delete any previous friendship relations
547 FriendInfo[] finfos = null;
548 FriendInfo f = null;
549 finfos = GetFriends(a1);
550 if (finfos != null)
551 {
552 f = GetFriend(finfos, a2);
553 if (f != null)
554 {
555 FriendsService.Delete(a1, f.Friend);
556 // and also the converse
557 FriendsService.Delete(f.Friend, a1.ToString());
558 }
559 }
560
561 finfos = GetFriends(a2);
562 if (finfos != null)
563 {
564 f = GetFriend(finfos, a1);
565 if (f != null)
566 {
567 FriendsService.Delete(a2, f.Friend);
568 // and also the converse
569 FriendsService.Delete(f.Friend, a2.ToString());
570 }
571 }
572 }
573
585 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) 574 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
586 { 575 {
587 Boolean agentIsLocal = true; 576 Boolean agentIsLocal = true;
@@ -684,5 +673,80 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
684 friendConn.DeleteFriendship(foreignUser, localUser, secret); 673 friendConn.DeleteFriendship(foreignUser, localUser, secret);
685 } 674 }
686 } 675 }
676
677 protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
678 {
679 if (base.ForwardFriendshipOffer(agentID, friendID, im))
680 return true;
681
682 // OK, that didn't work, so let's try to find this user somewhere
683 if (!m_uMan.IsLocalGridUser(friendID))
684 {
685 string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
686 if (friendsURL != string.Empty)
687 {
688 m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
689 GridRegion region = new GridRegion();
690 region.ServerURI = friendsURL;
691
692 string name = im.fromAgentName;
693 if (m_uMan.IsLocalGridUser(agentID))
694 {
695 IClientAPI agentClient = LocateClientObject(agentID);
696 AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
697 string agentHomeService = string.Empty;
698 try
699 {
700 agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
701 string lastname = "@" + new Uri(agentHomeService).Authority;
702 string firstname = im.fromAgentName.Replace(" ", ".");
703 name = firstname + lastname;
704 }
705 catch (KeyNotFoundException)
706 {
707 m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
708 return false;
709 }
710 catch (NullReferenceException)
711 {
712 m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
713 return false;
714 }
715 catch (UriFormatException)
716 {
717 m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
718 return false;
719 }
720 }
721
722 m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
723
724 return true;
725 }
726 }
727
728 return false;
729 }
730
731 public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
732 {
733 if (base.LocalFriendshipOffered(toID, im))
734 {
735 if (im.fromAgentName.Contains("@"))
736 {
737 string[] parts = im.fromAgentName.Split(new char[] { '@' });
738 if (parts.Length == 2)
739 {
740 string[] fl = parts[0].Trim().Split(new char[] { '.' });
741 if (fl.Length == 2)
742 m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], fl[1], "http://" + parts[1]);
743 else
744 m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], "", "http://" + parts[1]);
745 }
746 }
747 return true;
748 }
749 return false;
750 }
687 } 751 }
688} \ No newline at end of file 752} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs
new file mode 100644
index 0000000..1fa4dd6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGStatusNotifier.cs
@@ -0,0 +1,69 @@
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5using System.Text;
6using OpenSim.Framework;
7using OpenSim.Region.Framework.Interfaces;
8using OpenSim.Services.Interfaces;
9using OpenSim.Services.Connectors.Hypergrid;
10using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
11
12using OpenMetaverse;
13
14using log4net;
15
16namespace OpenSim.Region.CoreModules.Avatar.Friends
17{
18 public class HGStatusNotifier
19 {
20 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
21
22 private HGFriendsModule m_FriendsModule;
23
24 public HGStatusNotifier(HGFriendsModule friendsModule)
25 {
26 m_FriendsModule = friendsModule;
27 }
28
29 public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online)
30 {
31 foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
32 {
33 if (kvp.Key != "local")
34 {
35 // For the others, call the user agent service
36 List<string> ids = new List<string>();
37 foreach (FriendInfo f in kvp.Value)
38 ids.Add(f.Friend);
39
40 if (ids.Count == 0)
41 continue; // no one to notify. caller don't do this
42
43 m_log.DebugFormat("[HG STATUS NOTIFIER]: Notifying {0} friends in {1}", ids.Count, kvp.Key);
44 // ASSUMPTION: we assume that all users for one home domain
45 // have exactly the same set of service URLs.
46 // If this is ever not true, we need to change this.
47 UUID friendID = UUID.Zero; String tmp = String.Empty;
48 if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp))
49 {
50 string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI");
51 if (friendsServerURI != string.Empty)
52 {
53 HGFriendsServicesConnector fConn = new HGFriendsServicesConnector(friendsServerURI);
54
55 List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online);
56
57 if (online && friendsOnline.Count > 0)
58 {
59 IClientAPI client = m_FriendsModule.LocateClientObject(userID);
60 if (client != null)
61 client.SendAgentOnline(friendsOnline.ToArray());
62 }
63 }
64 }
65 }
66 }
67 }
68 }
69}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 5238325..a26c73a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -270,12 +270,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
270 270
271 m_archiveWriter = new TarArchiveWriter(m_saveStream); 271 m_archiveWriter = new TarArchiveWriter(m_saveStream);
272 272
273 m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
274
273 // Write out control file. This has to be done first so that subsequent loaders will see this file first 275 // Write out control file. This has to be done first so that subsequent loaders will see this file first
274 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this 276 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
275 // not sure how to fix this though, short of going with a completely different file format. 277 // not sure how to fix this though, short of going with a completely different file format.
276 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); 278 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
277 m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive."); 279
278
279 if (inventoryFolder != null) 280 if (inventoryFolder != null)
280 { 281 {
281 m_log.DebugFormat( 282 m_log.DebugFormat(
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 650069a..ac22c3f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
108 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; 108 OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
109 109
110 scene.AddCommand( 110 scene.AddCommand(
111 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>]",
113 "Load user inventory archive (IAR).", 113 "Load user inventory archive (IAR).",
114 "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones" 114 "-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
@@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
121 HandleLoadInvConsoleCommand); 121 HandleLoadInvConsoleCommand);
122 122
123 scene.AddCommand( 123 scene.AddCommand(
124 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] [-v|--verbose]",
126 "Save user inventory archive (IAR).", 126 "Save user inventory archive (IAR).",
127 "<first> is the user's first name." + Environment.NewLine 127 "<first> is the user's first name.\n"
128 + "<last> is the user's last name." + Environment.NewLine 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." + Environment.NewLine 129 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
130 + "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
131 + "-c|--creators preserves information about foreign creators." + Environment.NewLine
132 + "-v|--verbose extra debug messages." + Environment.NewLine
133 + "--noassets stops assets being saved to the IAR."
134 + "<IAR path> is the filesystem path at which to save the IAR." 130 + "<IAR path> is the filesystem path at which to save the IAR."
135 + string.Format(" If this is not given then the filename {0} in the current directory is used", 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"
133 + "-c|--creators preserves information about foreign creators.\n"
134 + "-v|--verbose extra debug messages.\n"
135 + "--noassets stops assets being saved to the IAR.",
136 HandleSaveInvConsoleCommand); 136 HandleSaveInvConsoleCommand);
137 137
138 m_aScene = scene; 138 m_aScene = scene;
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 9d1538f..4ea85a8 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -69,9 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework
69 { 69 {
70 m_scene = scene; 70 m_scene = scene;
71 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); 71 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
72 MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps", 72
73 MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps",
73 "show caps", 74 "show caps",
74 "Shows all registered capabilities", HandleShowCapsCommand); 75 "Shows all registered capabilities for users", HandleShowCapsCommand);
75 } 76 }
76 77
77 public void RegionLoaded(Scene scene) 78 public void RegionLoaded(Scene scene)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f6e4dbf..2d73594 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -304,6 +304,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
304 return; 304 return;
305 } 305 }
306 306
307 if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
308 return;
309
307 m_log.DebugFormat( 310 m_log.DebugFormat(
308 "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", 311 "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}",
309 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); 312 reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
@@ -444,7 +447,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
444 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.", 447 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
445 sp.Name, finalDestination.RegionName); 448 sp.Name, finalDestination.RegionName);
446 449
447 Fail(sp, finalDestination); 450 Fail(sp, finalDestination, logout);
448 return; 451 return;
449 } 452 }
450 453
@@ -476,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
476 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", 479 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
477 sp.Name, finalDestination.RegionName); 480 sp.Name, finalDestination.RegionName);
478 481
479 Fail(sp, finalDestination); 482 Fail(sp, finalDestination, logout);
480 return; 483 return;
481 } 484 }
482 485
@@ -527,7 +530,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
527 } 530 }
528 } 531 }
529 532
530 private void Fail(ScenePresence sp, GridRegion finalDestination) 533 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
531 { 534 {
532 // Client never contacted destination. Let's restore everything back 535 // Client never contacted destination. Let's restore everything back
533 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); 536 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
@@ -1861,6 +1864,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1861 } 1864 }
1862 } 1865 }
1863 1866
1867 protected bool IsInTransit(UUID id)
1868 {
1869 lock (m_agentsInTransit)
1870 {
1871 if (m_agentsInTransit.Contains(id))
1872 return true;
1873 }
1874 return false;
1875 }
1876
1864 protected bool ResetFromTransit(UUID id) 1877 protected bool ResetFromTransit(UUID id)
1865 { 1878 {
1866 lock (m_agentsInTransit) 1879 lock (m_agentsInTransit)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 38a7805..b277095 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
50 50
51 private bool m_Initialized = false; 51 private bool m_Initialized = false;
52 52
53 private bool m_RestrictInventoryAccessAbroad = false;
54
53 private GatekeeperServiceConnector m_GatekeeperConnector; 55 private GatekeeperServiceConnector m_GatekeeperConnector;
54 56
55 #region ISharedRegionModule 57 #region ISharedRegionModule
@@ -68,6 +70,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
68 if (name == Name) 70 if (name == Name)
69 { 71 {
70 InitialiseCommon(source); 72 InitialiseCommon(source);
73 IConfig transferConfig = source.Configs["HGEntityTransfer"];
74 if (transferConfig != null)
75 m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
76
71 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 77 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
72 } 78 }
73 } 79 }
@@ -170,6 +176,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
170 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); 176 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
171 logout = success; // flag for later logout from this grid; this is an HG TP 177 logout = success; // flag for later logout from this grid; this is an HG TP
172 178
179 if (success && m_RestrictInventoryAccessAbroad)
180 {
181 // TODO tell the viewer to remove the root folder
182 }
183
173 return success; 184 return success;
174 } 185 }
175 else 186 else
@@ -283,6 +294,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
283 294
284 } 295 }
285 296
297 protected override void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
298 {
299 base.Fail(sp, finalDestination, logout);
300 if (logout && m_RestrictInventoryAccessAbroad)
301 {
302 // Restore the user's inventory, because we removed it earlier on
303 InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(sp.UUID);
304 if (root != null)
305 {
306 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring");
307 sp.ControllingClient.SendBulkUpdateInventory(root);
308 }
309 }
310 }
311
286 #endregion 312 #endregion
287 313
288 #region IUserAgentVerificationModule 314 #region IUserAgentVerificationModule
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index 3f466be..7f8271d 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
72 72
73 m_scene = scene; 73 m_scene = scene;
74 74
75 m_scene.AddCommand(this, "monitor report", 75 m_scene.AddCommand("General", this, "monitor report",
76 "monitor report", 76 "monitor report",
77 "Returns a variety of statistics about the current region and/or simulator", 77 "Returns a variety of statistics about the current region and/or simulator",
78 DebugMonitors); 78 DebugMonitors);
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
new file mode 100644
index 0000000..4eecaa2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -0,0 +1,161 @@
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 */
27using System;
28using System.Collections.Generic;
29using System.IO;
30using System.Reflection;
31
32using OpenSim.Framework;
33using OpenSim.Framework.Console;
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces;
38using OpenSim.Services.Connectors.Hypergrid;
39
40using OpenMetaverse;
41using OpenMetaverse.Packets;
42using log4net;
43using Nini.Config;
44
45namespace OpenSim.Region.CoreModules.Framework.UserManagement
46{
47 public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51
52 #region ISharedRegionModule
53
54 public new void Initialise(IConfigSource config)
55 {
56 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", base.Name);
57 if (umanmod == Name)
58 {
59 m_Enabled = true;
60 RegisterConsoleCmds();
61 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
62 }
63 }
64
65 public override string Name
66 {
67 get { return "HGUserManagementModule"; }
68 }
69
70 #endregion ISharedRegionModule
71
72 protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
73 {
74 if (query.Contains("@")) // First.Last@foo.com, maybe?
75 {
76 string[] words = query.Split(new char[] { '@' });
77 if (words.Length != 2)
78 {
79 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
80 return;
81 }
82
83 words[0] = words[0].Trim(); // it has at least 1
84 words[1] = words[1].Trim();
85
86 if (words[0] == String.Empty) // query was @foo.com?
87 {
88 foreach (UserData d in m_UserCache.Values)
89 {
90 if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
91 users.Add(d);
92 }
93
94 // We're done
95 return;
96 }
97
98 // words.Length == 2 and words[0] != string.empty
99 // first.last@foo.com ?
100 foreach (UserData d in m_UserCache.Values)
101 {
102 if (d.LastName.StartsWith("@") &&
103 d.FirstName.ToLower().Equals(words[0].ToLower()) &&
104 d.LastName.ToLower().Equals("@" + words[1].ToLower()))
105 {
106 users.Add(d);
107 // It's cached. We're done
108 return;
109 }
110 }
111
112 // This is it! Let's ask the other world
113 if (words[0].Contains("."))
114 {
115 string[] names = words[0].Split(new char[] { '.' });
116 if (names.Length >= 2)
117 {
118
119 string uriStr = "http://" + words[1];
120 // Let's check that the last name is a valid address
121 try
122 {
123 new Uri(uriStr);
124 }
125 catch (UriFormatException)
126 {
127 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
128 return;
129 }
130
131 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
132 UUID userID = uasConn.GetUUID(names[0], names[1]);
133 if (!userID.Equals(UUID.Zero))
134 {
135 UserData ud = new UserData();
136 ud.Id = userID;
137 ud.FirstName = words[0];
138 ud.LastName = "@" + words[1];
139 users.Add(ud);
140 AddUser(userID, names[0], names[1], uriStr);
141 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
142 }
143 else
144 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
145 }
146 }
147 }
148 //else
149 //{
150 // foreach (UserData d in m_UserCache.Values)
151 // {
152 // if (d.LastName.StartsWith("@") &&
153 // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
154 // d.LastName.ToLower().StartsWith(query.ToLower())))
155 // users.Add(d);
156 // }
157 //}
158 }
159
160 }
161} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index b4f6b5a..0397478 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -38,12 +38,13 @@ using OpenSim.Services.Interfaces;
38using OpenSim.Services.Connectors.Hypergrid; 38using OpenSim.Services.Connectors.Hypergrid;
39 39
40using OpenMetaverse; 40using OpenMetaverse;
41using OpenMetaverse.Packets;
41using log4net; 42using log4net;
42using Nini.Config; 43using Nini.Config;
43 44
44namespace OpenSim.Region.CoreModules.Framework.UserManagement 45namespace OpenSim.Region.CoreModules.Framework.UserManagement
45{ 46{
46 class UserData 47 public class UserData
47 { 48 {
48 public UUID Id { get; set; } 49 public UUID Id { get; set; }
49 public string FirstName { get; set; } 50 public string FirstName { get; set; }
@@ -56,36 +57,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
56 { 57 {
57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 59
59 private List<Scene> m_Scenes = new List<Scene>(); 60 protected bool m_Enabled;
61 protected List<Scene> m_Scenes = new List<Scene>();
60 62
61 // The cache 63 // The cache
62 Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); 64 protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
63 65
64 #region ISharedRegionModule 66 #region ISharedRegionModule
65 67
66 public void Initialise(IConfigSource config) 68 public void Initialise(IConfigSource config)
67 { 69 {
68 //m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled); 70 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
69 //if (m_Enabled) 71 if (umanmod == Name)
70 //{ 72 {
71 // IConfig libConfig = config.Configs["LibraryService"]; 73 m_Enabled = true;
72 // if (libConfig != null) 74 RegisterConsoleCmds();
73 // { 75 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
74 // string dllName = libConfig.GetString("LocalServiceModule", string.Empty); 76 }
75 // m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
76 // if (dllName != string.Empty)
77 // {
78 // Object[] args = new Object[] { config };
79 // m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
80 // }
81 // }
82 //}
83 MainConsole.Instance.Commands.AddCommand("grid", true,
84 "show names",
85 "show names",
86 "Show the bindings between user UUIDs and user names",
87 String.Empty,
88 HandleShowUsers);
89 } 77 }
90 78
91 public bool IsSharedModule 79 public bool IsSharedModule
@@ -93,9 +81,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
93 get { return true; } 81 get { return true; }
94 } 82 }
95 83
96 public string Name 84 public virtual string Name
97 { 85 {
98 get { return "UserManagement Module"; } 86 get { return "BasicUserManagementModule"; }
99 } 87 }
100 88
101 public Type ReplaceableInterface 89 public Type ReplaceableInterface
@@ -105,17 +93,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
105 93
106 public void AddRegion(Scene scene) 94 public void AddRegion(Scene scene)
107 { 95 {
108 m_Scenes.Add(scene); 96 if (m_Enabled)
97 {
98 m_Scenes.Add(scene);
109 99
110 scene.RegisterModuleInterface<IUserManagement>(this); 100 scene.RegisterModuleInterface<IUserManagement>(this);
111 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 101 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
112 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); 102 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
103 }
113 } 104 }
114 105
115 public void RemoveRegion(Scene scene) 106 public void RemoveRegion(Scene scene)
116 { 107 {
117 scene.UnregisterModuleInterface<IUserManagement>(this); 108 if (m_Enabled)
118 m_Scenes.Remove(scene); 109 {
110 scene.UnregisterModuleInterface<IUserManagement>(this);
111 m_Scenes.Remove(scene);
112 }
119 } 113 }
120 114
121 public void RegionLoaded(Scene s) 115 public void RegionLoaded(Scene s)
@@ -149,7 +143,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
149 143
150 void EventManager_OnNewClient(IClientAPI client) 144 void EventManager_OnNewClient(IClientAPI client)
151 { 145 {
146 client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
152 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); 147 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
148 client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
149 }
150
151 void HandleConnectionClosed(IClientAPI client)
152 {
153 client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
154 client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
153 } 155 }
154 156
155 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) 157 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
@@ -170,6 +172,77 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
170 } 172 }
171 } 173 }
172 174
175 public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
176 {
177 //EventManager.TriggerAvatarPickerRequest();
178
179 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
180
181 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
182
183 List<UserData> users = new List<UserData>();
184 if (accs != null)
185 {
186 foreach (UserAccount acc in accs)
187 {
188 UserData ud = new UserData();
189 ud.FirstName = acc.FirstName;
190 ud.LastName = acc.LastName;
191 ud.Id = acc.PrincipalID;
192 users.Add(ud);
193 }
194 }
195
196 AddAdditionalUsers(avatarID, query, users);
197
198 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
199 // TODO: don't create new blocks if recycling an old packet
200
201 AvatarPickerReplyPacket.DataBlock[] searchData =
202 new AvatarPickerReplyPacket.DataBlock[users.Count];
203 AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
204
205 agentData.AgentID = avatarID;
206 agentData.QueryID = RequestID;
207 replyPacket.AgentData = agentData;
208 //byte[] bytes = new byte[AvatarResponses.Count*32];
209
210 int i = 0;
211 foreach (UserData item in users)
212 {
213 UUID translatedIDtem = item.Id;
214 searchData[i] = new AvatarPickerReplyPacket.DataBlock();
215 searchData[i].AvatarID = translatedIDtem;
216 searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName);
217 searchData[i].LastName = Utils.StringToBytes((string)item.LastName);
218 i++;
219 }
220 if (users.Count == 0)
221 {
222 searchData = new AvatarPickerReplyPacket.DataBlock[0];
223 }
224 replyPacket.Data = searchData;
225
226 AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
227 agent_data.AgentID = replyPacket.AgentData.AgentID;
228 agent_data.QueryID = replyPacket.AgentData.QueryID;
229
230 List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
231 for (i = 0; i < replyPacket.Data.Length; i++)
232 {
233 AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
234 data_arg.AvatarID = replyPacket.Data[i].AvatarID;
235 data_arg.FirstName = replyPacket.Data[i].FirstName;
236 data_arg.LastName = replyPacket.Data[i].LastName;
237 data_args.Add(data_arg);
238 }
239 client.SendAvatarPickerReply(agent_data, data_args);
240 }
241
242 protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
243 {
244 }
245
173 #endregion Event Handlers 246 #endregion Event Handlers
174 247
175 private void CacheCreators(SceneObjectGroup sog) 248 private void CacheCreators(SceneObjectGroup sog)
@@ -226,7 +299,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
226 299
227 public string GetUserName(UUID uuid) 300 public string GetUserName(UUID uuid)
228 { 301 {
229 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
230 string[] names = GetUserNames(uuid); 302 string[] names = GetUserNames(uuid);
231 if (names.Length == 2) 303 if (names.Length == 2)
232 { 304 {
@@ -267,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
267 339
268 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) 340 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
269 { 341 {
270 m_log.DebugFormat( 342 //m_log.DebugFormat(
271 "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", 343 // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
272 serverType, userdata.HomeURL, userID); 344 // serverType, userdata.HomeURL, userID);
273 345
274 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); 346 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
275 userdata.ServerURLs = uConn.GetServerURLs(userID); 347 userdata.ServerURLs = uConn.GetServerURLs(userID);
@@ -328,11 +400,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
328 400
329 public void AddUser(UUID uuid, string first, string last, string homeURL) 401 public void AddUser(UUID uuid, string first, string last, string homeURL)
330 { 402 {
403 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
404
331 AddUser(uuid, homeURL + ";" + first + " " + last); 405 AddUser(uuid, homeURL + ";" + first + " " + last);
332 } 406 }
333 407
334 public void AddUser (UUID id, string creatorData) 408 public void AddUser (UUID id, string creatorData)
335 { 409 {
410 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
411
336 UserData oldUser; 412 UserData oldUser;
337 //lock the whole block - prevent concurrent update 413 //lock the whole block - prevent concurrent update
338 lock (m_UserCache) 414 lock (m_UserCache)
@@ -358,9 +434,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
358 return; 434 return;
359 } 435 }
360 } 436 }
361// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
362 437
363 UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id); 438 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
364 439
365 if (account != null) 440 if (account != null)
366 { 441 {
@@ -409,9 +484,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
409 lock (m_UserCache) 484 lock (m_UserCache)
410 m_UserCache[user.Id] = user; 485 m_UserCache[user.Id] = user;
411 486
412// m_log.DebugFormat( 487 //m_log.DebugFormat(
413// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", 488 // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
414// user.Id, user.FirstName, user.LastName, user.HomeURL); 489 // user.Id, user.FirstName, user.LastName, user.HomeURL);
415 } 490 }
416 491
417 public bool IsLocalGridUser(UUID uuid) 492 public bool IsLocalGridUser(UUID uuid)
@@ -425,13 +500,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
425 500
426 #endregion IUserManagement 501 #endregion IUserManagement
427 502
503 protected void RegisterConsoleCmds()
504 {
505 MainConsole.Instance.Commands.AddCommand("Users", true,
506 "show names",
507 "show names",
508 "Show the bindings between user UUIDs and user names",
509 String.Empty,
510 HandleShowUsers);
511 }
512
428 private void HandleShowUsers(string module, string[] cmd) 513 private void HandleShowUsers(string module, string[] cmd)
429 { 514 {
430 lock (m_UserCache) 515 lock (m_UserCache)
431 { 516 {
432 if (m_UserCache.Count == 0) 517 if (m_UserCache.Count == 0)
433 { 518 {
434 MainConsole.Instance.Output("No users not found"); 519 MainConsole.Instance.Output("No users found");
435 return; 520 return;
436 } 521 }
437 522
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index e22fd38..dc6efed 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -9,6 +9,7 @@
9 9
10 <Extension path = "/OpenSim/RegionModules"> 10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" /> 11 <RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
12 <RegionModule id="HGUserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.HGUserManagementModule" />
12 <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" /> 13 <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
13 <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" /> 14 <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
14 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> 15 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 640a60b..ef9b4e0 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -151,6 +151,14 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
151 151
152 #region IWorldComm Members 152 #region IWorldComm Members
153 153
154 public int ListenerCount
155 {
156 get
157 {
158 return m_listenerManager.ListenerCount;
159 }
160 }
161
154 /// <summary> 162 /// <summary>
155 /// Create a listen event callback with the specified filters. 163 /// Create a listen event callback with the specified filters.
156 /// The parameters localID,itemID are needed to uniquely identify 164 /// The parameters localID,itemID are needed to uniquely identify
@@ -438,6 +446,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
438 private int m_maxhandles; 446 private int m_maxhandles;
439 private int m_curlisteners; 447 private int m_curlisteners;
440 448
449 /// <summary>
450 /// Total number of listeners
451 /// </summary>
452 public int ListenerCount
453 {
454 get
455 {
456 lock (m_listeners)
457 return m_listeners.Count;
458 }
459 }
460
441 public ListenerManager(int maxlisteners, int maxhandles) 461 public ListenerManager(int maxlisteners, int maxhandles)
442 { 462 {
443 m_maxlisteners = maxlisteners; 463 m_maxlisteners = maxlisteners;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index 89abbb2..8df1c7b 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
48 private static bool m_Enabled = false; 48 private static bool m_Enabled = false;
49 49
50 private IConfigSource m_Config; 50 private IConfigSource m_Config;
51 bool m_Registered = false; 51 private bool m_Registered = false;
52 GatekeeperServiceInConnector m_HypergridHandler; 52 private string m_LocalServiceDll = String.Empty;
53 private GatekeeperServiceInConnector m_HypergridHandler;
54 private UserAgentServerConnector m_UASHandler;
53 55
54 #region IRegionModule interface 56 #region IRegionModule interface
55 57
@@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
63 if (m_Enabled) 65 if (m_Enabled)
64 { 66 {
65 m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled"); 67 m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
68 IConfig fconfig = config.Configs["FriendsService"];
69 if (fconfig != null)
70 {
71 m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
72 if (m_LocalServiceDll == String.Empty)
73 m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
74 }
66 } 75 }
67 76
68 } 77 }
@@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
91 { 100 {
92 if (!m_Enabled) 101 if (!m_Enabled)
93 return; 102 return;
94
95 } 103 }
96 104
97 public void RemoveRegion(Scene scene) 105 public void RemoveRegion(Scene scene)
@@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
112 m_log.Info("[HypergridService]: Starting..."); 120 m_log.Info("[HypergridService]: Starting...");
113 121
114 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 122 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
123 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
124 Object[] args = new Object[] { m_Config };
125 IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
126
115 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 127 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
116 128
117 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); 129 m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
118 new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn); 130
119 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 131 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
120 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService"); 132
133 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
121 } 134 }
122 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 135 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
136 scene.RegisterModuleInterface<IUserAgentService>(m_UASHandler.HomeUsersService);
123 } 137 }
124 138
125 #endregion 139 #endregion
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index 2e6ec90..c78915f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -73,14 +73,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
73 return; 73 return;
74 } 74 }
75 75
76 string serviceDll = assetConfig.GetString("LocalServiceModule", 76 string serviceDll = assetConfig.GetString("LocalServiceModule", String.Empty);
77 String.Empty);
78 77
79 if (serviceDll == String.Empty) 78 if (serviceDll == String.Empty)
80 { 79 {
81 m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService"); 80 m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService");
82 return; 81 return;
83 } 82 }
83 else
84 {
85 m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Loading asset service at {0}", serviceDll);
86 }
84 87
85 Object[] args = new Object[] { source }; 88 Object[] args = new Object[] { source };
86 m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args); 89 m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs
new file mode 100644
index 0000000..f0d21e6
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs
@@ -0,0 +1,124 @@
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 Nini.Config;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Services.Interfaces;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using OpenMetaverse;
39
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
43{
44 public class AuthorizationService : IAuthorizationService
45 {
46 private enum AccessFlags
47 {
48 None = 0, /* No restrictions */
49 DisallowResidents = 1, /* Only gods and managers*/
50 DisallowForeigners = 2, /* Only local people */
51 }
52
53 private static readonly ILog m_log =
54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType);
56
57 private IUserManagement m_UserManagement;
58 private IGridService m_GridService;
59
60 private Scene m_Scene;
61 AccessFlags m_accessValue = AccessFlags.None;
62
63
64 public AuthorizationService(IConfig config, Scene scene)
65 {
66 m_Scene = scene;
67 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
68 m_GridService = scene.GridService;
69
70 if (config != null)
71 {
72 string accessStr = config.GetString("Region_" + scene.RegionInfo.RegionName.Replace(' ', '_'), String.Empty);
73 if (accessStr != string.Empty)
74 {
75 try
76 {
77 m_accessValue = (AccessFlags)Enum.Parse(typeof(AccessFlags), accessStr);
78 }
79 catch (ArgumentException)
80 {
81 m_log.WarnFormat("[AuthorizationService]: {0} is not a valid access flag", accessStr);
82 }
83 }
84 m_log.DebugFormat("[AuthorizationService]: Region {0} access restrictions: {1}", m_Scene.RegionInfo.RegionName, m_accessValue);
85 }
86
87 }
88
89 public bool IsAuthorizedForRegion(
90 string user, string firstName, string lastName, string regionID, out string message)
91 {
92 message = "authorized";
93
94 // This should not happen
95 if (m_Scene.RegionInfo.RegionID.ToString() != regionID)
96 {
97 m_log.WarnFormat("[AuthorizationService]: Service for region {0} received request to authorize for region {1}",
98 m_Scene.RegionInfo.RegionID, regionID);
99 return true;
100 }
101
102 if (m_accessValue == AccessFlags.None)
103 return true;
104
105 UUID userID = new UUID(user);
106 bool authorized = true;
107 if ((m_accessValue & AccessFlags.DisallowForeigners) == AccessFlags.DisallowForeigners)
108 {
109 authorized = m_UserManagement.IsLocalGridUser(userID);
110 if (!authorized)
111 message = "no foreigner users allowed in this region";
112 }
113 if (authorized && (m_accessValue & AccessFlags.DisallowResidents) == AccessFlags.DisallowResidents)
114 {
115 authorized = m_Scene.Permissions.IsGod(userID) | m_Scene.Permissions.IsAdministrator(userID);
116 if (!authorized)
117 message = "only Admins and Managers allowed in this region";
118 }
119
120 return authorized;
121 }
122
123 }
124} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index 18a7177..267fb9e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -39,13 +39,15 @@ using OpenMetaverse;
39 39
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 41{
42 public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService 42 public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService
43 { 43 {
44 private static readonly ILog m_log = 44 private static readonly ILog m_log =
45 LogManager.GetLogger( 45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private IAuthorizationService m_AuthorizationService; 48 private IAuthorizationService m_AuthorizationService;
49 private Scene m_Scene;
50 private IConfig m_AuthorizationConfig;
49 51
50 private bool m_Enabled = false; 52 private bool m_Enabled = false;
51 53
@@ -69,33 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
69 string name = moduleConfig.GetString("AuthorizationServices", string.Empty); 71 string name = moduleConfig.GetString("AuthorizationServices", string.Empty);
70 if (name == Name) 72 if (name == Name)
71 { 73 {
72 IConfig authorizationConfig = source.Configs["AuthorizationService"];
73 if (authorizationConfig == null)
74 {
75 m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini");
76 return;
77 }
78
79 string serviceDll = authorizationConfig.GetString("LocalServiceModule",
80 String.Empty);
81
82 if (serviceDll == String.Empty)
83 {
84 m_log.Error("[AUTHORIZATION CONNECTOR]: No LocalServiceModule named in section AuthorizationService");
85 return;
86 }
87
88 Object[] args = new Object[] { source };
89 m_AuthorizationService =
90 ServerUtils.LoadPlugin<IAuthorizationService>(serviceDll,
91 args);
92
93 if (m_AuthorizationService == null)
94 {
95 m_log.Error("[AUTHORIZATION CONNECTOR]: Can't load authorization service");
96 return;
97 }
98 m_Enabled = true; 74 m_Enabled = true;
75 m_AuthorizationConfig = source.Configs["AuthorizationService"];
99 m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled"); 76 m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled");
100 } 77 }
101 } 78 }
@@ -115,6 +92,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
115 return; 92 return;
116 93
117 scene.RegisterModuleInterface<IAuthorizationService>(this); 94 scene.RegisterModuleInterface<IAuthorizationService>(this);
95 m_Scene = scene;
118 } 96 }
119 97
120 public void RemoveRegion(Scene scene) 98 public void RemoveRegion(Scene scene)
@@ -126,6 +104,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
126 if (!m_Enabled) 104 if (!m_Enabled)
127 return; 105 return;
128 106
107 m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
108
129 m_log.InfoFormat( 109 m_log.InfoFormat(
130 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", 110 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
131 scene.RegionInfo.RegionName); 111 scene.RegionInfo.RegionName);
@@ -134,6 +114,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
134 public bool IsAuthorizedForRegion( 114 public bool IsAuthorizedForRegion(
135 string userID, string firstName, string lastName, string regionID, out string message) 115 string userID, string firstName, string lastName, string regionID, out string message)
136 { 116 {
117 message = "";
118 if (!m_Enabled)
119 return true;
120
137 return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message); 121 return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
138 } 122 }
139 } 123 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 3c36799..540f33a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -48,8 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
48 LogManager.GetLogger( 48 LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType); 49 MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 private static LocalGridServicesConnector m_MainInstance;
52
53 private IGridService m_GridService; 51 private IGridService m_GridService;
54 private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); 52 private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
55 53
@@ -62,7 +60,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
62 public LocalGridServicesConnector(IConfigSource source) 60 public LocalGridServicesConnector(IConfigSource source)
63 { 61 {
64 m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated"); 62 m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
65 m_MainInstance = this;
66 InitialiseService(source); 63 InitialiseService(source);
67 } 64 }
68 65
@@ -87,7 +84,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
87 if (name == Name) 84 if (name == Name)
88 { 85 {
89 InitialiseService(source); 86 InitialiseService(source);
90 m_MainInstance = this;
91 m_Enabled = true; 87 m_Enabled = true;
92 m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled"); 88 m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
93 } 89 }
@@ -126,12 +122,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
126 122
127 public void PostInitialise() 123 public void PostInitialise()
128 { 124 {
129 if (m_MainInstance == this) 125 MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
130 { 126 "show neighbours",
131 MainConsole.Instance.Commands.AddCommand("LocalGridConnector", false, "show neighbours", 127 "Shows the local regions' neighbours", NeighboursCommand);
132 "show neighbours",
133 "Shows the local regions' neighbours", NeighboursCommand);
134 }
135 } 128 }
136 129
137 public void Close() 130 public void Close()
@@ -143,22 +136,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
143 if (m_Enabled) 136 if (m_Enabled)
144 scene.RegisterModuleInterface<IGridService>(this); 137 scene.RegisterModuleInterface<IGridService>(this);
145 138
146 if (m_MainInstance == this) 139 if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
147 { 140 m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
148 if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) 141 else
149 m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); 142 m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
150 else
151 m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
152 }
153 } 143 }
154 144
155 public void RemoveRegion(Scene scene) 145 public void RemoveRegion(Scene scene)
156 { 146 {
157 if (m_MainInstance == this) 147 m_LocalCache[scene.RegionInfo.RegionID].Clear();
158 { 148 m_LocalCache.Remove(scene.RegionInfo.RegionID);
159 m_LocalCache[scene.RegionInfo.RegionID].Clear();
160 m_LocalCache.Remove(scene.RegionInfo.RegionID);
161 }
162 } 149 }
163 150
164 public void RegionLoaded(Scene scene) 151 public void RegionLoaded(Scene scene)
@@ -259,6 +246,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
259 246
260 MainConsole.Instance.Output(caps.ToString()); 247 MainConsole.Instance.Output(caps.ToString());
261 } 248 }
262
263 } 249 }
264} 250} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index b5c0af6..4be3804 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -58,6 +58,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
58 58
59 private List<Scene> m_Scenes = new List<Scene>(); 59 private List<Scene> m_Scenes = new List<Scene>();
60 60
61 private InventoryCache m_Cache = new InventoryCache();
62
61 protected IUserManagement m_UserManagement; 63 protected IUserManagement m_UserManagement;
62 protected IUserManagement UserManagementModule 64 protected IUserManagement UserManagementModule
63 { 65 {
@@ -312,6 +314,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
312 public InventoryFolderBase GetRootFolder(UUID userID) 314 public InventoryFolderBase GetRootFolder(UUID userID)
313 { 315 {
314 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID); 316 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
317 InventoryFolderBase root = m_Cache.GetRootFolder(userID);
318 if (root != null)
319 return root;
315 320
316 string invURL = GetInventoryServiceURL(userID); 321 string invURL = GetInventoryServiceURL(userID);
317 322
@@ -320,12 +325,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
320 325
321 IInventoryService connector = GetConnector(invURL); 326 IInventoryService connector = GetConnector(invURL);
322 327
323 return connector.GetRootFolder(userID); 328 root = connector.GetRootFolder(userID);
329
330 m_Cache.Cache(userID, root);
331
332 return root;
324 } 333 }
325 334
326 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) 335 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
327 { 336 {
328 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type); 337 //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
338 InventoryFolderBase f = m_Cache.GetFolderForType(userID, type);
339 if (f != null)
340 return f;
329 341
330 string invURL = GetInventoryServiceURL(userID); 342 string invURL = GetInventoryServiceURL(userID);
331 343
@@ -334,7 +346,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
334 346
335 IInventoryService connector = GetConnector(invURL); 347 IInventoryService connector = GetConnector(invURL);
336 348
337 return connector.GetFolderForType(userID, type); 349 f = connector.GetFolderForType(userID, type);
350
351 m_Cache.Cache(userID, type, f);
352
353 return f;
338 } 354 }
339 355
340 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 356 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
new file mode 100644
index 0000000..0fe778d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
@@ -0,0 +1,59 @@
1using System;
2using System.Collections.Generic;
3
4using OpenSim.Framework;
5using OpenMetaverse;
6
7namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
8{
9 public class InventoryCache
10 {
11 private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour
12
13 private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
14 private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
15
16 public void Cache(UUID userID, InventoryFolderBase root)
17 {
18 lock (m_RootFolders)
19 m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS);
20 }
21
22 public InventoryFolderBase GetRootFolder(UUID userID)
23 {
24 InventoryFolderBase root = null;
25 if (m_RootFolders.TryGetValue(userID, out root))
26 return root;
27
28 return null;
29 }
30
31 public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
32 {
33 lock (m_FolderTypes)
34 {
35 Dictionary<AssetType, InventoryFolderBase> ff = null;
36 if (!m_FolderTypes.TryGetValue(userID, out ff))
37 {
38 ff = new Dictionary<AssetType, InventoryFolderBase>();
39 m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
40 }
41 if (!ff.ContainsKey(type))
42 ff.Add(type, folder);
43 }
44 }
45
46 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
47 {
48 Dictionary<AssetType, InventoryFolderBase> ff = null;
49 if (m_FolderTypes.TryGetValue(userID, out ff))
50 {
51 InventoryFolderBase f = null;
52 if (ff.TryGetValue(type, out f))
53 return f;
54 }
55
56 return null;
57 }
58 }
59}
diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
index 2399134..553a32d 100644
--- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
+++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
@@ -47,21 +47,21 @@ namespace OpenSim.Region.CoreModules.World
47 47
48 public void Initialise(IConfigSource config) 48 public void Initialise(IConfigSource config)
49 { 49 {
50 MainConsole.Instance.Commands.AddCommand("access", true, 50 MainConsole.Instance.Commands.AddCommand("Users", true,
51 "login enable", 51 "login enable",
52 "login enable", 52 "login enable",
53 "Enable simulator logins", 53 "Enable simulator logins",
54 String.Empty, 54 String.Empty,
55 HandleLoginCommand); 55 HandleLoginCommand);
56 56
57 MainConsole.Instance.Commands.AddCommand("access", true, 57 MainConsole.Instance.Commands.AddCommand("Users", true,
58 "login disable", 58 "login disable",
59 "login disable", 59 "login disable",
60 "Disable simulator logins", 60 "Disable simulator logins",
61 String.Empty, 61 String.Empty,
62 HandleLoginCommand); 62 HandleLoginCommand);
63 63
64 MainConsole.Instance.Commands.AddCommand("access", true, 64 MainConsole.Instance.Commands.AddCommand("Users", true,
65 "login status", 65 "login status",
66 "login status", 66 "login status",
67 "Show login status", 67 "Show login status",
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
index 9ec4ebe..c179a34 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
@@ -108,12 +108,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
108// "[ARCHIVER]: Received {0} of {1} assets requested", 108// "[ARCHIVER]: Received {0} of {1} assets requested",
109// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); 109// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
110 110
111 m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
112
111 // Write out region settings 113 // Write out region settings
112 string settingsPath 114 string settingsPath
113 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName); 115 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
114 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings)); 116 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
115 117
116 m_log.InfoFormat("[ARCHIVER]: Added region settings to archive."); 118 m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
117 119
118 // Write out land data (aka parcel) settings 120 // Write out land data (aka parcel) settings
119 List<ILandObject>landObjects = m_scene.LandChannel.AllParcels(); 121 List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
@@ -124,7 +126,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
124 landData.GlobalID.ToString()); 126 landData.GlobalID.ToString());
125 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData)); 127 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
126 } 128 }
127 m_log.InfoFormat("[ARCHIVER]: Added parcel settings to archive."); 129
130 m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
128 131
129 // Write out terrain 132 // Write out terrain
130 string terrainPath 133 string terrainPath
@@ -135,7 +138,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
135 m_archiveWriter.WriteFile(terrainPath, ms.ToArray()); 138 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
136 ms.Close(); 139 ms.Close();
137 140
138 m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive."); 141 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
139 142
140 // Write out scene object metadata 143 // Write out scene object metadata
141 foreach (SceneObjectGroup sceneObject in m_sceneObjects) 144 foreach (SceneObjectGroup sceneObject in m_sceneObjects)
@@ -145,10 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
145 string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options); 148 string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
146 m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject); 149 m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
147 } 150 }
148
149 m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");
150 } 151 }
151
152
153 } 152 }
154} 153} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index ffcf063..4d459bf 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -219,12 +219,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
219 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 219 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
220 220
221 if (SaveAssets) 221 if (SaveAssets)
222 new AssetsRequest( 222 {
223 new AssetsArchiver(archiveWriter), assetUuids, 223 AssetsRequest ar
224 m_scene.AssetService, m_scene.UserAccountService, 224 = new AssetsRequest(
225 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); 225 new AssetsArchiver(archiveWriter), assetUuids,
226 m_scene.AssetService, m_scene.UserAccountService,
227 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
228
229 Util.FireAndForget(o => ar.Execute());
230 }
226 else 231 else
232 {
227 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>()); 233 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
234 }
228 } 235 }
229 catch (Exception) 236 catch (Exception)
230 { 237 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 8e29e3c..55110dc 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -141,13 +141,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
141 PerformAssetsRequestCallback(null); 141 PerformAssetsRequestCallback(null);
142 return; 142 return;
143 } 143 }
144 144
145 m_requestCallbackTimer.Enabled = true;
146
145 foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids) 147 foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
146 { 148 {
147 m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); 149// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
150 AssetBase asset = m_assetService.Get(kvp.Key.ToString());
151 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
148 } 152 }
149
150 m_requestCallbackTimer.Enabled = true;
151 } 153 }
152 154
153 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) 155 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
index f6d1a82..d2bbea3 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs
@@ -62,58 +62,25 @@ namespace OpenSim.Region.CoreModules.World.Estate
62 { 62 {
63 m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); 63 m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
64 64
65 m_module.Scene.AddCommand(m_module, "set terrain texture", 65 m_module.Scene.AddCommand("Regions", m_module, "set terrain texture",
66 "set terrain texture <number> <uuid> [<x>] [<y>]", 66 "set terrain texture <number> <uuid> [<x>] [<y>]",
67 "Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " + 67 "Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
68 "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + 68 "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
69 " that coordinate.", 69 " that coordinate.",
70 consoleSetTerrainTexture); 70 consoleSetTerrainTexture);
71 71
72 m_module.Scene.AddCommand(m_module, "set terrain heights", 72 m_module.Scene.AddCommand("Regions", m_module, "set terrain heights",
73 "set terrain heights <corner> <min> <max> [<x>] [<y>]", 73 "set terrain heights <corner> <min> <max> [<x>] [<y>]",
74 "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + 74 "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
75 "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + 75 "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
76 " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.", 76 " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
77 consoleSetTerrainHeights); 77 consoleSetTerrainHeights);
78
79 Command showCommand
80 = new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator.");
81
82 m_commander.RegisterCommand("show", showCommand);
83 78
84 m_module.Scene.RegisterModuleCommander(m_commander); 79 m_module.Scene.AddCommand(
85 80 "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand);
86 m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
87 } 81 }
88 82
89 public void Close() 83 public void Close() {}
90 {
91 m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
92 m_module.Scene.UnregisterModuleCommander(m_commander.Name);
93 }
94
95 /// <summary>
96 /// Processes commandline input. Do not call directly.
97 /// </summary>
98 /// <param name="args">Commandline arguments</param>
99 protected void EventManagerOnPluginConsole(string[] args)
100 {
101 if (args[0] == "estate")
102 {
103 if (args.Length == 1)
104 {
105 m_commander.ProcessConsoleCommand("help", new string[0]);
106 return;
107 }
108
109 string[] tmpArgs = new string[args.Length - 2];
110 int i;
111 for (i = 2; i < args.Length; i++)
112 tmpArgs[i - 2] = args[i];
113
114 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
115 }
116 }
117 84
118 protected void consoleSetTerrainTexture(string module, string[] args) 85 protected void consoleSetTerrainTexture(string module, string[] args)
119 { 86 {
@@ -201,7 +168,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
201 } 168 }
202 } 169 }
203 170
204 protected void ShowEstatesCommand(Object[] args) 171 protected void ShowEstatesCommand(string module, string[] cmd)
205 { 172 {
206 StringBuilder report = new StringBuilder(); 173 StringBuilder report = new StringBuilder();
207 RegionInfo ri = m_module.Scene.RegionInfo; 174 RegionInfo ri = m_module.Scene.RegionInfo;
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index c303d6d..fc217b0 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -26,8 +26,10 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.IO; 31using System.IO;
32using System.Linq;
31using System.Reflection; 33using System.Reflection;
32using System.Security; 34using System.Security;
33using log4net; 35using log4net;
@@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
45 { 47 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 49
48 private delegate void LookupUUIDS(List<UUID> uuidLst);
49
50 public Scene Scene { get; private set; } 50 public Scene Scene { get; private set; }
51 public IUserManagement UserManager { get; private set; } 51 public IUserManagement UserManager { get; private set; }
52 52
@@ -604,7 +604,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
604 604
605 public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) 605 public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
606 { 606 {
607 uint ObjectLocalID;
608 SceneObjectPart part; 607 SceneObjectPart part;
609 608
610 switch (cmd) 609 switch (cmd)
@@ -661,28 +660,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
661 TriggerEstateMessage(senderID, senderName, message); 660 TriggerEstateMessage(senderID, senderName, message);
662 } 661 }
663 662
664 private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics) 663 private void handleEstateDebugRegionRequest(
664 IClientAPI remote_client, UUID invoice, UUID senderID,
665 bool disableScripts, bool disableCollisions, bool disablePhysics)
665 { 666 {
666 if (physics) 667 Scene.RegionInfo.RegionSettings.DisablePhysics = disablePhysics;
667 Scene.RegionInfo.RegionSettings.DisablePhysics = true; 668 Scene.RegionInfo.RegionSettings.DisableScripts = disableScripts;
668 else 669 Scene.RegionInfo.RegionSettings.DisableCollisions = disableCollisions;
669 Scene.RegionInfo.RegionSettings.DisablePhysics = false;
670
671 if (scripted)
672 Scene.RegionInfo.RegionSettings.DisableScripts = true;
673 else
674 Scene.RegionInfo.RegionSettings.DisableScripts = false;
675
676 if (collisionEvents)
677 Scene.RegionInfo.RegionSettings.DisableCollisions = true;
678 else
679 Scene.RegionInfo.RegionSettings.DisableCollisions = false;
680
681
682 Scene.RegionInfo.RegionSettings.Save(); 670 Scene.RegionInfo.RegionSettings.Save();
683 TriggerRegionInfoChange(); 671 TriggerRegionInfoChange();
684 672
685 Scene.SetSceneCoreDebug(scripted, collisionEvents, physics); 673 Scene.SetSceneCoreDebug(
674 new Dictionary<string, string>() {
675 { "scripting", (!disableScripts).ToString() },
676 { "collisions", (!disableCollisions).ToString() },
677 { "physics", (!disablePhysics).ToString() }
678 }
679 );
686 } 680 }
687 681
688 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) 682 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
@@ -876,98 +870,76 @@ namespace OpenSim.Region.CoreModules.World.Estate
876 if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) 870 if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
877 return; 871 return;
878 872
879 Dictionary<uint, float> SceneData = new Dictionary<uint,float>(); 873 Dictionary<uint, float> sceneData = null;
880 List<UUID> uuidNameLookupList = new List<UUID>();
881 874
882 if (reportType == 1) 875 if (reportType == 1)
883 { 876 {
884 SceneData = Scene.PhysicsScene.GetTopColliders(); 877 sceneData = Scene.PhysicsScene.GetTopColliders();
885 } 878 }
886 else if (reportType == 0) 879 else if (reportType == 0)
887 { 880 {
888 SceneData = Scene.SceneGraph.GetTopScripts(); 881 IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>();
882
883 if (scriptModule != null)
884 sceneData = scriptModule.GetObjectScriptsExecutionTimes();
889 } 885 }
890 886
891 List<LandStatReportItem> SceneReport = new List<LandStatReportItem>(); 887 List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
892 lock (SceneData) 888 if (sceneData != null)
893 { 889 {
894 foreach (uint obj in SceneData.Keys) 890 var sortedSceneData
891 = sceneData.Select(
892 item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
893
894 sortedSceneData.OrderBy(item => item.Measurement);
895
896 int items = 0;
897
898 foreach (var entry in sortedSceneData)
895 { 899 {
896 SceneObjectPart prt = Scene.GetSceneObjectPart(obj); 900 // The object may have been deleted since we received the data.
897 if (prt != null) 901 if (entry.Part == null)
902 continue;
903
904 // Don't show scripts that haven't executed or where execution time is below one microsecond in
905 // order to produce a more readable report.
906 if (entry.Measurement < 0.001)
907 continue;
908
909 items++;
910 SceneObjectGroup so = entry.Part.ParentGroup;
911
912 LandStatReportItem lsri = new LandStatReportItem();
913 lsri.LocationX = so.AbsolutePosition.X;
914 lsri.LocationY = so.AbsolutePosition.Y;
915 lsri.LocationZ = so.AbsolutePosition.Z;
916 lsri.Score = entry.Measurement;
917 lsri.TaskID = so.UUID;
918 lsri.TaskLocalID = so.LocalId;
919 lsri.TaskName = entry.Part.Name;
920 lsri.OwnerName = UserManager.GetUserName(so.OwnerID);
921
922 if (filter.Length != 0)
898 { 923 {
899 SceneObjectGroup sog = prt.ParentGroup; 924 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
900 LandStatReportItem lsri = new LandStatReportItem();
901 lsri.LocationX = sog.AbsolutePosition.X;
902 lsri.LocationY = sog.AbsolutePosition.Y;
903 lsri.LocationZ = sog.AbsolutePosition.Z;
904 lsri.Score = SceneData[obj];
905 lsri.TaskID = sog.UUID;
906 lsri.TaskLocalID = sog.LocalId;
907 lsri.TaskName = sog.GetPartName(obj);
908 lsri.OwnerName = "waiting";
909 lock (uuidNameLookupList)
910 uuidNameLookupList.Add(sog.OwnerID);
911
912 if (filter.Length != 0)
913 { 925 {
914 if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
915 {
916 }
917 else
918 {
919 continue;
920 }
921 } 926 }
922 927 else
923 SceneReport.Add(lsri); 928 {
929 continue;
930 }
924 } 931 }
932
933 SceneReport.Add(lsri);
934
935 if (items >= 100)
936 break;
925 } 937 }
926 } 938 }
927 939
928 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); 940 remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
929
930 if (uuidNameLookupList.Count > 0)
931 LookupUUID(uuidNameLookupList);
932 }
933
934 private static void LookupUUIDSCompleted(IAsyncResult iar)
935 {
936 LookupUUIDS icon = (LookupUUIDS)iar.AsyncState;
937 icon.EndInvoke(iar);
938 } 941 }
939
940 private void LookupUUID(List<UUID> uuidLst)
941 {
942 LookupUUIDS d = LookupUUIDsAsync;
943 942
944 d.BeginInvoke(uuidLst,
945 LookupUUIDSCompleted,
946 d);
947 }
948
949 private void LookupUUIDsAsync(List<UUID> uuidLst)
950 {
951 UUID[] uuidarr;
952
953 lock (uuidLst)
954 {
955 uuidarr = uuidLst.ToArray();
956 }
957
958 for (int i = 0; i < uuidarr.Length; i++)
959 {
960 // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
961
962 IUserManagement userManager = Scene.RequestModuleInterface<IUserManagement>();
963 if (userManager != null)
964 userManager.GetUserName(uuidarr[i]);
965
966 // we drop it. It gets cached though... so we're ready for the next request.
967 // diva commnent 11/21/2010: uh?!? wft?
968 // justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume.
969 }
970 }
971 #endregion 943 #endregion
972 944
973 #region Outgoing Packets 945 #region Outgoing Packets
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index cc42f7f..a0ed5a5 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -448,8 +448,6 @@ namespace OpenSim.Region.CoreModules.World.Land
448 448
449 public bool IsRestrictedFromLand(UUID avatar) 449 public bool IsRestrictedFromLand(UUID avatar)
450 { 450 {
451 ExpireAccessList();
452
453 if (m_scene.Permissions.IsAdministrator(avatar)) 451 if (m_scene.Permissions.IsAdministrator(avatar))
454 return false; 452 return false;
455 453
@@ -459,20 +457,27 @@ namespace OpenSim.Region.CoreModules.World.Land
459 if (avatar == LandData.OwnerID) 457 if (avatar == LandData.OwnerID)
460 return false; 458 return false;
461 459
462 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) 460 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
461 return false;
462
463 return (!IsInLandAccessList(avatar));
464 }
465
466 public bool IsInLandAccessList(UUID avatar)
467 {
468 ExpireAccessList();
469
470 if (LandData.ParcelAccessList.FindIndex(
471 delegate(LandAccessEntry e)
472 {
473 if (e.AgentID == avatar && e.Flags == AccessList.Access)
474 return true;
475 return false;
476 }) == -1)
463 { 477 {
464 if (LandData.ParcelAccessList.FindIndex( 478 return false;
465 delegate(LandAccessEntry e)
466 {
467 if (e.AgentID == avatar && e.Flags == AccessList.Access)
468 return true;
469 return false;
470 }) == -1)
471 {
472 return true;
473 }
474 } 479 }
475 return false; 480 return true;
476 } 481 }
477 482
478 public void SendLandUpdateToClient(IClientAPI remote_client) 483 public void SendLandUpdateToClient(IClientAPI remote_client)
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index e3d04cd..f5a5c92 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -78,45 +78,45 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
78 m_scene = scene; 78 m_scene = scene;
79 m_console = MainConsole.Instance; 79 m_console = MainConsole.Instance;
80 80
81 m_console.Commands.AddCommand("region", false, "delete object owner", 81 m_console.Commands.AddCommand("Regions", false, "delete object owner",
82 "delete object owner <UUID>", 82 "delete object owner <UUID>",
83 "Delete a scene object by owner", HandleDeleteObject); 83 "Delete a scene object by owner", HandleDeleteObject);
84 m_console.Commands.AddCommand("region", false, "delete object creator", 84 m_console.Commands.AddCommand("Regions", false, "delete object creator",
85 "delete object creator <UUID>", 85 "delete object creator <UUID>",
86 "Delete a scene object by creator", HandleDeleteObject); 86 "Delete a scene object by creator", HandleDeleteObject);
87 m_console.Commands.AddCommand("region", false, "delete object uuid", 87 m_console.Commands.AddCommand("Regions", false, "delete object uuid",
88 "delete object uuid <UUID>", 88 "delete object uuid <UUID>",
89 "Delete a scene object by uuid", HandleDeleteObject); 89 "Delete a scene object by uuid", HandleDeleteObject);
90 m_console.Commands.AddCommand("region", false, "delete object name", 90 m_console.Commands.AddCommand("Regions", false, "delete object name",
91 "delete object name <name>", 91 "delete object name <name>",
92 "Delete a scene object by name", HandleDeleteObject); 92 "Delete a scene object by name", HandleDeleteObject);
93 m_console.Commands.AddCommand("region", false, "delete object outside", 93 m_console.Commands.AddCommand("Regions", false, "delete object outside",
94 "delete object outside", 94 "delete object outside",
95 "Delete all scene objects outside region boundaries", HandleDeleteObject); 95 "Delete all scene objects outside region boundaries", HandleDeleteObject);
96 96
97 m_console.Commands.AddCommand( 97 m_console.Commands.AddCommand(
98 "region", 98 "Regions",
99 false, 99 false,
100 "show object uuid", 100 "show object uuid",
101 "show object uuid <UUID>", 101 "show object uuid <UUID>",
102 "Show details of a scene object with the given UUID", HandleShowObjectByUuid); 102 "Show details of a scene object with the given UUID", HandleShowObjectByUuid);
103 103
104 m_console.Commands.AddCommand( 104 m_console.Commands.AddCommand(
105 "region", 105 "Regions",
106 false, 106 false,
107 "show object name", 107 "show object name",
108 "show object name <name>", 108 "show object name <name>",
109 "Show details of scene objects with the given name", HandleShowObjectByName); 109 "Show details of scene objects with the given name", HandleShowObjectByName);
110 110
111 m_console.Commands.AddCommand( 111 m_console.Commands.AddCommand(
112 "region", 112 "Regions",
113 false, 113 false,
114 "show part uuid", 114 "show part uuid",
115 "show part uuid <UUID>", 115 "show part uuid <UUID>",
116 "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); 116 "Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
117 117
118 m_console.Commands.AddCommand( 118 m_console.Commands.AddCommand(
119 "region", 119 "Regions",
120 false, 120 false,
121 "show part name", 121 "show part name",
122 "show part name <name>", 122 "show part name <name>",
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 7023984..ac03747 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -94,7 +94,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
94 private bool m_RegionOwnerIsGod = false; 94 private bool m_RegionOwnerIsGod = false;
95 private bool m_RegionManagerIsGod = false; 95 private bool m_RegionManagerIsGod = false;
96 private bool m_ParcelOwnerIsGod = false; 96 private bool m_ParcelOwnerIsGod = false;
97 97
98 private bool m_SimpleBuildPermissions = false;
99
98 /// <value> 100 /// <value>
99 /// The set of users that are allowed to create scripts. This is only active if permissions are not being 101 /// The set of users that are allowed to create scripts. This is only active if permissions are not being
100 /// bypassed. This overrides normal permissions. 102 /// bypassed. This overrides normal permissions.
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
139 m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true); 141 m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true);
140 m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false); 142 m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);
141 m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true); 143 m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true);
142 144
145 m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false);
146
143 m_allowedScriptCreators 147 m_allowedScriptCreators
144 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); 148 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators);
145 m_allowedScriptEditors 149 m_allowedScriptEditors
@@ -206,17 +210,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
206 m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; 210 m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
207 m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; 211 m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
208 212
209 m_scene.AddCommand(this, "bypass permissions", 213 m_scene.AddCommand("Users", this, "bypass permissions",
210 "bypass permissions <true / false>", 214 "bypass permissions <true / false>",
211 "Bypass permission checks", 215 "Bypass permission checks",
212 HandleBypassPermissions); 216 HandleBypassPermissions);
213 217
214 m_scene.AddCommand(this, "force permissions", 218 m_scene.AddCommand("Users", this, "force permissions",
215 "force permissions <true / false>", 219 "force permissions <true / false>",
216 "Force permissions on or off", 220 "Force permissions on or off",
217 HandleForcePermissions); 221 HandleForcePermissions);
218 222
219 m_scene.AddCommand(this, "debug permissions", 223 m_scene.AddCommand("Users", this, "debug permissions",
220 "debug permissions <true / false>", 224 "debug permissions <true / false>",
221 "Turn on permissions debugging", 225 "Turn on permissions debugging",
222 HandleDebugPermissions); 226 HandleDebugPermissions);
@@ -824,6 +828,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
824 permission = true; 828 permission = true;
825 } 829 }
826 830
831 if (m_SimpleBuildPermissions &&
832 (parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user))
833 permission = true;
834
827 return permission; 835 return permission;
828 } 836 }
829 837
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 0f37ddd..fea4de0 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -66,21 +66,21 @@ namespace OpenSim.Region.CoreModules.World.Region
66 m_Scene = scene; 66 m_Scene = scene;
67 67
68 scene.RegisterModuleInterface<IRestartModule>(this); 68 scene.RegisterModuleInterface<IRestartModule>(this);
69 MainConsole.Instance.Commands.AddCommand("RestartModule", 69 MainConsole.Instance.Commands.AddCommand("Regions",
70 false, "region restart bluebox", 70 false, "region restart bluebox",
71 "region restart bluebox <message> <delta seconds>+", 71 "region restart bluebox <message> <delta seconds>+",
72 "Schedule a region restart", 72 "Schedule a region restart",
73 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.", 73 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
74 HandleRegionRestart); 74 HandleRegionRestart);
75 75
76 MainConsole.Instance.Commands.AddCommand("RestartModule", 76 MainConsole.Instance.Commands.AddCommand("Regions",
77 false, "region restart notice", 77 false, "region restart notice",
78 "region restart notice <message> <delta seconds>+", 78 "region restart notice <message> <delta seconds>+",
79 "Schedule a region restart", 79 "Schedule a region restart",
80 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.", 80 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
81 HandleRegionRestart); 81 HandleRegionRestart);
82 82
83 MainConsole.Instance.Commands.AddCommand("RestartModule", 83 MainConsole.Instance.Commands.AddCommand("Regions",
84 false, "region restart abort", 84 false, "region restart abort",
85 "region restart abort [<message>]", 85 "region restart abort [<message>]",
86 "Abort a region restart", HandleRegionRestart); 86 "Abort a region restart", HandleRegionRestart);
diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
index a838e1e..9a954b8 100644
--- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
@@ -277,18 +277,19 @@ namespace OpenSim.Region.CoreModules
277 m_frame = 0; 277 m_frame = 0;
278 278
279 // This one puts an entry in the main help screen 279 // This one puts an entry in the main help screen
280 m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); 280// m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
281 281
282 // This one enables the ability to type just "sun" without any parameters 282 // This one enables the ability to type just "sun" without any parameters
283 m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); 283// m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
284 foreach (KeyValuePair<string, string> kvp in GetParamList()) 284 foreach (KeyValuePair<string, string> kvp in GetParamList())
285 { 285 {
286 m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); 286 string sunCommand = string.Format("sun {0}", kvp.Key);
287 m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
287 } 288 }
288 289
289 TimeZone local = TimeZone.CurrentTimeZone; 290 TimeZone local = TimeZone.CurrentTimeZone;
290 TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; 291 TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
291 m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset); 292 m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
292 293
293 // Align ticks with Second Life 294 // Align ticks with Second Life
294 295
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
index 21a9999..58925fd 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs
@@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
132 { 132 {
133 // We need to do this because: 133 // We need to do this because:
134 // "Saving the image to the same file it was constructed from is not allowed and throws an exception." 134 // "Saving the image to the same file it was constructed from is not allowed and throws an exception."
135 string tempName = offsetX + "_ " + offsetY + "_" + filename; 135 string tempName = Path.GetTempFileName();
136 136
137 Bitmap entireBitmap = null; 137 Bitmap entireBitmap = null;
138 Bitmap thisBitmap = null; 138 Bitmap thisBitmap = null;
139 if (File.Exists(filename)) 139 if (File.Exists(filename))
140 { 140 {
141 File.Copy(filename, tempName); 141 File.Copy(filename, tempName, true);
142 entireBitmap = new Bitmap(tempName); 142 entireBitmap = new Bitmap(tempName);
143 if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) 143 if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
144 { 144 {
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
152 } 152 }
153 153
154 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); 154 thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
155 Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); 155// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
156 for (int x = 0; x < regionSizeX; x++) 156 for (int x = 0; x < regionSizeX; x++)
157 for (int y = 0; y < regionSizeY; y++) 157 for (int y = 0; y < regionSizeY; y++)
158 entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); 158 entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
index 7237f90..d407617 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainLoader.cs
@@ -38,6 +38,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain
38 ITerrainChannel LoadStream(Stream stream); 38 ITerrainChannel LoadStream(Stream stream);
39 void SaveFile(string filename, ITerrainChannel map); 39 void SaveFile(string filename, ITerrainChannel map);
40 void SaveStream(Stream stream, ITerrainChannel map); 40 void SaveStream(Stream stream, ITerrainChannel map);
41
42 /// <summary>
43 /// Save a number of map tiles to a single big image file.
44 /// </summary>
45 /// <remarks>
46 /// If the image file already exists then the tiles saved will replace those already in the file - other tiles
47 /// will be untouched.
48 /// </remarks>
49 /// <param name="filename">The terrain file to save</param>
50 /// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
51 /// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
52 /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
53 /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
54 /// <param name="regionSizeX">The width of a map tile.</param>
55 /// <param name="regionSizeY">The height of a map tile.</param>
41 void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY); 56 void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
42 } 57 }
43} \ No newline at end of file 58} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index cf000a4..b3c2969 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -86,6 +86,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
86 private volatile bool m_tainted; 86 private volatile bool m_tainted;
87 private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); 87 private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
88 88
89 private String m_InitialTerrain = "pinhead-island";
90
89 /// <summary> 91 /// <summary>
90 /// Human readable list of terrain file extensions that are supported. 92 /// Human readable list of terrain file extensions that are supported.
91 /// </summary> 93 /// </summary>
@@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
109 /// <param name="config">Config for the region</param> 111 /// <param name="config">Config for the region</param>
110 public void Initialise(IConfigSource config) 112 public void Initialise(IConfigSource config)
111 { 113 {
114 IConfig terrainConfig = config.Configs["Terrain"];
115 if (terrainConfig != null)
116 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
112 } 117 }
113 118
114 public void AddRegion(Scene scene) 119 public void AddRegion(Scene scene)
@@ -120,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
120 { 125 {
121 if (m_scene.Heightmap == null) 126 if (m_scene.Heightmap == null)
122 { 127 {
123 m_channel = new TerrainChannel(); 128 m_channel = new TerrainChannel(m_InitialTerrain);
124 m_scene.Heightmap = m_channel; 129 m_scene.Heightmap = m_channel;
125 m_revert = new TerrainChannel(); 130 m_revert = new TerrainChannel();
126 UpdateRevertMap(); 131 UpdateRevertMap();
@@ -556,43 +561,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
556 } 561 }
557 562
558 /// <summary> 563 /// <summary>
559 /// Saves the terrain to a larger terrain file. 564 /// Save a number of map tiles to a single big image file.
560 /// </summary> 565 /// </summary>
566 /// <remarks>
567 /// If the image file already exists then the tiles saved will replace those already in the file - other tiles
568 /// will be untouched.
569 /// </remarks>
561 /// <param name="filename">The terrain file to save</param> 570 /// <param name="filename">The terrain file to save</param>
562 /// <param name="fileWidth">The width of the file in units</param> 571 /// <param name="fileWidth">The number of tiles to save along the X axis.</param>
563 /// <param name="fileHeight">The height of the file in units</param> 572 /// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
564 /// <param name="fileStartX">Where to begin our slice</param> 573 /// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
565 /// <param name="fileStartY">Where to begin our slice</param> 574 /// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
566 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) 575 public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
567 { 576 {
568 int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; 577 int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
569 int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; 578 int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
570 579
571 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) 580 if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
572 { 581 {
573 // this region is included in the tile request 582 MainConsole.Instance.OutputFormat(
574 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 583 "ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
584 m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
585
586 return;
587 }
588
589 // this region is included in the tile request
590 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
591 {
592 if (filename.EndsWith(loader.Key))
575 { 593 {
576 if (filename.EndsWith(loader.Key)) 594 lock (m_scene)
577 { 595 {
578 lock (m_scene) 596 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
579 { 597 fileWidth, fileHeight,
580 loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, 598 (int)Constants.RegionSize,
581 fileWidth, fileHeight, 599 (int)Constants.RegionSize);
582 (int)Constants.RegionSize, 600
583 (int)Constants.RegionSize); 601 MainConsole.Instance.OutputFormat(
584 602 "Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
585 m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename); 603 fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
586 } 604 m_scene.RegionInfo.RegionName, filename);
587
588 return;
589 } 605 }
606
607 return;
590 } 608 }
591
592 m_log.ErrorFormat(
593 "[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
594 m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
595 } 609 }
610
611 MainConsole.Instance.OutputFormat(
612 "ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
613 m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
596 } 614 }
597 615
598 /// <summary> 616 /// <summary>
@@ -1179,8 +1197,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1179 saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); 1197 saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
1180 saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", 1198 saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
1181 "Integer"); 1199 "Integer");
1182 saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", 1200 saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
1183 "Integer"); 1201 + "= Example =\n"
1202 + "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
1203 + " # terrain save-tile ST06.png 2 3 9910 10234\n",
1204 "Integer");
1205
1184 // Terrain adjustments 1206 // Terrain adjustments
1185 Command fillRegionCommand = 1207 Command fillRegionCommand =
1186 new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value."); 1208 new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
index a488725..7b6fbda 100644
--- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
@@ -117,24 +117,31 @@ namespace OpenSim.Region.CoreModules
117 } 117 }
118 118
119 // This one puts an entry in the main help screen 119 // This one puts an entry in the main help screen
120 m_scene.AddCommand(this, String.Empty, "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null); 120// m_scene.AddCommand("Regions", this, "wind", "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null);
121 121
122 // This one enables the ability to type just the base command without any parameters 122 // This one enables the ability to type just the base command without any parameters
123 m_scene.AddCommand(this, "wind", "", "", HandleConsoleCommand); 123// m_scene.AddCommand("Regions", this, "wind", "", "", HandleConsoleCommand);
124 124
125 // Get a list of the parameters for each plugin 125 // Get a list of the parameters for each plugin
126 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values) 126 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
127 { 127 {
128 m_scene.AddCommand(this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand); 128// m_scene.AddCommand("Regions", this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand);
129 m_scene.AddCommand(this, String.Format("wind base wind_update_rate"), "Change the wind update rate.", "", HandleConsoleBaseCommand); 129 m_scene.AddCommand(
130 "Regions",
131 this,
132 "wind base wind_update_rate",
133 "wind base wind_update_rate [<value>]",
134 "Get or set the wind update rate.",
135 "",
136 HandleConsoleBaseCommand);
130 137
131 foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams()) 138 foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams())
132 { 139 {
133 m_scene.AddCommand(this, String.Format("wind {0} {1}", windPlugin.Name, kvp.Key), String.Format("{0} : {1} - {2}", windPlugin.Name, kvp.Key, kvp.Value), "", HandleConsoleParamCommand); 140 string windCommand = String.Format("wind {0} {1}", windPlugin.Name, kvp.Key);
141 m_scene.AddCommand("Regions", this, windCommand, string.Format("{0} [<value>]", windCommand), kvp.Value, "", HandleConsoleParamCommand);
134 } 142 }
135 } 143 }
136 144
137
138 // Register event handlers for when Avatars enter the region, and frame ticks 145 // Register event handlers for when Avatars enter the region, and frame ticks
139 m_scene.EventManager.OnFrame += WindUpdate; 146 m_scene.EventManager.OnFrame += WindUpdate;
140 m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion; 147 m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion;
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 657975b..f37dd94 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -92,7 +92,23 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
92 return; 92 return;
93 } 93 }
94 94
95//m_log.DebugFormat("MAP NAME=({0})", mapName); 95 //m_log.DebugFormat("MAP NAME=({0})", mapName);
96
97 // Hack to get around the fact that ll V3 now drops the port from the
98 // map name. See https://jira.secondlife.com/browse/VWR-28570
99 //
100 // Caller, use this magic form instead:
101 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
102 // or url encode if possible.
103 // the hacks we do with this viewer...
104 //
105 string mapNameOrig = mapName;
106 if (mapName.Contains("|"))
107 mapName = mapName.Replace('|', ':');
108 if (mapName.Contains("+"))
109 mapName = mapName.Replace('+', ' ');
110 if (mapName.Contains("!"))
111 mapName = mapName.Replace('!', '/');
96 112
97 // try to fetch from GridServer 113 // try to fetch from GridServer
98 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 114 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
@@ -114,7 +130,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
114 data.MapImageId = UUID.Zero; 130 data.MapImageId = UUID.Zero;
115 else 131 else
116 data.MapImageId = info.TerrainImage; 132 data.MapImageId = info.TerrainImage;
117 data.Name = info.RegionName; 133 // ugh! V2-3 is very sensitive about the result being
134 // exactly the same as the requested name
135 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
136 data.Name = mapNameOrig;
137 else
138 data.Name = info.RegionName;
118 data.RegionFlags = 0; // TODO not used? 139 data.RegionFlags = 0; // TODO not used?
119 data.WaterHeight = 0; // not used 140 data.WaterHeight = 0; // not used
120 data.X = (ushort)(info.RegionLocX / Constants.RegionSize); 141 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
@@ -138,6 +159,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
138 // flags are agent flags sent from the viewer. 159 // flags are agent flags sent from the viewer.
139 // they have different values depending on different viewers, apparently 160 // they have different values depending on different viewers, apparently
140 remoteClient.SendMapBlock(blocks, flags); 161 remoteClient.SendMapBlock(blocks, flags);
162
163 // send extra user messages for V3
164 // because the UI is very confusing
165 // while we don't fix the hard-coded urls
166 if (flags == 2)
167 {
168 if (regionInfos.Count == 0)
169 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
170 else if (regionInfos.Count == 1)
171 remoteClient.SendAgentAlertMessage("Region found!", false);
172 }
141 } 173 }
142 174
143// private Scene GetClientScene(IClientAPI client) 175// private Scene GetClientScene(IClientAPI client)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index fd122da..faaf928 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
102 m_scene.RegisterModuleInterface<IWorldMapModule>(this); 102 m_scene.RegisterModuleInterface<IWorldMapModule>(this);
103 103
104 m_scene.AddCommand( 104 m_scene.AddCommand(
105 this, "export-map", 105 "Regions", this, "export-map",
106 "export-map [<path>]", 106 "export-map [<path>]",
107 "Save an image of the world map", HandleExportWorldMapConsoleCommand); 107 "Save an image of the world map", HandleExportWorldMapConsoleCommand);
108 108
diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
index 93648d6..2f2b3e6 100644
--- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
+++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
@@ -46,8 +46,6 @@ namespace OpenSim.Region.DataSnapshot
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 private readonly string m_discoveryPath = "DS0001/";
50
51 public DataRequestHandler(Scene scene, DataSnapshotManager externalData) 49 public DataRequestHandler(Scene scene, DataSnapshotManager externalData)
52 { 50 {
53 m_scene = scene; 51 m_scene = scene;
@@ -58,37 +56,9 @@ namespace OpenSim.Region.DataSnapshot
58 { 56 {
59 m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); 57 m_log.Info("[DATASNAPSHOT]: Set up snapshot service");
60 } 58 }
59 // Register validation callback handler
60 MainServer.Instance.AddHTTPHandler("validate", OnValidate);
61 61
62 //Register CAPS handler event
63 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
64
65 //harbl
66 }
67
68 public void OnRegisterCaps(UUID agentID, Caps caps)
69 {
70// m_log.InfoFormat("[DATASNAPSHOT]: Registering service discovery capability for {0}", agentID);
71 string capsBase = "/CAPS/" + caps.CapsObjectPath;
72 caps.RegisterHandler("PublicSnapshotDataInfo",
73 new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt));
74 }
75
76 public string OnDiscoveryAttempt(string request, string path, string param,
77 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
78 {
79 //Very static for now, flexible enough to add new formats
80 LLSDDiscoveryResponse llsd_response = new LLSDDiscoveryResponse();
81 llsd_response.snapshot_resources = new OSDArray();
82
83 LLSDDiscoveryDataURL llsd_dataurl = new LLSDDiscoveryDataURL();
84 llsd_dataurl.snapshot_format = "os-datasnapshot-v1";
85 llsd_dataurl.snapshot_url = "http://" + m_externalData.m_hostname + ":" + m_externalData.m_listener_port + "/?method=collector";
86
87 llsd_response.snapshot_resources.Array.Add(llsd_dataurl);
88
89 string response = LLSDHelpers.SerialiseLLSDReply(llsd_response);
90
91 return response;
92 } 62 }
93 63
94 public Hashtable OnGetSnapshot(Hashtable keysvals) 64 public Hashtable OnGetSnapshot(Hashtable keysvals)
@@ -107,5 +77,23 @@ namespace OpenSim.Region.DataSnapshot
107 77
108 return reply; 78 return reply;
109 } 79 }
80
81 public Hashtable OnValidate(Hashtable keysvals)
82 {
83 m_log.Info("[DATASNAPSHOT] Received validation request");
84 Hashtable reply = new Hashtable();
85 int statuscode = 200;
86
87 string secret = (string)keysvals["secret"];
88 if (secret == m_externalData.Secret.ToString())
89 statuscode = 403;
90
91 reply["str_response_string"] = string.Empty;
92 reply["int_response_code"] = statuscode;
93 reply["content_type"] = "text/plain";
94
95 return reply;
96 }
97
110 } 98 }
111} 99}
diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
index 9fc002b..5540656 100644
--- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
+++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
@@ -66,6 +66,7 @@ namespace OpenSim.Region.DataSnapshot
66 private string m_dataServices = "noservices"; 66 private string m_dataServices = "noservices";
67 public string m_listener_port = ConfigSettings.DefaultRegionHttpPort.ToString(); 67 public string m_listener_port = ConfigSettings.DefaultRegionHttpPort.ToString();
68 public string m_hostname = "127.0.0.1"; 68 public string m_hostname = "127.0.0.1";
69 private UUID m_Secret = UUID.Random();
69 70
70 //Update timers 71 //Update timers
71 private int m_period = 20; // in seconds 72 private int m_period = 20; // in seconds
@@ -85,6 +86,11 @@ namespace OpenSim.Region.DataSnapshot
85 get { return m_exposure_level; } 86 get { return m_exposure_level; }
86 } 87 }
87 88
89 public UUID Secret
90 {
91 get { return m_Secret; }
92 }
93
88 #endregion 94 #endregion
89 95
90 #region IRegionModule 96 #region IRegionModule
@@ -103,10 +109,10 @@ namespace OpenSim.Region.DataSnapshot
103 m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled); 109 m_enabled = config.Configs["DataSnapshot"].GetBoolean("index_sims", m_enabled);
104 IConfig conf = config.Configs["GridService"]; 110 IConfig conf = config.Configs["GridService"];
105 if (conf != null) 111 if (conf != null)
106 m_gridinfo.Add("gridserverURL", conf.GetString("GridServerURI", "http://127.0.0.1:8003")); 112 m_gridinfo.Add("gatekeeperURL", conf.GetString("Gatekeeper", String.Empty));
107 113
108 m_gridinfo.Add( 114 m_gridinfo.Add(
109 "Name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); 115 "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo"));
110 m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level); 116 m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level);
111 m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); 117 m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period);
112 m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); 118 m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales);
@@ -315,6 +321,7 @@ namespace OpenSim.Region.DataSnapshot
315 cli.AddQueryParameter("service", serviceName); 321 cli.AddQueryParameter("service", serviceName);
316 cli.AddQueryParameter("host", m_hostname); 322 cli.AddQueryParameter("host", m_hostname);
317 cli.AddQueryParameter("port", m_listener_port); 323 cli.AddQueryParameter("port", m_listener_port);
324 cli.AddQueryParameter("secret", m_Secret.ToString());
318 cli.RequestMethod = "GET"; 325 cli.RequestMethod = "GET";
319 try 326 try
320 { 327 {
@@ -341,7 +348,7 @@ namespace OpenSim.Region.DataSnapshot
341 } 348 }
342 // This is not quite working, so... 349 // This is not quite working, so...
343 // string responseStr = Util.UTF8.GetString(response); 350 // string responseStr = Util.UTF8.GetString(response);
344 m_log.Info("[DATASNAPSHOT]: data service notified: " + url); 351 m_log.Info("[DATASNAPSHOT]: data service " + url + " notified. Secret: " + m_Secret);
345 } 352 }
346 353
347 } 354 }
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 15060fd..1334905 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -155,6 +155,15 @@ namespace OpenSim.Region.Framework.Interfaces
155 TaskInventoryItem GetInventoryItem(UUID itemId); 155 TaskInventoryItem GetInventoryItem(UUID itemId);
156 156
157 /// <summary> 157 /// <summary>
158 /// Get all inventory items.
159 /// </summary>
160 /// <param name="name"></param>
161 /// <returns>
162 /// If there are no inventory items then an empty list is returned.
163 /// </returns>
164 List<TaskInventoryItem> GetInventoryItems();
165
166 /// <summary>
158 /// Get inventory items by name. 167 /// Get inventory items by name.
159 /// </summary> 168 /// </summary>
160 /// <param name="name"></param> 169 /// <param name="name"></param>
@@ -162,7 +171,7 @@ namespace OpenSim.Region.Framework.Interfaces
162 /// A list of inventory items with that name. 171 /// A list of inventory items with that name.
163 /// If no inventory item has that name then an empty list is returned. 172 /// If no inventory item has that name then an empty list is returned.
164 /// </returns> 173 /// </returns>
165 IList<TaskInventoryItem> GetInventoryItems(string name); 174 List<TaskInventoryItem> GetInventoryItems(string name);
166 175
167 /// <summary> 176 /// <summary>
168 /// Get the scene object referenced by an inventory item. 177 /// Get the scene object referenced by an inventory item.
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 18c45dd..9cab2e1 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31 32
32namespace OpenSim.Region.Framework.Interfaces 33namespace OpenSim.Region.Framework.Interfaces
@@ -74,5 +75,14 @@ namespace OpenSim.Region.Framework.Interfaces
74 /// Starts the processing threads. 75 /// Starts the processing threads.
75 /// </summary> 76 /// </summary>
76 void StartProcessing(); 77 void StartProcessing();
78
79 /// <summary>
80 /// Get the execution times of all scripts in each object.
81 /// </summary>
82 /// <returns>
83 /// A dictionary where the key is the root object ID of a linkset
84 /// and the value is a representative execution time in milliseconds of all scripts in that linkset.
85 /// </returns>
86 Dictionary<uint, float> GetObjectScriptsExecutionTimes();
77 } 87 }
78} 88} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
index d7fa316..bfe1e8d 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using OpenMetaverse; 30using OpenMetaverse;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
@@ -45,6 +46,18 @@ namespace OpenSim.Region.Framework.Interfaces
45 /// </summary> 46 /// </summary>
46 event ScriptCommand OnScriptCommand; 47 event ScriptCommand OnScriptCommand;
47 48
49 void RegisterScriptInvocation(object target, string method);
50 void RegisterScriptInvocation(object target, MethodInfo method);
51 void RegisterScriptInvocation(object target, string[] methods);
52 Delegate[] GetScriptInvocationList();
53
54 Delegate LookupScriptInvocation(string fname);
55 string LookupModInvocation(string fname);
56 Type[] LookupTypeSignature(string fname);
57 Type LookupReturnType(string fname);
58
59 object InvokeOperation(UUID hostId, UUID scriptId, string fname, params object[] parms);
60
48 /// <summary> 61 /// <summary>
49 /// Send a link_message event to an in-world script 62 /// Send a link_message event to an in-world script
50 /// </summary> 63 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index dafbf30..e8e375e 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -50,6 +50,11 @@ namespace OpenSim.Region.Framework.Interfaces
50 public interface IWorldComm 50 public interface IWorldComm
51 { 51 {
52 /// <summary> 52 /// <summary>
53 /// Total number of listeners
54 /// </summary>
55 int ListenerCount { get; }
56
57 /// <summary>
53 /// Create a listen event callback with the specified filters. 58 /// Create a listen event callback with the specified filters.
54 /// The parameters localID,itemID are needed to uniquely identify 59 /// The parameters localID,itemID are needed to uniquely identify
55 /// the script during 'peek' time. Parameter hostID is needed to 60 /// the script during 'peek' time. Parameter hostID is needed to
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index 9176d3d..33041e9 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -27,8 +27,10 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Framework; 30using System.Reflection;
31using log4net;
31using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework;
32 34
33using Animation = OpenSim.Framework.Animation; 35using Animation = OpenSim.Framework.Animation;
34 36
@@ -37,7 +39,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
37 [Serializable] 39 [Serializable]
38 public class AnimationSet 40 public class AnimationSet
39 { 41 {
40 public static AvatarAnimations Animations = new AvatarAnimations(); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 43
42 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation(); 44 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
43 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>(); 45 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
@@ -132,9 +134,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation
132 /// </summary> 134 /// </summary>
133 public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID) 135 public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
134 { 136 {
135 if (Animations.AnimsUUID.ContainsKey(anim)) 137// m_log.DebugFormat(
138// "[ANIMATION SET]: Setting default animation {0}, sequence number {1}, object id {2}",
139// anim, sequenceNum, objectID);
140
141 if (DefaultAvatarAnimations.AnimsUUID.ContainsKey(anim))
136 { 142 {
137 return SetDefaultAnimation(Animations.AnimsUUID[anim], sequenceNum, objectID); 143 return SetDefaultAnimation(DefaultAvatarAnimations.AnimsUUID[anim], sequenceNum, objectID);
138 } 144 }
139 return false; 145 return false;
140 } 146 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
new file mode 100644
index 0000000..c2b0468
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs
@@ -0,0 +1,108 @@
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.Collections.Generic;
29using System.Reflection;
30using System.Xml;
31using log4net;
32using OpenMetaverse;
33
34namespace OpenSim.Region.Framework.Scenes.Animation
35{
36 public class DefaultAvatarAnimations
37 {
38// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
39
40 public static readonly string DefaultAnimationsPath = "data/avataranimations.xml";
41
42 public static Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>();
43 public static Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>();
44 public static Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>();
45
46 static DefaultAvatarAnimations()
47 {
48 LoadAnimations(DefaultAnimationsPath);
49 }
50
51 /// <summary>
52 /// Load the default SL avatar animations.
53 /// </summary>
54 /// <returns></returns>
55 private static void LoadAnimations(string path)
56 {
57// Dictionary<string, UUID> animations = new Dictionary<string, UUID>();
58
59 using (XmlTextReader reader = new XmlTextReader(path))
60 {
61 XmlDocument doc = new XmlDocument();
62 doc.Load(reader);
63// if (doc.DocumentElement != null)
64// {
65 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
66 {
67 if (nod.Attributes["name"] != null)
68 {
69 string name = nod.Attributes["name"].Value;
70 UUID id = (UUID)nod.InnerText;
71 string animState = (string)nod.Attributes["state"].Value;
72
73 AnimsUUID.Add(name, id);
74 AnimsNames.Add(id, name);
75 if (animState != "")
76 AnimStateNames.Add(id, animState);
77
78// m_log.DebugFormat("[AVATAR ANIMATIONS]: Loaded {0} {1} {2}", id, name, animState);
79 }
80 }
81// }
82 }
83
84// return animations;
85 }
86
87 /// <summary>
88 /// Get the default avatar animation with the given name.
89 /// </summary>
90 /// <param name="name"></param>
91 /// <returns></returns>
92 public static UUID GetDefaultAnimation(string name)
93 {
94// m_log.DebugFormat(
95// "[AVATAR ANIMATIONS]: Looking for default avatar animation with name {0}", name);
96
97 if (AnimsUUID.ContainsKey(name))
98 {
99// m_log.DebugFormat(
100// "[AVATAR ANIMATIONS]: Found {0} {1} in GetDefaultAvatarAnimation()", AnimsUUID[name], name);
101
102 return AnimsUUID[name];
103 }
104
105 return UUID.Zero;
106 }
107 }
108} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 3584cda..f5623bd 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -97,7 +97,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
97 if (m_scenePresence.IsChildAgent) 97 if (m_scenePresence.IsChildAgent)
98 return; 98 return;
99 99
100 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); 100 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
101 // are referenced with lower case names!
102 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
101 if (animID == UUID.Zero) 103 if (animID == UUID.Zero)
102 return; 104 return;
103 105
@@ -121,7 +123,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
121 if (m_scenePresence.IsChildAgent) 123 if (m_scenePresence.IsChildAgent)
122 return; 124 return;
123 125
124 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name); 126 // XXX: For some reason, we store all animations and use them with upper case names, but in LSL animations
127 // are referenced with lower case names!
128 UUID animID = DefaultAvatarAnimations.GetDefaultAnimation(name.ToUpper());
125 if (animID == UUID.Zero) 129 if (animID == UUID.Zero)
126 return; 130 return;
127 131
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 569c235..1e1fcb7 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -138,8 +138,11 @@ namespace OpenSim.Region.Framework.Scenes
138 public event OnPermissionErrorDelegate OnPermissionError; 138 public event OnPermissionErrorDelegate OnPermissionError;
139 139
140 /// <summary> 140 /// <summary>
141 /// Fired when a new script is created. 141 /// Fired when a script is run.
142 /// </summary> 142 /// </summary>
143 /// <remarks>
144 /// Occurs after OnNewScript.
145 /// </remarks>
143 public event NewRezScript OnRezScript; 146 public event NewRezScript OnRezScript;
144 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); 147 public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
145 148
@@ -187,10 +190,16 @@ namespace OpenSim.Region.Framework.Scenes
187 190
188 public event ClientClosed OnClientClosed; 191 public event ClientClosed OnClientClosed;
189 192
190 // Fired when a script is created
191 // The indication that a new script exists in this region.
192 public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID); 193 public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
194
195 /// <summary>
196 /// Fired when a script is created.
197 /// </summary>
198 /// <remarks>
199 /// Occurs before OnRezScript
200 /// </remarks>
193 public event NewScript OnNewScript; 201 public event NewScript OnNewScript;
202
194 public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID) 203 public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
195 { 204 {
196 NewScript handlerNewScript = OnNewScript; 205 NewScript handlerNewScript = OnNewScript;
@@ -212,10 +221,16 @@ namespace OpenSim.Region.Framework.Scenes
212 } 221 }
213 } 222 }
214 223
215 //TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
216 // An indication that the script has changed.
217 public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID); 224 public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
225
226 /// <summary>
227 /// An indication that the script has changed.
228 /// </summary>
229 /// <remarks>
230 /// Triggered after the scene receives a client's upload of an updated script and has stored it in an asset.
231 /// </remarks>
218 public event UpdateScript OnUpdateScript; 232 public event UpdateScript OnUpdateScript;
233
219 public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID) 234 public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
220 { 235 {
221 UpdateScript handlerUpdateScript = OnUpdateScript; 236 UpdateScript handlerUpdateScript = OnUpdateScript;
@@ -466,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes
466 public event RegionHeartbeatEnd OnRegionHeartbeatEnd; 481 public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
467 482
468 public delegate void LoginsEnabled(string regionName); 483 public delegate void LoginsEnabled(string regionName);
484
485 /// <summary>
486 /// This should only fire in all circumstances if the RegionReady module is active.
487 /// </summary>
488 /// <remarks>
489 /// TODO: Fire this even when the RegionReady module is not active.
490 /// </remarks>
469 public event LoginsEnabled OnLoginsEnabled; 491 public event LoginsEnabled OnLoginsEnabled;
470 492
471 public delegate void PrimsLoaded(Scene s); 493 public delegate void PrimsLoaded(Scene s);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 23f39a8..5abd74f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -633,7 +633,7 @@ namespace OpenSim.Region.Framework.Scenes
633 { 633 {
634 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); 634 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
635 if (invAccess != null) 635 if (invAccess != null)
636 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); 636 Util.FireAndForget(delegate { invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); });
637 } 637 }
638 638
639 if (!Permissions.BypassPermissions()) 639 if (!Permissions.BypassPermissions())
@@ -1210,9 +1210,9 @@ namespace OpenSim.Region.Framework.Scenes
1210 /// <summary> 1210 /// <summary>
1211 /// Copy a task (prim) inventory item to another task (prim) 1211 /// Copy a task (prim) inventory item to another task (prim)
1212 /// </summary> 1212 /// </summary>
1213 /// <param name="destId"></param> 1213 /// <param name="destId">ID of destination part</param>
1214 /// <param name="part"></param> 1214 /// <param name="part">Source part</param>
1215 /// <param name="itemId"></param> 1215 /// <param name="itemId">Source item id to transfer</param>
1216 public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId) 1216 public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
1217 { 1217 {
1218 TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId); 1218 TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
@@ -1238,24 +1238,21 @@ namespace OpenSim.Region.Framework.Scenes
1238 return; 1238 return;
1239 } 1239 }
1240 1240
1241 // Can't transfer this 1241 if (part.OwnerID != destPart.OwnerID)
1242 //
1243 if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
1244 return;
1245
1246 if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1247 { 1242 {
1248 // object cannot copy items to an object owned by a different owner 1243 // Source must have transfer permissions
1249 // unless llAllowInventoryDrop has been called 1244 if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1245 return;
1250 1246
1251 return; 1247 // Object cannot copy items to an object owned by a different owner
1248 // unless llAllowInventoryDrop has been called on the destination
1249 if ((destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
1250 return;
1252 } 1251 }
1253 1252
1254 // must have both move and modify permission to put an item in an object 1253 // must have both move and modify permission to put an item in an object
1255 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) 1254 if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
1256 {
1257 return; 1255 return;
1258 }
1259 1256
1260 TaskInventoryItem destTaskItem = new TaskInventoryItem(); 1257 TaskInventoryItem destTaskItem = new TaskInventoryItem();
1261 1258
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 3355ebe..87ffc74 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -339,59 +339,6 @@ namespace OpenSim.Region.Framework.Scenes
339 EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); 339 EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg);
340 } 340 }
341 341
342 public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
343 {
344 //EventManager.TriggerAvatarPickerRequest();
345
346 List<UserAccount> accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query);
347
348 if (accounts == null)
349 return;
350
351 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
352 // TODO: don't create new blocks if recycling an old packet
353
354 AvatarPickerReplyPacket.DataBlock[] searchData =
355 new AvatarPickerReplyPacket.DataBlock[accounts.Count];
356 AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
357
358 agentData.AgentID = avatarID;
359 agentData.QueryID = RequestID;
360 replyPacket.AgentData = agentData;
361 //byte[] bytes = new byte[AvatarResponses.Count*32];
362
363 int i = 0;
364 foreach (UserAccount item in accounts)
365 {
366 UUID translatedIDtem = item.PrincipalID;
367 searchData[i] = new AvatarPickerReplyPacket.DataBlock();
368 searchData[i].AvatarID = translatedIDtem;
369 searchData[i].FirstName = Utils.StringToBytes((string) item.FirstName);
370 searchData[i].LastName = Utils.StringToBytes((string) item.LastName);
371 i++;
372 }
373 if (accounts.Count == 0)
374 {
375 searchData = new AvatarPickerReplyPacket.DataBlock[0];
376 }
377 replyPacket.Data = searchData;
378
379 AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
380 agent_data.AgentID = replyPacket.AgentData.AgentID;
381 agent_data.QueryID = replyPacket.AgentData.QueryID;
382
383 List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
384 for (i = 0; i < replyPacket.Data.Length; i++)
385 {
386 AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
387 data_arg.AvatarID = replyPacket.Data[i].AvatarID;
388 data_arg.FirstName = replyPacket.Data[i].FirstName;
389 data_arg.LastName = replyPacket.Data[i].LastName;
390 data_args.Add(data_arg);
391 }
392 client.SendAvatarPickerReply(agent_data, data_args);
393 }
394
395 public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, 342 public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
396 UUID itemID) 343 UUID itemID)
397 { 344 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 292c81f..0b31e0c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -65,7 +65,16 @@ namespace OpenSim.Region.Framework.Scenes
65 #region Fields 65 #region Fields
66 66
67 public bool EmergencyMonitoring = false; 67 public bool EmergencyMonitoring = false;
68 public bool DEBUG = false; 68
69 /// <summary>
70 /// Show debug information about teleports.
71 /// </summary>
72 public bool DebugTeleporting { get; private set; }
73
74 /// <summary>
75 /// Show debug information about the scene loop.
76 /// </summary>
77 public bool DebugUpdates { get; private set; }
69 78
70 public SynchronizeSceneHandler SynchronizeScene; 79 public SynchronizeSceneHandler SynchronizeScene;
71 public SimStatsReporter StatsReporter; 80 public SimStatsReporter StatsReporter;
@@ -95,6 +104,11 @@ namespace OpenSim.Region.Framework.Scenes
95 public bool m_allowScriptCrossings; 104 public bool m_allowScriptCrossings;
96 public bool m_useFlySlow; 105 public bool m_useFlySlow;
97 106
107 /// <summary>
108 /// Temporarily setting to trigger appearance resends at 60 second intervals.
109 /// </summary>
110 public bool SendPeriodicAppearanceUpdates { get; set; }
111
98 protected float m_defaultDrawDistance = 255.0f; 112 protected float m_defaultDrawDistance = 255.0f;
99 public float DefaultDrawDistance 113 public float DefaultDrawDistance
100 { 114 {
@@ -160,6 +174,11 @@ namespace OpenSim.Region.Framework.Scenes
160 } 174 }
161 175
162 /// <summary> 176 /// <summary>
177 /// Current maintenance run number
178 /// </summary>
179 public uint MaintenanceRun { get; private set; }
180
181 /// <summary>
163 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we 182 /// The minimum length of time in seconds that will be taken for a scene frame. If the frame takes less time then we
164 /// will sleep for the remaining period. 183 /// will sleep for the remaining period.
165 /// </summary> 184 /// </summary>
@@ -169,6 +188,11 @@ namespace OpenSim.Region.Framework.Scenes
169 /// </remarks> 188 /// </remarks>
170 public float MinFrameTime { get; private set; } 189 public float MinFrameTime { get; private set; }
171 190
191 /// <summary>
192 /// The minimum length of time in seconds that will be taken for a maintenance run.
193 /// </summary>
194 public float MinMaintenanceTime { get; private set; }
195
172 private int m_update_physics = 1; 196 private int m_update_physics = 1;
173 private int m_update_entitymovement = 1; 197 private int m_update_entitymovement = 1;
174 private int m_update_objects = 1; 198 private int m_update_objects = 1;
@@ -190,7 +214,16 @@ namespace OpenSim.Region.Framework.Scenes
190 private int backupMS; 214 private int backupMS;
191 private int terrainMS; 215 private int terrainMS;
192 private int landMS; 216 private int landMS;
193 private int lastCompletedFrame; 217
218 /// <summary>
219 /// Tick at which the last frame was processed.
220 /// </summary>
221 private int m_lastFrameTick;
222
223 /// <summary>
224 /// Tick at which the last maintenance run occurred.
225 /// </summary>
226 private int m_lastMaintenanceTick;
194 227
195 /// <summary> 228 /// <summary>
196 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 229 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
@@ -198,14 +231,12 @@ namespace OpenSim.Region.Framework.Scenes
198 /// </summary> 231 /// </summary>
199 private bool m_cleaningTemps = false; 232 private bool m_cleaningTemps = false;
200 233
201 private Object m_heartbeatLock = new Object(); 234// private Object m_heartbeatLock = new Object();
202 235
203 // TODO: Possibly stop other classes being able to manipulate this directly. 236 // TODO: Possibly stop other classes being able to manipulate this directly.
204 private SceneGraph m_sceneGraph; 237 private SceneGraph m_sceneGraph;
205 private volatile int m_bordersLocked; 238 private volatile int m_bordersLocked;
206// private int m_RestartTimerCounter;
207 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 239 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
208// private int m_incrementsof15seconds;
209 private volatile bool m_backingup; 240 private volatile bool m_backingup;
210 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 241 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
211 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>(); 242 private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
@@ -213,14 +244,28 @@ namespace OpenSim.Region.Framework.Scenes
213 private bool m_physics_enabled = true; 244 private bool m_physics_enabled = true;
214 private bool m_scripts_enabled = true; 245 private bool m_scripts_enabled = true;
215 private string m_defaultScriptEngine; 246 private string m_defaultScriptEngine;
247
248 /// <summary>
249 /// Tick at which the last login occurred.
250 /// </summary>
216 private int m_LastLogin; 251 private int m_LastLogin;
217 private Thread HeartbeatThread;
218 private volatile bool shuttingdown;
219 252
220 private int m_lastUpdate; 253 /// <summary>
221 private bool m_firstHeartbeat = true; 254 /// Thread that runs the scene loop.
255 /// </summary>
256 private Thread m_heartbeatThread;
222 257
223 private object m_deleting_scene_object = new object(); 258 /// <summary>
259 /// True if these scene is in the process of shutting down or is shutdown.
260 /// </summary>
261 public bool ShuttingDown
262 {
263 get { return m_shuttingDown; }
264 }
265 private volatile bool m_shuttingDown;
266
267// private int m_lastUpdate;
268// private bool m_firstHeartbeat = true;
224 269
225 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; 270 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
226 private bool m_reprioritizationEnabled = true; 271 private bool m_reprioritizationEnabled = true;
@@ -466,7 +511,7 @@ namespace OpenSim.Region.Framework.Scenes
466 public int MonitorBackupTime { get { return backupMS; } } 511 public int MonitorBackupTime { get { return backupMS; } }
467 public int MonitorTerrainTime { get { return terrainMS; } } 512 public int MonitorTerrainTime { get { return terrainMS; } }
468 public int MonitorLandTime { get { return landMS; } } 513 public int MonitorLandTime { get { return landMS; } }
469 public int MonitorLastFrameTick { get { return lastCompletedFrame; } } 514 public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
470 515
471 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } 516 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
472 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } 517 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@@ -535,6 +580,7 @@ namespace OpenSim.Region.Framework.Scenes
535 { 580 {
536 m_config = config; 581 m_config = config;
537 MinFrameTime = 0.089f; 582 MinFrameTime = 0.089f;
583 MinMaintenanceTime = 1;
538 584
539 Random random = new Random(); 585 Random random = new Random();
540 586
@@ -596,7 +642,7 @@ namespace OpenSim.Region.Framework.Scenes
596 642
597 #endregion Region Settings 643 #endregion Region Settings
598 644
599 MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", 645 MainConsole.Instance.Commands.AddCommand("Estates", false, "reload estate",
600 "reload estate", 646 "reload estate",
601 "Reload the estate data", HandleReloadEstate); 647 "Reload the estate data", HandleReloadEstate);
602 648
@@ -628,10 +674,10 @@ namespace OpenSim.Region.Framework.Scenes
628 674
629 #region Region Config 675 #region Region Config
630 676
631 try 677 // Region config overrides global config
678 //
679 if (m_config.Configs["Startup"] != null)
632 { 680 {
633 // Region config overrides global config
634 //
635 IConfig startupConfig = m_config.Configs["Startup"]; 681 IConfig startupConfig = m_config.Configs["Startup"];
636 682
637 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance); 683 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
@@ -720,47 +766,42 @@ namespace OpenSim.Region.Framework.Scenes
720 m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences); 766 m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
721 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain); 767 m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
722 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning); 768 m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
723 } 769
724 catch 770 SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
725 {
726 m_log.Warn("[SCENE]: Failed to load StartupConfig");
727 } 771 }
728 772
729 #endregion Region Config 773 #endregion Region Config
730 774
731 #region Interest Management 775 #region Interest Management
732 776
733 if (m_config != null) 777 IConfig interestConfig = m_config.Configs["InterestManagement"];
778 if (interestConfig != null)
734 { 779 {
735 IConfig interestConfig = m_config.Configs["InterestManagement"]; 780 string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
736 if (interestConfig != null)
737 {
738 string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
739 781
740 try 782 try
741 { 783 {
742 m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true); 784 m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
743 } 785 }
744 catch (Exception) 786 catch (Exception)
745 { 787 {
746 m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time"); 788 m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
747 m_priorityScheme = UpdatePrioritizationSchemes.Time; 789 m_priorityScheme = UpdatePrioritizationSchemes.Time;
748 }
749
750 m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
751 m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
752 m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
753 m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
754 } 790 }
791
792 m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
793 m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
794 m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
795 m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
755 } 796 }
756 797
757 m_log.InfoFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme); 798 m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", m_priorityScheme);
758 799
759 #endregion Interest Management 800 #endregion Interest Management
760 801
761 StatsReporter = new SimStatsReporter(this); 802 StatsReporter = new SimStatsReporter(this);
762 StatsReporter.OnSendStatsResult += SendSimStatsPackets; 803 StatsReporter.OnSendStatsResult += SendSimStatsPackets;
763 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; 804 StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
764 } 805 }
765 806
766 /// <summary> 807 /// <summary>
@@ -797,18 +838,13 @@ namespace OpenSim.Region.Framework.Scenes
797 838
798 m_permissions = new ScenePermissions(this); 839 m_permissions = new ScenePermissions(this);
799 840
800 m_lastUpdate = Util.EnvironmentTickCount(); 841// m_lastUpdate = Util.EnvironmentTickCount();
801 } 842 }
802 843
803 #endregion 844 #endregion
804 845
805 #region Startup / Close Methods 846 #region Startup / Close Methods
806 847
807 public bool ShuttingDown
808 {
809 get { return shuttingdown; }
810 }
811
812 /// <value> 848 /// <value>
813 /// The scene graph for this scene 849 /// The scene graph for this scene
814 /// </value> 850 /// </value>
@@ -1025,44 +1061,72 @@ namespace OpenSim.Region.Framework.Scenes
1025 } 1061 }
1026 } 1062 }
1027 1063
1028 public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine) 1064 public void SetSceneCoreDebug(Dictionary<string, string> options)
1029 { 1065 {
1030 if (m_scripts_enabled != !ScriptEngine) 1066 if (options.ContainsKey("scripting"))
1031 { 1067 {
1032 if (ScriptEngine) 1068 bool enableScripts = true;
1069 if (bool.TryParse(options["scripting"], out enableScripts) && m_scripts_enabled != enableScripts)
1033 { 1070 {
1034 m_log.Info("Stopping all Scripts in Scene"); 1071 if (!enableScripts)
1035
1036 EntityBase[] entities = Entities.GetEntities();
1037 foreach (EntityBase ent in entities)
1038 { 1072 {
1039 if (ent is SceneObjectGroup) 1073 m_log.Info("Stopping all Scripts in Scene");
1040 ((SceneObjectGroup)ent).RemoveScriptInstances(false); 1074
1075 EntityBase[] entities = Entities.GetEntities();
1076 foreach (EntityBase ent in entities)
1077 {
1078 if (ent is SceneObjectGroup)
1079 ((SceneObjectGroup)ent).RemoveScriptInstances(false);
1080 }
1041 } 1081 }
1042 } 1082 else
1043 else
1044 {
1045 m_log.Info("Starting all Scripts in Scene");
1046
1047 EntityBase[] entities = Entities.GetEntities();
1048 foreach (EntityBase ent in entities)
1049 { 1083 {
1050 if (ent is SceneObjectGroup) 1084 m_log.Info("Starting all Scripts in Scene");
1085
1086 EntityBase[] entities = Entities.GetEntities();
1087 foreach (EntityBase ent in entities)
1051 { 1088 {
1052 SceneObjectGroup sog = (SceneObjectGroup)ent; 1089 if (ent is SceneObjectGroup)
1053 sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0); 1090 {
1054 sog.ResumeScripts(); 1091 SceneObjectGroup sog = (SceneObjectGroup)ent;
1092 sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
1093 sog.ResumeScripts();
1094 }
1055 } 1095 }
1056 } 1096 }
1097
1098 m_scripts_enabled = enableScripts;
1057 } 1099 }
1100 }
1101
1102 if (options.ContainsKey("physics"))
1103 {
1104 bool enablePhysics;
1105 if (bool.TryParse(options["physics"], out enablePhysics))
1106 m_physics_enabled = enablePhysics;
1107 }
1108
1109// if (options.ContainsKey("collisions"))
1110// {
1111// // TODO: Implement. If false, should stop objects colliding, though possibly should still allow
1112// // the avatar themselves to collide with the ground.
1113// }
1058 1114
1059 m_scripts_enabled = !ScriptEngine; 1115 if (options.ContainsKey("teleport"))
1060 m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine"); 1116 {
1117 bool enableTeleportDebugging;
1118 if (bool.TryParse(options["teleport"], out enableTeleportDebugging))
1119 DebugTeleporting = enableTeleportDebugging;
1061 } 1120 }
1062 1121
1063 if (m_physics_enabled != !PhysicsEngine) 1122 if (options.ContainsKey("updates"))
1064 { 1123 {
1065 m_physics_enabled = !PhysicsEngine; 1124 bool enableUpdateDebugging;
1125 if (bool.TryParse(options["updates"], out enableUpdateDebugging))
1126 {
1127 DebugUpdates = enableUpdateDebugging;
1128 GcNotify.Enabled = DebugUpdates;
1129 }
1066 } 1130 }
1067 } 1131 }
1068 1132
@@ -1076,6 +1140,8 @@ namespace OpenSim.Region.Framework.Scenes
1076 { 1140 {
1077 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName); 1141 m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1078 1142
1143 StatsReporter.Close();
1144
1079 m_restartTimer.Stop(); 1145 m_restartTimer.Stop();
1080 m_restartTimer.Close(); 1146 m_restartTimer.Close();
1081 1147
@@ -1097,8 +1163,7 @@ namespace OpenSim.Region.Framework.Scenes
1097 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); 1163 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
1098 1164
1099 // Stop updating the scene objects and agents. 1165 // Stop updating the scene objects and agents.
1100 //m_heartbeatTimer.Close(); 1166 m_shuttingDown = true;
1101 shuttingdown = true;
1102 1167
1103 m_log.Debug("[SCENE]: Persisting changed objects"); 1168 m_log.Debug("[SCENE]: Persisting changed objects");
1104 EventManager.TriggerSceneShuttingDown(this); 1169 EventManager.TriggerSceneShuttingDown(this);
@@ -1122,23 +1187,23 @@ namespace OpenSim.Region.Framework.Scenes
1122 } 1187 }
1123 1188
1124 /// <summary> 1189 /// <summary>
1125 /// Start the timer which triggers regular scene updates 1190 /// Start the scene
1126 /// </summary> 1191 /// </summary>
1127 public void StartTimer() 1192 public void Start()
1128 { 1193 {
1129// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName); 1194// m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1130 1195
1131 //m_heartbeatTimer.Enabled = true; 1196 //m_heartbeatTimer.Enabled = true;
1132 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000); 1197 //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
1133 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); 1198 //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
1134 if (HeartbeatThread != null) 1199 if (m_heartbeatThread != null)
1135 { 1200 {
1136 HeartbeatThread.Abort(); 1201 m_heartbeatThread.Abort();
1137 HeartbeatThread = null; 1202 m_heartbeatThread = null;
1138 } 1203 }
1139 m_lastUpdate = Util.EnvironmentTickCount(); 1204// m_lastUpdate = Util.EnvironmentTickCount();
1140 1205
1141 HeartbeatThread 1206 m_heartbeatThread
1142 = Watchdog.StartThread( 1207 = Watchdog.StartThread(
1143 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1208 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1144 } 1209 }
@@ -1169,222 +1234,296 @@ namespace OpenSim.Region.Framework.Scenes
1169 /// </summary> 1234 /// </summary>
1170 private void Heartbeat() 1235 private void Heartbeat()
1171 { 1236 {
1172 if (!Monitor.TryEnter(m_heartbeatLock)) 1237// if (!Monitor.TryEnter(m_heartbeatLock))
1173 { 1238// {
1174 Watchdog.RemoveThread(); 1239// Watchdog.RemoveThread();
1175 return; 1240// return;
1176 } 1241// }
1177 1242
1178 try 1243// try
1179 { 1244// {
1180 m_eventManager.TriggerOnRegionStarted(this);
1181 1245
1182 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1246 m_eventManager.TriggerOnRegionStarted(this);
1183 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1184 // alarms for scenes with many objects.
1185 Update();
1186 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1187 1247
1188 while (!shuttingdown) 1248 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1189 Update(); 1249 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1250 // alarms for scenes with many objects.
1251 Update(1);
1190 1252
1191 m_lastUpdate = Util.EnvironmentTickCount(); 1253 Watchdog.StartThread(
1192 m_firstHeartbeat = false; 1254 Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1193 } 1255
1194 catch (ThreadAbortException) 1256 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1195 { 1257 Update(-1);
1196 } 1258
1197 finally 1259// m_lastUpdate = Util.EnvironmentTickCount();
1198 { 1260// m_firstHeartbeat = false;
1199 Monitor.Pulse(m_heartbeatLock); 1261// }
1200 Monitor.Exit(m_heartbeatLock); 1262// finally
1201 } 1263// {
1264// Monitor.Pulse(m_heartbeatLock);
1265// Monitor.Exit(m_heartbeatLock);
1266// }
1202 1267
1203 Watchdog.RemoveThread(); 1268 Watchdog.RemoveThread();
1204 } 1269 }
1205 1270
1206 public override void Update() 1271 private void Maintenance()
1207 { 1272 {
1208 float physicsFPS = 0f; 1273 DoMaintenance(-1);
1209
1210 int maintc = Util.EnvironmentTickCount();
1211 int tmpFrameMS = maintc;
1212 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1213
1214 ++Frame;
1215
1216// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1217 1274
1218 try 1275 Watchdog.RemoveThread();
1219 { 1276 }
1220 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1221 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1222 m_sceneGraph.UpdatePreparePhysics();
1223 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1224
1225 // Apply any pending avatar force input to the avatar's velocity
1226 int tmpAgentMS = Util.EnvironmentTickCount();
1227 if (Frame % m_update_entitymovement == 0)
1228 m_sceneGraph.UpdateScenePresenceMovement();
1229 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1230
1231 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1232 // velocity
1233 int tmpPhysicsMS = Util.EnvironmentTickCount();
1234 if (Frame % m_update_physics == 0)
1235 {
1236 if (m_physics_enabled)
1237 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1238
1239 if (SynchronizeScene != null)
1240 SynchronizeScene(this);
1241 }
1242 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1243 1277
1244 tmpAgentMS = Util.EnvironmentTickCount(); 1278 public void DoMaintenance(int runs)
1279 {
1280 long? endRun = null;
1281 int runtc;
1282 int previousMaintenanceTick;
1245 1283
1246 // Check if any objects have reached their targets 1284 if (runs >= 0)
1247 CheckAtTargets(); 1285 endRun = MaintenanceRun + runs;
1248 1286
1249 // Update SceneObjectGroups that have scheduled themselves for updates 1287 List<Vector3> coarseLocations;
1250 // Objects queue their updates onto all scene presences 1288 List<UUID> avatarUUIDs;
1251 if (Frame % m_update_objects == 0)
1252 m_sceneGraph.UpdateObjectGroups();
1253 1289
1254 // Run through all ScenePresences looking for updates 1290 while (!m_shuttingDown && (endRun == null || MaintenanceRun < endRun))
1255 // Presence updates and queued object updates for each presence are sent to clients 1291 {
1256 if (Frame % m_update_presences == 0) 1292 runtc = Util.EnvironmentTickCount();
1257 m_sceneGraph.UpdatePresences(); 1293 ++MaintenanceRun;
1258 1294
1259 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1295 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1260 if (Frame % m_update_coarse_locations == 0) 1296 if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
1261 { 1297 {
1262 List<Vector3> coarseLocations;
1263 List<UUID> avatarUUIDs;
1264 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); 1298 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1265 // Send coarse locations to clients 1299 // Send coarse locations to clients
1266 ForEachScenePresence(delegate(ScenePresence presence) 1300 ForEachScenePresence(delegate(ScenePresence presence)
1267 { 1301 {
1268 presence.SendCoarseLocations(coarseLocations, avatarUUIDs); 1302 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1269 }); 1303 });
1270 } 1304 }
1271 1305
1272 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1306 if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
1273
1274 // Delete temp-on-rez stuff
1275 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1276 { 1307 {
1277 int tmpTempOnRezMS = Util.EnvironmentTickCount(); 1308// m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
1278 m_cleaningTemps = true;
1279 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1280 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1281 }
1282 1309
1283 if (Frame % m_update_events == 0) 1310 if (AvatarFactory != null)
1284 { 1311 {
1285 int evMS = Util.EnvironmentTickCount(); 1312 ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID));
1286 UpdateEvents(); 1313 }
1287 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1288 } 1314 }
1289 1315
1290 if (Frame % m_update_backup == 0) 1316 Watchdog.UpdateThread();
1291 {
1292 int backMS = Util.EnvironmentTickCount();
1293 UpdateStorageBackup();
1294 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1295 }
1296 1317
1297 if (Frame % m_update_terrain == 0) 1318 previousMaintenanceTick = m_lastMaintenanceTick;
1298 { 1319 m_lastMaintenanceTick = Util.EnvironmentTickCount();
1299 int terMS = Util.EnvironmentTickCount(); 1320 runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1300 UpdateTerrain(); 1321 runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1301 terrainMS = Util.EnvironmentTickCountSubtract(terMS); 1322
1302 } 1323 if (runtc > 0)
1324 Thread.Sleep(runtc);
1325
1326 // Optionally warn if a frame takes double the amount of time that it should.
1327 if (DebugUpdates
1328 && Util.EnvironmentTickCountSubtract(
1329 m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
1330 m_log.WarnFormat(
1331 "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1332 Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1333 MinMaintenanceTime * 1000,
1334 RegionInfo.RegionName);
1335 }
1336 }
1337
1338 public override void Update(int frames)
1339 {
1340 long? endFrame = null;
1341
1342 if (frames >= 0)
1343 endFrame = Frame + frames;
1303 1344
1304 //if (Frame % m_update_land == 0) 1345 float physicsFPS = 0f;
1305 //{ 1346 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1306 // int ldMS = Util.EnvironmentTickCount(); 1347 int previousFrameTick;
1307 // UpdateLand(); 1348 int maintc;
1308 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1349
1309 //} 1350 while (!m_shuttingDown && (endFrame == null || Frame < endFrame))
1310 1351 {
1311 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); 1352 maintc = Util.EnvironmentTickCount();
1312 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1353 ++Frame;
1313 lastCompletedFrame = Util.EnvironmentTickCount(); 1354
1314 1355// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1315 // if (Frame%m_update_avatars == 0) 1356
1316 // UpdateInWorldTime(); 1357 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1317 StatsReporter.AddPhysicsFPS(physicsFPS); 1358
1318 StatsReporter.AddTimeDilation(TimeDilation); 1359 try
1319 StatsReporter.AddFPS(1);
1320 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1321 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1322 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1323 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1324 StatsReporter.addFrameMS(frameMS);
1325 StatsReporter.addAgentMS(agentMS);
1326 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1327 StatsReporter.addOtherMS(otherMS);
1328 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1329 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1330
1331 if (LoginsDisabled && Frame == 20)
1332 { 1360 {
1333// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock); 1361 tmpPhysicsMS2 = Util.EnvironmentTickCount();
1362 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1363 m_sceneGraph.UpdatePreparePhysics();
1364 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1365
1366 // Apply any pending avatar force input to the avatar's velocity
1367 tmpAgentMS = Util.EnvironmentTickCount();
1368 if (Frame % m_update_entitymovement == 0)
1369 m_sceneGraph.UpdateScenePresenceMovement();
1370 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1371
1372 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1373 // velocity
1374 tmpPhysicsMS = Util.EnvironmentTickCount();
1375 if (Frame % m_update_physics == 0)
1376 {
1377 if (m_physics_enabled)
1378 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1379
1380 if (SynchronizeScene != null)
1381 SynchronizeScene(this);
1382 }
1383 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1334 1384
1335 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1385 tmpAgentMS = Util.EnvironmentTickCount();
1336 // this is a rare case where we know we have just went through a long cycle of heap 1386
1337 // allocations, and there is no more work to be done until someone logs in 1387 // Check if any objects have reached their targets
1338 GC.Collect(); 1388 CheckAtTargets();
1389
1390 // Update SceneObjectGroups that have scheduled themselves for updates
1391 // Objects queue their updates onto all scene presences
1392 if (Frame % m_update_objects == 0)
1393 m_sceneGraph.UpdateObjectGroups();
1394
1395 // Run through all ScenePresences looking for updates
1396 // Presence updates and queued object updates for each presence are sent to clients
1397 if (Frame % m_update_presences == 0)
1398 m_sceneGraph.UpdatePresences();
1399
1400 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
1401
1402 // Delete temp-on-rez stuff
1403 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1404 {
1405 tmpTempOnRezMS = Util.EnvironmentTickCount();
1406 m_cleaningTemps = true;
1407 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1408 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1409 }
1410
1411 if (Frame % m_update_events == 0)
1412 {
1413 evMS = Util.EnvironmentTickCount();
1414 UpdateEvents();
1415 eventMS = Util.EnvironmentTickCountSubtract(evMS);
1416 }
1417
1418 if (Frame % m_update_backup == 0)
1419 {
1420 backMS = Util.EnvironmentTickCount();
1421 UpdateStorageBackup();
1422 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1423 }
1424
1425 if (Frame % m_update_terrain == 0)
1426 {
1427 terMS = Util.EnvironmentTickCount();
1428 UpdateTerrain();
1429 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1430 }
1431
1432 //if (Frame % m_update_land == 0)
1433 //{
1434 // int ldMS = Util.EnvironmentTickCount();
1435 // UpdateLand();
1436 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1437 //}
1339 1438
1340 IConfig startupConfig = m_config.Configs["Startup"]; 1439 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1341 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1440 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1441
1442 // if (Frame%m_update_avatars == 0)
1443 // UpdateInWorldTime();
1444 StatsReporter.AddPhysicsFPS(physicsFPS);
1445 StatsReporter.AddTimeDilation(TimeDilation);
1446 StatsReporter.AddFPS(1);
1447 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1448 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1449 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1450 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1451
1452 // frameMS currently records work frame times, not total frame times (work + any required sleep to
1453 // reach min frame time.
1454 StatsReporter.addFrameMS(frameMS);
1455
1456 StatsReporter.addAgentMS(agentMS);
1457 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1458 StatsReporter.addOtherMS(otherMS);
1459 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1460 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1461
1462 if (LoginsDisabled && Frame == 20)
1342 { 1463 {
1343 // This handles a case of a region having no scripts for the RegionReady module 1464 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1344 if (m_sceneGraph.GetActiveScriptsCount() == 0) 1465
1466 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1467 // this is a rare case where we know we have just went through a long cycle of heap
1468 // allocations, and there is no more work to be done until someone logs in
1469 GC.Collect();
1470
1471 IConfig startupConfig = m_config.Configs["Startup"];
1472 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1345 { 1473 {
1346 // need to be able to tell these have changed in RegionReady 1474 // This handles a case of a region having no scripts for the RegionReady module
1347 LoginLock = false; 1475 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1348 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); 1476 {
1477 // need to be able to tell these have changed in RegionReady
1478 LoginLock = false;
1479 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1480 }
1481 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1482
1483 // For RegionReady lockouts
1484 if(LoginLock == false)
1485 {
1486 LoginsDisabled = false;
1487 }
1488
1489 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1349 } 1490 }
1350 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1491 else
1351
1352 // For RegionReady lockouts
1353 if(LoginLock == false)
1354 { 1492 {
1355 LoginsDisabled = false; 1493 StartDisabled = true;
1494 LoginsDisabled = true;
1356 } 1495 }
1357
1358 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1359 }
1360 else
1361 {
1362 StartDisabled = true;
1363 LoginsDisabled = true;
1364 } 1496 }
1365 } 1497 }
1366 } 1498 catch (Exception e)
1367 catch (NotImplementedException) 1499 {
1368 { 1500 m_log.ErrorFormat(
1369 throw; 1501 "[SCENE]: Failed on region {0} with exception {1}{2}",
1370 } 1502 RegionInfo.RegionName, e.Message, e.StackTrace);
1371 catch (Exception e) 1503 }
1372 { 1504
1373 m_log.ErrorFormat( 1505 EventManager.TriggerRegionHeartbeatEnd(this);
1374 "[SCENE]: Failed on region {0} with exception {1}{2}",
1375 RegionInfo.RegionName, e.Message, e.StackTrace);
1376 }
1377 1506
1378 EventManager.TriggerRegionHeartbeatEnd(this); 1507 Watchdog.UpdateThread();
1379 1508
1380 maintc = Util.EnvironmentTickCountSubtract(maintc); 1509 previousFrameTick = m_lastFrameTick;
1381 maintc = (int)(MinFrameTime * 1000) - maintc; 1510 m_lastFrameTick = Util.EnvironmentTickCount();
1511 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1512 maintc = (int)(MinFrameTime * 1000) - maintc;
1382 1513
1383 if (maintc > 0) 1514 if (maintc > 0)
1384 Thread.Sleep(maintc); 1515 Thread.Sleep(maintc);
1385 1516
1386 // Tell the watchdog that this thread is still alive 1517 // Optionally warn if a frame takes double the amount of time that it should.
1387 Watchdog.UpdateThread(); 1518 if (DebugUpdates
1519 && Util.EnvironmentTickCountSubtract(
1520 m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
1521 m_log.WarnFormat(
1522 "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1523 Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1524 MinFrameTime * 1000,
1525 RegionInfo.RegionName);
1526 }
1388 } 1527 }
1389 1528
1390 public void AddGroupTarget(SceneObjectGroup grp) 1529 public void AddGroupTarget(SceneObjectGroup grp)
@@ -1583,8 +1722,15 @@ namespace OpenSim.Region.Framework.Scenes
1583 double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); 1722 double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID);
1584 if (map == null) 1723 if (map == null)
1585 { 1724 {
1586 m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain."); 1725 // This should be in the Terrain module, but it isn't because
1587 Heightmap = new TerrainChannel(); 1726 // the heightmap is needed _way_ before the modules are initialized...
1727 IConfig terrainConfig = m_config.Configs["Terrain"];
1728 String m_InitialTerrain = "pinhead-island";
1729 if (terrainConfig != null)
1730 m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
1731
1732 m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
1733 Heightmap = new TerrainChannel(m_InitialTerrain);
1588 1734
1589 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1735 SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1590 } 1736 }
@@ -1999,15 +2145,8 @@ namespace OpenSim.Region.Framework.Scenes
1999 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 2145 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2000 { 2146 {
2001// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2147// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2002
2003 //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
2004 2148
2005 // Serialise calls to RemoveScriptInstances to avoid 2149 group.RemoveScriptInstances(true);
2006 // deadlocking on m_parts inside SceneObjectGroup
2007 lock (m_deleting_scene_object)
2008 {
2009 group.RemoveScriptInstances(true);
2010 }
2011 2150
2012 SceneObjectPart[] partList = group.Parts; 2151 SceneObjectPart[] partList = group.Parts;
2013 2152
@@ -2489,7 +2628,7 @@ namespace OpenSim.Region.Framework.Scenes
2489 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 2628 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2490 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2629 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2491 2630
2492 CheckHeartbeat(); 2631// CheckHeartbeat();
2493 2632
2494 ScenePresence sp = GetScenePresence(client.AgentId); 2633 ScenePresence sp = GetScenePresence(client.AgentId);
2495 2634
@@ -2536,6 +2675,14 @@ namespace OpenSim.Region.Framework.Scenes
2536 // Cache the user's name 2675 // Cache the user's name
2537 CacheUserName(sp, aCircuit); 2676 CacheUserName(sp, aCircuit);
2538 2677
2678 // Let's send the Suitcase folder for incoming HG agents
2679 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
2680 {
2681 m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
2682 InventoryFolderBase suitcase = InventoryService.GetRootFolder(client.AgentId);
2683 client.SendBulkUpdateInventory(suitcase);
2684 }
2685
2539 EventManager.TriggerOnNewClient(client); 2686 EventManager.TriggerOnNewClient(client);
2540 if (vialogin) 2687 if (vialogin)
2541 EventManager.TriggerOnClientLogin(client); 2688 EventManager.TriggerOnClientLogin(client);
@@ -2774,7 +2921,6 @@ namespace OpenSim.Region.Framework.Scenes
2774 { 2921 {
2775 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 2922 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
2776 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 2923 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
2777 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
2778 client.OnSetStartLocationRequest += SetHomeRezPoint; 2924 client.OnSetStartLocationRequest += SetHomeRezPoint;
2779 client.OnRegionHandleRequest += RegionHandleRequest; 2925 client.OnRegionHandleRequest += RegionHandleRequest;
2780 } 2926 }
@@ -2900,7 +3046,6 @@ namespace OpenSim.Region.Framework.Scenes
2900 { 3046 {
2901 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 3047 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
2902 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 3048 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
2903 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
2904 client.OnSetStartLocationRequest -= SetHomeRezPoint; 3049 client.OnSetStartLocationRequest -= SetHomeRezPoint;
2905 client.OnRegionHandleRequest -= RegionHandleRequest; 3050 client.OnRegionHandleRequest -= RegionHandleRequest;
2906 } 3051 }
@@ -3067,7 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
3067 3212
3068 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3213 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3069 { 3214 {
3070 CheckHeartbeat(); 3215// CheckHeartbeat();
3071 bool isChildAgent = false; 3216 bool isChildAgent = false;
3072 ScenePresence avatar = GetScenePresence(agentID); 3217 ScenePresence avatar = GetScenePresence(agentID);
3073 if (avatar != null) 3218 if (avatar != null)
@@ -3540,8 +3685,8 @@ namespace OpenSim.Region.Framework.Scenes
3540 if (!AuthorizationService.IsAuthorizedForRegion( 3685 if (!AuthorizationService.IsAuthorizedForRegion(
3541 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) 3686 agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
3542 { 3687 {
3543 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", 3688 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because {4}",
3544 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 3689 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason);
3545 3690
3546 return false; 3691 return false;
3547 } 3692 }
@@ -4156,16 +4301,11 @@ namespace OpenSim.Region.Framework.Scenes
4156 public bool PipeEventsForScript(uint localID) 4301 public bool PipeEventsForScript(uint localID)
4157 { 4302 {
4158 SceneObjectPart part = GetSceneObjectPart(localID); 4303 SceneObjectPart part = GetSceneObjectPart(localID);
4304
4159 if (part != null) 4305 if (part != null)
4160 { 4306 {
4161 // Changed so that child prims of attachments return ScriptDanger for their parent, so that
4162 // their scripts will actually run.
4163 // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
4164 SceneObjectPart parent = part.ParentGroup.RootPart; 4307 SceneObjectPart parent = part.ParentGroup.RootPart;
4165 if (part.ParentGroup.IsAttachment) 4308 return ScriptDanger(parent, parent.GetWorldPosition());
4166 return ScriptDanger(parent, parent.GetWorldPosition());
4167 else
4168 return ScriptDanger(part, part.GetWorldPosition());
4169 } 4309 }
4170 else 4310 else
4171 { 4311 {
@@ -4459,8 +4599,8 @@ namespace OpenSim.Region.Framework.Scenes
4459 // 4599 //
4460 int health=1; // Start at 1, means we're up 4600 int health=1; // Start at 1, means we're up
4461 4601
4462 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) 4602 if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
4463 health+=1; 4603 health += 1;
4464 else 4604 else
4465 return health; 4605 return health;
4466 4606
@@ -4471,7 +4611,7 @@ namespace OpenSim.Region.Framework.Scenes
4471 else 4611 else
4472 return health; 4612 return health;
4473 4613
4474 CheckHeartbeat(); 4614// CheckHeartbeat();
4475 4615
4476 return health; 4616 return health;
4477 } 4617 }
@@ -4659,14 +4799,14 @@ namespace OpenSim.Region.Framework.Scenes
4659 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z; 4799 return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
4660 } 4800 }
4661 4801
4662 private void CheckHeartbeat() 4802// private void CheckHeartbeat()
4663 { 4803// {
4664 if (m_firstHeartbeat) 4804// if (m_firstHeartbeat)
4665 return; 4805// return;
4666 4806//
4667 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4807// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick) > 2000)
4668 StartTimer(); 4808// StartTimer();
4669 } 4809// }
4670 4810
4671 public override ISceneObject DeserializeObject(string representation) 4811 public override ISceneObject DeserializeObject(string representation)
4672 { 4812 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 712e094..9c6b884 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes
149 #region Update Methods 149 #region Update Methods
150 150
151 /// <summary> 151 /// <summary>
152 /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) 152 /// Called to update the scene loop by a number of frames and until shutdown.
153 /// </summary> 153 /// </summary>
154 public abstract void Update(); 154 /// <param name="frames">
155 /// Number of frames to update. Exits on shutdown even if there are frames remaining.
156 /// If -1 then updates until shutdown.
157 /// </param>
158 public abstract void Update(int frames);
155 159
156 #endregion 160 #endregion
157 161
@@ -472,6 +476,63 @@ namespace OpenSim.Region.Framework.Scenes
472 /// <summary> 476 /// <summary>
473 /// Call this from a region module to add a command to the OpenSim console. 477 /// Call this from a region module to add a command to the OpenSim console.
474 /// </summary> 478 /// </summary>
479 /// <param name="mod">
480 /// The use of IRegionModuleBase is a cheap trick to get a different method signature,
481 /// though all new modules should be using interfaces descended from IRegionModuleBase anyway.
482 /// </param>
483 /// <param name="category">
484 /// Category of the command. This is the section under which it will appear when the user asks for help
485 /// </param>
486 /// <param name="command"></param>
487 /// <param name="shorthelp"></param>
488 /// <param name="longhelp"></param>
489 /// <param name="callback"></param>
490 public void AddCommand(
491 string category, object mod, string command, string shorthelp, string longhelp, CommandDelegate callback)
492 {
493 AddCommand(category, mod, command, shorthelp, longhelp, string.Empty, callback);
494 }
495
496 /// <summary>
497 /// Call this from a region module to add a command to the OpenSim console.
498 /// </summary>
499 /// <param name="mod"></param>
500 /// <param name="command"></param>
501 /// <param name="shorthelp"></param>
502 /// <param name="longhelp"></param>
503 /// <param name="descriptivehelp"></param>
504 /// <param name="callback"></param>
505 public void AddCommand(object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
506 {
507 string moduleName = "";
508
509 if (mod != null)
510 {
511 if (mod is IRegionModule)
512 {
513 IRegionModule module = (IRegionModule)mod;
514 moduleName = module.Name;
515 }
516 else if (mod is IRegionModuleBase)
517 {
518 IRegionModuleBase module = (IRegionModuleBase)mod;
519 moduleName = module.Name;
520 }
521 else
522 {
523 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
524 }
525 }
526
527 AddCommand(moduleName, mod, command, shorthelp, longhelp, descriptivehelp, callback);
528 }
529
530 /// <summary>
531 /// Call this from a region module to add a command to the OpenSim console.
532 /// </summary>
533 /// <param name="category">
534 /// Category of the command. This is the section under which it will appear when the user asks for help
535 /// </param>
475 /// <param name="mod"></param> 536 /// <param name="mod"></param>
476 /// <param name="command"></param> 537 /// <param name="command"></param>
477 /// <param name="shorthelp"></param> 538 /// <param name="shorthelp"></param>
@@ -479,12 +540,12 @@ namespace OpenSim.Region.Framework.Scenes
479 /// <param name="descriptivehelp"></param> 540 /// <param name="descriptivehelp"></param>
480 /// <param name="callback"></param> 541 /// <param name="callback"></param>
481 public void AddCommand( 542 public void AddCommand(
482 object mod, string command, string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback) 543 string category, object mod, string command,
544 string shorthelp, string longhelp, string descriptivehelp, CommandDelegate callback)
483 { 545 {
484 if (MainConsole.Instance == null) 546 if (MainConsole.Instance == null)
485 return; 547 return;
486 548
487 string modulename = String.Empty;
488 bool shared = false; 549 bool shared = false;
489 550
490 if (mod != null) 551 if (mod != null)
@@ -492,20 +553,20 @@ namespace OpenSim.Region.Framework.Scenes
492 if (mod is IRegionModule) 553 if (mod is IRegionModule)
493 { 554 {
494 IRegionModule module = (IRegionModule)mod; 555 IRegionModule module = (IRegionModule)mod;
495 modulename = module.Name;
496 shared = module.IsSharedModule; 556 shared = module.IsSharedModule;
497 } 557 }
498 else if (mod is IRegionModuleBase) 558 else if (mod is IRegionModuleBase)
499 { 559 {
500 IRegionModuleBase module = (IRegionModuleBase)mod;
501 modulename = module.Name;
502 shared = mod is ISharedRegionModule; 560 shared = mod is ISharedRegionModule;
503 } 561 }
504 else throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase"); 562 else
563 {
564 throw new Exception("AddCommand module parameter must be IRegionModule or IRegionModuleBase");
565 }
505 } 566 }
506 567
507 MainConsole.Instance.Commands.AddCommand( 568 MainConsole.Instance.Commands.AddCommand(
508 modulename, shared, command, shorthelp, longhelp, descriptivehelp, callback); 569 category, shared, command, shorthelp, longhelp, descriptivehelp, callback);
509 } 570 }
510 571
511 public virtual ISceneObject DeserializeObject(string representation) 572 public virtual ISceneObject DeserializeObject(string representation)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 66fb493..5c542d6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -215,27 +215,9 @@ namespace OpenSim.Region.Framework.Scenes
215 if (sp.IsChildAgent) 215 if (sp.IsChildAgent)
216 continue; 216 continue;
217 217
218 if (sp.ParentID != 0) 218 coarseLocations.Add(sp.AbsolutePosition);
219 { 219
220 // sitting avatar 220 avatarUUIDs.Add(sp.UUID);
221 SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID);
222 if (sop != null)
223 {
224 coarseLocations.Add(sop.AbsolutePosition + sp.OffsetPosition);
225 avatarUUIDs.Add(sp.UUID);
226 }
227 else
228 {
229 // we can't find the parent.. ! arg!
230 coarseLocations.Add(sp.AbsolutePosition);
231 avatarUUIDs.Add(sp.UUID);
232 }
233 }
234 else
235 {
236 coarseLocations.Add(sp.AbsolutePosition);
237 avatarUUIDs.Add(sp.UUID);
238 }
239 } 221 }
240 } 222 }
241 223
@@ -751,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
751 #endregion 733 #endregion
752 734
753 #region Get Methods 735 #region Get Methods
736
754 /// <summary> 737 /// <summary>
755 /// Get the controlling client for the given avatar, if there is one. 738 /// Get the controlling client for the given avatar, if there is one.
756 /// 739 ///
@@ -1092,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
1092 return Entities.GetEntities(); 1075 return Entities.GetEntities();
1093 } 1076 }
1094 1077
1095 public Dictionary<uint, float> GetTopScripts()
1096 {
1097 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1098
1099 EntityBase[] EntityList = GetEntities();
1100 int limit = 0;
1101 foreach (EntityBase ent in EntityList)
1102 {
1103 if (ent is SceneObjectGroup)
1104 {
1105 SceneObjectGroup grp = (SceneObjectGroup)ent;
1106 if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
1107 {
1108 if (grp.scriptScore >= 0.01)
1109 {
1110 topScripts.Add(grp.LocalId, grp.scriptScore);
1111 limit++;
1112 if (limit >= 100)
1113 {
1114 break;
1115 }
1116 }
1117 grp.scriptScore = 0;
1118 }
1119 }
1120 }
1121
1122 return topScripts;
1123 }
1124
1125 #endregion 1078 #endregion
1126 1079
1127 #region Other Methods 1080 #region Other Methods
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 878476e..afb5ccf 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes
229 get { return RootPart.VolumeDetectActive; } 229 get { return RootPart.VolumeDetectActive; }
230 } 230 }
231 231
232 public float scriptScore;
233
234 private Vector3 lastPhysGroupPos; 232 private Vector3 lastPhysGroupPos;
235 private Quaternion lastPhysGroupRot; 233 private Quaternion lastPhysGroupRot;
236 234
@@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
1184 1182
1185 public void AddScriptLPS(int count) 1183 public void AddScriptLPS(int count)
1186 { 1184 {
1187 if (scriptScore + count >= float.MaxValue - count) 1185 m_scene.SceneGraph.AddToScriptLPS(count);
1188 scriptScore = 0;
1189
1190 scriptScore += (float)count;
1191 SceneGraph d = m_scene.SceneGraph;
1192 d.AddToScriptLPS(count);
1193 } 1186 }
1194 1187
1195 public void AddActiveScriptCount(int count) 1188 public void AddActiveScriptCount(int count)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 65905a0..439b718 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1546,10 +1546,7 @@ namespace OpenSim.Region.Framework.Scenes
1546 if (userExposed) 1546 if (userExposed)
1547 dupe.UUID = UUID.Random(); 1547 dupe.UUID = UUID.Random();
1548 1548
1549 //memberwiseclone means it also clones the physics actor reference 1549 dupe.PhysActor = null;
1550 // This will make physical prim 'bounce' if not set to null.
1551 if (!userExposed)
1552 dupe.PhysActor = null;
1553 1550
1554 dupe.OwnerID = AgentID; 1551 dupe.OwnerID = AgentID;
1555 dupe.GroupID = GroupID; 1552 dupe.GroupID = GroupID;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index f2d1915..71a9084 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -590,9 +590,9 @@ namespace OpenSim.Region.Framework.Scenes
590 /// A list of inventory items with that name. 590 /// A list of inventory items with that name.
591 /// If no inventory item has that name then an empty list is returned. 591 /// If no inventory item has that name then an empty list is returned.
592 /// </returns> 592 /// </returns>
593 public IList<TaskInventoryItem> GetInventoryItems(string name) 593 public List<TaskInventoryItem> GetInventoryItems(string name)
594 { 594 {
595 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 595 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
596 596
597 lock (m_items) 597 lock (m_items)
598 { 598 {
@@ -1100,7 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes
1100 1100
1101 public List<TaskInventoryItem> GetInventoryItems() 1101 public List<TaskInventoryItem> GetInventoryItems()
1102 { 1102 {
1103 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1103 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1104 1104
1105 lock (m_items) 1105 lock (m_items)
1106 ret = new List<TaskInventoryItem>(m_items.Values); 1106 ret = new List<TaskInventoryItem>(m_items.Values);
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ec6bb89..cf60c69 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -432,7 +432,7 @@ namespace OpenSim.Region.Framework.Scenes
432 { 432 {
433 get 433 get
434 { 434 {
435 if (PhysicsActor != null && m_parentID == 0) 435 if (PhysicsActor != null)
436 { 436 {
437 m_pos = PhysicsActor.Position; 437 m_pos = PhysicsActor.Position;
438 438
@@ -455,19 +455,12 @@ namespace OpenSim.Region.Framework.Scenes
455 // in the sim unless the avatar is on a sit target. While 455 // in the sim unless the avatar is on a sit target. While
456 // on a sit target, m_pos will contain the desired offset 456 // on a sit target, m_pos will contain the desired offset
457 // without the parent rotation applied. 457 // without the parent rotation applied.
458 if (ParentID != 0) 458 SceneObjectPart sitPart = ParentPart;
459 { 459
460 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 460 if (sitPart != null)
461 if (part != null) 461 return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation());
462 {
463 return part.AbsolutePosition + (m_pos * part.GetWorldRotation());
464 }
465 else
466 {
467 return ParentPosition + m_pos;
468 }
469 }
470 } 462 }
463
471 return m_pos; 464 return m_pos;
472 } 465 }
473 set 466 set
@@ -484,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
484 } 477 }
485 } 478 }
486 479
487 // Don't update while sitting 480 // Don't update while sitting. The PhysicsActor above is null whilst sitting.
488 if (ParentID == 0) 481 if (ParentID == 0)
489 { 482 {
490 m_pos = value; 483 m_pos = value;
@@ -511,6 +504,7 @@ namespace OpenSim.Region.Framework.Scenes
511 // There is no offset position when not seated 504 // There is no offset position when not seated
512 if (ParentID == 0) 505 if (ParentID == 0)
513 return; 506 return;
507
514 m_pos = value; 508 m_pos = value;
515 } 509 }
516 } 510 }
@@ -569,12 +563,18 @@ namespace OpenSim.Region.Framework.Scenes
569 563
570 public bool IsChildAgent { get; set; } 564 public bool IsChildAgent { get; set; }
571 565
572 public uint ParentID 566 /// <summary>
573 { 567 /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
574 get { return m_parentID; } 568 /// </summary>
575 set { m_parentID = value; } 569 public uint ParentID { get; set; }
576 } 570
577 private uint m_parentID; 571 /// <summary>
572 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
573 /// </summary>
574 /// <remarks>
575 /// If you use this property then you must take a reference since another thread could set it to null.
576 /// </remarks>
577 public SceneObjectPart ParentPart { get; set; }
578 578
579 public float Health 579 public float Health
580 { 580 {
@@ -1751,36 +1751,34 @@ namespace OpenSim.Region.Framework.Scenes
1751 1751
1752 if (ParentID != 0) 1752 if (ParentID != 0)
1753 { 1753 {
1754 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); 1754 SceneObjectPart part = ParentPart;
1755 if (part != null) 1755 TaskInventoryDictionary taskIDict = part.TaskInventory;
1756 if (taskIDict != null)
1756 { 1757 {
1757 TaskInventoryDictionary taskIDict = part.TaskInventory; 1758 lock (taskIDict)
1758 if (taskIDict != null)
1759 { 1759 {
1760 lock (taskIDict) 1760 foreach (UUID taskID in taskIDict.Keys)
1761 { 1761 {
1762 foreach (UUID taskID in taskIDict.Keys) 1762 UnRegisterControlEventsToScript(LocalId, taskID);
1763 { 1763 taskIDict[taskID].PermsMask &= ~(
1764 UnRegisterControlEventsToScript(LocalId, taskID); 1764 2048 | //PERMISSION_CONTROL_CAMERA
1765 taskIDict[taskID].PermsMask &= ~( 1765 4); // PERMISSION_TAKE_CONTROLS
1766 2048 | //PERMISSION_CONTROL_CAMERA
1767 4); // PERMISSION_TAKE_CONTROLS
1768 }
1769 } 1766 }
1770 } 1767 }
1768 }
1771 1769
1772 // Reset sit target. 1770 // Reset sit target.
1773 if (part.SitTargetAvatar == UUID) 1771 if (part.SitTargetAvatar == UUID)
1774 part.SitTargetAvatar = UUID.Zero; 1772 part.SitTargetAvatar = UUID.Zero;
1775 1773
1776 ParentPosition = part.GetWorldPosition(); 1774 ParentPosition = part.GetWorldPosition();
1777 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1775 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
1778 }
1779 1776
1780 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); 1777 m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight);
1781 ParentPosition = Vector3.Zero; 1778 ParentPosition = Vector3.Zero;
1782 1779
1783 ParentID = 0; 1780 ParentID = 0;
1781 ParentPart = null;
1784 SendAvatarDataToAllAgents(); 1782 SendAvatarDataToAllAgents();
1785 m_requestedSitTargetID = 0; 1783 m_requestedSitTargetID = 0;
1786 1784
@@ -2206,19 +2204,16 @@ namespace OpenSim.Region.Framework.Scenes
2206// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", 2204// "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target",
2207// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); 2205// Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId);
2208 } 2206 }
2209 }
2210 else
2211 {
2212 return;
2213 }
2214 2207
2215 ParentID = m_requestedSitTargetID; 2208 ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
2209 ParentID = m_requestedSitTargetID;
2216 2210
2217 Velocity = Vector3.Zero; 2211 Velocity = Vector3.Zero;
2218 RemoveFromPhysicalScene(); 2212 RemoveFromPhysicalScene();
2219 2213
2220 Animator.TrySetMovementAnimation(sitAnimation); 2214 Animator.TrySetMovementAnimation(sitAnimation);
2221 SendAvatarDataToAllAgents(); 2215 SendAvatarDataToAllAgents();
2216 }
2222 } 2217 }
2223 2218
2224 public void HandleAgentSitOnGround() 2219 public void HandleAgentSitOnGround()
@@ -2298,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes
2298 { 2293 {
2299 if (direc.Z > 2.0f) 2294 if (direc.Z > 2.0f)
2300 { 2295 {
2301 direc.Z *= 3.0f; 2296 direc.Z *= 2.6f;
2302 2297
2303 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2298 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2304 Animator.TrySetMovementAnimation("PREJUMP"); 2299 Animator.TrySetMovementAnimation("PREJUMP");
@@ -3831,7 +3826,7 @@ namespace OpenSim.Region.Framework.Scenes
3831 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); 3826 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
3832 if (land != null) 3827 if (land != null)
3833 { 3828 {
3834 if (Scene.DEBUG) 3829 if (Scene.DebugTeleporting)
3835 TeleportFlagsDebug(); 3830 TeleportFlagsDebug();
3836 3831
3837 // If we come in via login, landmark or map, we want to 3832 // If we come in via login, landmark or map, we want to
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 35cd025..5c56264 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -178,13 +178,19 @@ namespace OpenSim.Region.Framework.Scenes
178 m_objectCapacity = scene.RegionInfo.ObjectCapacity; 178 m_objectCapacity = scene.RegionInfo.ObjectCapacity;
179 m_report.AutoReset = true; 179 m_report.AutoReset = true;
180 m_report.Interval = statsUpdatesEveryMS; 180 m_report.Interval = statsUpdatesEveryMS;
181 m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat); 181 m_report.Elapsed += statsHeartBeat;
182 m_report.Enabled = true; 182 m_report.Enabled = true;
183 183
184 if (StatsManager.SimExtraStats != null) 184 if (StatsManager.SimExtraStats != null)
185 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; 185 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
186 } 186 }
187 187
188 public void Close()
189 {
190 m_report.Elapsed -= statsHeartBeat;
191 m_report.Close();
192 }
193
188 public void SetUpdateMS(int ms) 194 public void SetUpdateMS(int ms)
189 { 195 {
190 statsUpdatesEveryMS = ms; 196 statsUpdatesEveryMS = ms;
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index ca6210d..c0ca48e 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -46,23 +46,20 @@ namespace OpenSim.Region.Framework.Scenes
46 public TerrainChannel() 46 public TerrainChannel()
47 { 47 {
48 map = new double[Constants.RegionSize, Constants.RegionSize]; 48 map = new double[Constants.RegionSize, Constants.RegionSize];
49 taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; 49 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
50 50
51 int x; 51 PinHeadIsland();
52 for (x = 0; x < Constants.RegionSize; x++) 52 }
53 { 53
54 int y; 54 public TerrainChannel(String type)
55 for (y = 0; y < Constants.RegionSize; y++) 55 {
56 { 56 map = new double[Constants.RegionSize, Constants.RegionSize];
57 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; 57 taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16];
58 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; 58
59 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; 59 if (type.Equals("flat"))
60 if (map[x, y] < spherFacA) 60 FlatLand();
61 map[x, y] = spherFacA; 61 else
62 if (map[x, y] < spherFacB) 62 PinHeadIsland();
63 map[x, y] = spherFacB;
64 }
65 }
66 } 63 }
67 64
68 public TerrainChannel(double[,] import) 65 public TerrainChannel(double[,] import)
@@ -238,5 +235,36 @@ namespace OpenSim.Region.Framework.Scenes
238 } 235 }
239 } 236 }
240 } 237 }
238
239 private void PinHeadIsland()
240 {
241 int x;
242 for (x = 0; x < Constants.RegionSize; x++)
243 {
244 int y;
245 for (y = 0; y < Constants.RegionSize; y++)
246 {
247 map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10;
248 double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01;
249 double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001;
250 if (map[x, y] < spherFacA)
251 map[x, y] = spherFacA;
252 if (map[x, y] < spherFacB)
253 map[x, y] = spherFacB;
254 }
255 }
256 }
257
258 private void FlatLand()
259 {
260 int x;
261 for (x = 0; x < Constants.RegionSize; x++)
262 {
263 int y;
264 for (y = 0; y < Constants.RegionSize; y++)
265 map[x, y] = 21;
266 }
267 }
268
241 } 269 }
242} 270}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index 442cb8b..cfea10d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change. 81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
82 sp.Flying = true; 82 sp.Flying = true;
83 83
84 m_scene.Update(); 84 m_scene.Update(1);
85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); 85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
86 86
87 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 87 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
91 Assert.That( 91 Assert.That(
92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); 92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
93 93
94 m_scene.Update(); 94 m_scene.Update(1);
95 95
96 // We should really check the exact figure. 96 // We should really check the exact figure.
97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); 97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); 100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
101 101
102 for (int i = 0; i < 10; i++) 102 m_scene.Update(10);
103 m_scene.Update();
104 103
105 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 104 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
106 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); 105 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
@@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
116 Assert.That( 115 Assert.That(
117 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); 116 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
118 117
119 m_scene.Update(); 118 m_scene.Update(1);
120 119
121 // We should really check the exact figure. 120 // We should really check the exact figure.
122 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); 121 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
124 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 123 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 124 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
126 125
127 for (int i = 0; i < 10; i++) 126 m_scene.Update(10);
128 m_scene.Update();
129 127
130 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 128 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
131 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); 129 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index c5a76b2..bebc10c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
63 63
64 Thread testThread = new Thread(testClass.run); 64 Thread testThread = new Thread(testClass.run);
65 65
66 try 66 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against
67 { 67 // A thread abort exception in the simulator code.
68 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against 68 testThread.Start();
69 // A thread abort exception in the simulator code. 69 testThread.Join();
70 testThread.Start(); 70
71 testThread.Join();
72 }
73 catch (ThreadAbortException)
74 {
75
76 }
77 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); 71 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message);
78 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); 72 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
79 } 73 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8b8aea5..5c9a77d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 TestHelpers.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
64 scene.Update(); 64 scene.Update(1);
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
67 } 67 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
index e16903c..55c80f5 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Region.Framework.Tests
113 } 113 }
114 114
115 /// <summary> 115 /// <summary>
116 /// Test MoveTaskInventoryItem where the item has no parent folder assigned. 116 /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
117 /// </summary> 117 /// </summary>
118 /// <remarks> 118 /// <remarks>
119 /// This should place it in the most suitable user folder. 119 /// This should place it in the most suitable user folder.
@@ -142,9 +142,11 @@ namespace OpenSim.Region.Framework.Tests
142 } 142 }
143 143
144 /// <summary> 144 /// <summary>
145 /// Test MoveTaskInventoryItem where the item has no parent folder assigned. 145 /// Test MoveTaskInventoryItem from a part inventory to a user inventory where the item has no parent folder assigned.
146 /// </summary> 146 /// </summary>
147 /// <remarks>
147 /// This should place it in the most suitable user folder. 148 /// This should place it in the most suitable user folder.
149 /// </remarks>
148 [Test] 150 [Test]
149 public void TestMoveTaskInventoryItemNoParent() 151 public void TestMoveTaskInventoryItemNoParent()
150 { 152 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index d3c96e2..5cf478a 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1203,11 +1203,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1203 1203
1204 } 1204 }
1205 1205
1206 public UUID GetDefaultAnimation(string name)
1207 {
1208 return UUID.Zero;
1209 }
1210
1211 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID) 1206 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID)
1212 { 1207 {
1213 1208
diff --git a/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
index 439096a..c897aa5 100644
--- a/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Agent.TextureSender
92 m_scene = scene; 92 m_scene = scene;
93 93
94 MainConsole.Instance.Commands.AddCommand( 94 MainConsole.Instance.Commands.AddCommand(
95 "j2k", 95 "Assets",
96 false, 96 false,
97 "j2k decode", 97 "j2k decode",
98 "j2k decode <ID>", 98 "j2k decode <ID>",
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index 261029c..a7ebecc 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -82,19 +82,19 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
82 m_scenes[scene.RegionInfo.RegionID] = scene; 82 m_scenes[scene.RegionInfo.RegionID] = scene;
83 83
84 scene.AddCommand( 84 scene.AddCommand(
85 this, "image queues clear", 85 "Comms", this, "image queues clear",
86 "image queues clear <first-name> <last-name>", 86 "image queues clear <first-name> <last-name>",
87 "Clear the image queues (textures downloaded via UDP) for a particular client.", 87 "Clear the image queues (textures downloaded via UDP) for a particular client.",
88 (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd))); 88 (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
89 89
90 scene.AddCommand( 90 scene.AddCommand(
91 this, "image queues show", 91 "Comms", this, "image queues show",
92 "image queues show <first-name> <last-name>", 92 "image queues show <first-name> <last-name>",
93 "Show the image queues (textures downloaded via UDP) for a particular client.", 93 "Show the image queues (textures downloaded via UDP) for a particular client.",
94 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); 94 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
95 95
96 scene.AddCommand( 96 scene.AddCommand(
97 this, "show pqueues", 97 "Comms", this, "show pqueues",
98 "show pqueues [full]", 98 "show pqueues [full]",
99 "Show priority queue data for each client", 99 "Show priority queue data for each client",
100 "Without the 'full' option, only root agents are shown." 100 "Without the 'full' option, only root agents are shown."
@@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
102 (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd))); 102 (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
103 103
104 scene.AddCommand( 104 scene.AddCommand(
105 this, "show queues", 105 "Comms", this, "show queues",
106 "show queues [full]", 106 "show queues [full]",
107 "Show queue data for each client", 107 "Show queue data for each client",
108 "Without the 'full' option, only root agents are shown." 108 "Without the 'full' option, only root agents are shown."
@@ -110,13 +110,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
110 (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd))); 110 (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
111 111
112 scene.AddCommand( 112 scene.AddCommand(
113 this, "show image queues", 113 "Comms", this, "show image queues",
114 "show image queues <first-name> <last-name>", 114 "show image queues <first-name> <last-name>",
115 "Show the image queues (textures downloaded via UDP) for a particular client.", 115 "Show the image queues (textures downloaded via UDP) for a particular client.",
116 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd))); 116 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
117 117
118 scene.AddCommand( 118 scene.AddCommand(
119 this, "show throttles", 119 "Comms", this, "show throttles",
120 "show throttles [full]", 120 "show throttles [full]",
121 "Show throttle settings for each client and for the server overall", 121 "Show throttle settings for each client and for the server overall",
122 "Without the 'full' option, only root agents are shown." 122 "Without the 'full' option, only root agents are shown."
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
124 (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd))); 124 (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
125 125
126 scene.AddCommand( 126 scene.AddCommand(
127 this, "emergency-monitoring", 127 "Comms", this, "emergency-monitoring",
128 "emergency-monitoring", 128 "emergency-monitoring",
129 "Go on/off emergency monitoring mode", 129 "Go on/off emergency monitoring mode",
130 "Go on/off emergency monitoring mode", 130 "Go on/off emergency monitoring mode",
diff --git a/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs b/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs
index a5207eb..41ec14f 100644
--- a/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs
@@ -88,7 +88,7 @@ namespace OpenSim.Region.OptionalModules.Asset
88 m_scene = scene; 88 m_scene = scene;
89 89
90 MainConsole.Instance.Commands.AddCommand( 90 MainConsole.Instance.Commands.AddCommand(
91 "asset", 91 "Assets",
92 false, 92 false,
93 "show asset", 93 "show asset",
94 "show asset <ID>", 94 "show asset <ID>",
@@ -96,7 +96,7 @@ namespace OpenSim.Region.OptionalModules.Asset
96 HandleShowAsset); 96 HandleShowAsset);
97 97
98 MainConsole.Instance.Commands.AddCommand( 98 MainConsole.Instance.Commands.AddCommand(
99 "asset", false, "dump asset", 99 "Assets", false, "dump asset",
100 "dump asset <id>", 100 "dump asset <id>",
101 "Dump an asset", 101 "Dump an asset",
102 HandleDumpAsset); 102 HandleDumpAsset);
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 2369d94..6bb6729 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -94,13 +94,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
94 m_scenes[scene.RegionInfo.RegionID] = scene; 94 m_scenes[scene.RegionInfo.RegionID] = scene;
95 95
96 scene.AddCommand( 96 scene.AddCommand(
97 this, "show appearance", 97 "Users", this, "show appearance",
98 "show appearance [<first-name> <last-name>]", 98 "show appearance [<first-name> <last-name>]",
99 "Synonym for 'appearance show'", 99 "Synonym for 'appearance show'",
100 HandleShowAppearanceCommand); 100 HandleShowAppearanceCommand);
101 101
102 scene.AddCommand( 102 scene.AddCommand(
103 this, "appearance show", 103 "Users", this, "appearance show",
104 "appearance show [<first-name> <last-name>]", 104 "appearance show [<first-name> <last-name>]",
105 "Show appearance information for each avatar in the simulator.", 105 "Show appearance information for each avatar in the simulator.",
106 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. " 106 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. "
@@ -110,14 +110,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
110 HandleShowAppearanceCommand); 110 HandleShowAppearanceCommand);
111 111
112 scene.AddCommand( 112 scene.AddCommand(
113 this, "appearance send", 113 "Users", this, "appearance send",
114 "appearance send [<first-name> <last-name>]", 114 "appearance send [<first-name> <last-name>]",
115 "Send appearance data for each avatar in the simulator to other viewers.", 115 "Send appearance data for each avatar in the simulator to other viewers.",
116 "Optionally, you can specify that only a particular avatar's appearance data is sent.", 116 "Optionally, you can specify that only a particular avatar's appearance data is sent.",
117 HandleSendAppearanceCommand); 117 HandleSendAppearanceCommand);
118 118
119 scene.AddCommand( 119 scene.AddCommand(
120 this, "appearance rebake", 120 "Users", this, "appearance rebake",
121 "appearance rebake <first-name> <last-name>", 121 "appearance rebake <first-name> <last-name>",
122 "Send a request to the user's viewer for it to rebake and reupload its appearance textures.", 122 "Send a request to the user's viewer for it to rebake and reupload its appearance textures.",
123 "This is currently done for all baked texture references previously received, whether the simulator can find the asset or not." 123 "This is currently done for all baked texture references previously received, whether the simulator can find the asset or not."
@@ -127,7 +127,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
127 HandleRebakeAppearanceCommand); 127 HandleRebakeAppearanceCommand);
128 128
129 scene.AddCommand( 129 scene.AddCommand(
130 this, "appearance find", 130 "Users", this, "appearance find",
131 "appearance find <uuid-or-start-of-uuid>", 131 "appearance find <uuid-or-start-of-uuid>",
132 "Find out which avatar uses the given asset as a baked texture, if any.", 132 "Find out which avatar uses the given asset as a baked texture, if any.",
133 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.", 133 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",
diff --git a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
index 23ef757..e452124 100755
--- a/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
+++ b/OpenSim/Region/OptionalModules/PhysicsParameters/PhysicsParameters.cs
@@ -100,22 +100,22 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
100 { 100 {
101 if (!m_commandsLoaded) 101 if (!m_commandsLoaded)
102 { 102 {
103 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics set", 103 MainConsole.Instance.Commands.AddCommand(
104 "physics set", 104 "Regions", false, "physics set",
105 "Set physics parameter from currently selected region" + Environment.NewLine 105 setInvocation,
106 + "Invocation: " + setInvocation, 106 "Set physics parameter from currently selected region",
107 ProcessPhysicsSet); 107 ProcessPhysicsSet);
108 108
109 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics get", 109 MainConsole.Instance.Commands.AddCommand(
110 "physics get", 110 "Regions", false, "physics get",
111 "Get physics parameter from currently selected region" + Environment.NewLine 111 getInvocation,
112 + "Invocation: " + getInvocation, 112 "Get physics parameter from currently selected region",
113 ProcessPhysicsGet); 113 ProcessPhysicsGet);
114 114
115 MainConsole.Instance.Commands.AddCommand("Physics", false, "physics list", 115 MainConsole.Instance.Commands.AddCommand(
116 "physics list", 116 "Regions", false, "physics list",
117 "List settable physics parameters" + Environment.NewLine 117 listInvocation,
118 + "Invocation: " + listInvocation, 118 "List settable physics parameters",
119 ProcessPhysicsList); 119 ProcessPhysicsList);
120 120
121 m_commandsLoaded = true; 121 m_commandsLoaded = true;
@@ -264,14 +264,14 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
264 264
265 private void WriteOut(string msg, params object[] args) 265 private void WriteOut(string msg, params object[] args)
266 { 266 {
267 m_log.InfoFormat(msg, args); 267 // m_log.InfoFormat(msg, args);
268 // MainConsole.Instance.OutputFormat(msg, args); 268 MainConsole.Instance.OutputFormat(msg, args);
269 } 269 }
270 270
271 private void WriteError(string msg, params object[] args) 271 private void WriteError(string msg, params object[] args)
272 { 272 {
273 m_log.ErrorFormat(msg, args); 273 // m_log.ErrorFormat(msg, args);
274 // MainConsole.Instance.OutputFormat(msg, args); 274 MainConsole.Instance.OutputFormat(msg, args);
275 } 275 }
276 } 276 }
277} \ No newline at end of file 277}
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index d0142a4..0b9f875 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -70,8 +70,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
70 70
71 public void Initialise(IConfigSource config) 71 public void Initialise(IConfigSource config)
72 { 72 {
73 //m_log.Info("[RegionReady] Initialising");
74
75 m_config = config.Configs["RegionReady"]; 73 m_config = config.Configs["RegionReady"];
76 if (m_config != null) 74 if (m_config != null)
77 { 75 {
@@ -84,9 +82,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
84 m_uri = m_config.GetString("alert_uri",string.Empty); 82 m_uri = m_config.GetString("alert_uri",string.Empty);
85 } 83 }
86 } 84 }
87
88// if (!m_enabled)
89// m_log.Info("[RegionReady] disabled.");
90 } 85 }
91 86
92 public void AddRegion(Scene scene) 87 public void AddRegion(Scene scene)
@@ -113,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
113 { 108 {
114 scene.LoginLock = true; 109 scene.LoginLock = true;
115 scene.LoginsDisabled = true; 110 scene.LoginsDisabled = true;
116 m_log.InfoFormat("[RegionReady]: Logins disabled for {0}",m_scene.RegionInfo.RegionName); 111 m_log.InfoFormat("[RegionReady]: Region {0} - logins disabled during initialization.",m_scene.RegionInfo.RegionName);
117 112
118 if(m_uri != string.Empty) 113 if(m_uri != string.Empty)
119 { 114 {
@@ -167,7 +162,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
167 162
168 void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) 163 void OnEmptyScriptCompileQueue(int numScriptsFailed, string message)
169 { 164 {
170 m_log.InfoFormat("[RegionReady]: Script compile queue empty!"); 165 m_log.DebugFormat("[RegionReady]: Script compile queue empty!");
171 166
172 if (m_firstEmptyCompileQueue || m_oarFileLoading) 167 if (m_firstEmptyCompileQueue || m_oarFileLoading)
173 { 168 {
@@ -194,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
194 c.SenderUUID = UUID.Zero; 189 c.SenderUUID = UUID.Zero;
195 c.Scene = m_scene; 190 c.Scene = m_scene;
196 191
197 m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", 192 m_log.DebugFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}",
198 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); 193 m_scene.RegionInfo.RegionName, c.Message, m_channelNotify);
199 194
200 m_scene.EventManager.TriggerOnChatBroadcast(this, c); 195 m_scene.EventManager.TriggerOnChatBroadcast(this, c);
@@ -210,7 +205,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
210 { 205 {
211 m_lastOarLoadedOk = true; 206 m_lastOarLoadedOk = true;
212 } else { 207 } else {
213 m_log.InfoFormat("[RegionReady]: Oar file load errors: {0}", message); 208 m_log.WarnFormat("[RegionReady]: Oar file load errors: {0}", message);
214 m_lastOarLoadedOk = false; 209 m_lastOarLoadedOk = false;
215 } 210 }
216 } 211 }
@@ -233,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
233 // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}", 228 // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
234 // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString()); 229 // m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
235 230
236 m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); 231 m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName);
237 232
238 if ( m_uri != string.Empty ) 233 if ( m_uri != string.Empty )
239 { 234 {
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 44c9ada..cab30de 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic;
30using Nini.Config; 31using Nini.Config;
31using log4net; 32using log4net;
32using OpenSim.Framework; 33using OpenSim.Framework;
@@ -34,8 +35,10 @@ using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
35using Mono.Addins; 36using Mono.Addins;
36using OpenMetaverse; 37using OpenMetaverse;
38using System.Linq;
39using System.Linq.Expressions;
37 40
38namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms 41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
39{ 42{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
41 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms 44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
@@ -43,10 +46,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
43 private static readonly ILog m_log = 46 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 48
46 private IScriptModule m_scriptModule = null; 49#region ScriptInvocation
50 protected class ScriptInvocationData
51 {
52 public Delegate ScriptInvocationDelegate { get; private set; }
53 public string FunctionName { get; private set; }
54 public Type[] TypeSignature { get; private set; }
55 public Type ReturnType { get; private set; }
56
57 public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
58 {
59 FunctionName = fname;
60 ScriptInvocationDelegate = fn;
61 TypeSignature = callsig;
62 ReturnType = returnsig;
63 }
64 }
65
66 private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
67#endregion
47 68
69 private IScriptModule m_scriptModule = null;
48 public event ScriptCommand OnScriptCommand; 70 public event ScriptCommand OnScriptCommand;
49 71
72#region RegionModuleInterface
50 public void Initialise(IConfigSource config) 73 public void Initialise(IConfigSource config)
51 { 74 {
52 } 75 }
@@ -81,6 +104,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
81 public void Close() 104 public void Close()
82 { 105 {
83 } 106 }
107#endregion
108
109#region ScriptModuleComms
84 110
85 public void RaiseEvent(UUID script, string id, string module, string command, string k) 111 public void RaiseEvent(UUID script, string id, string module, string command, string k)
86 { 112 {
@@ -101,5 +127,149 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
101 127
102 m_scriptModule.PostScriptEvent(script, "link_message", args); 128 m_scriptModule.PostScriptEvent(script, "link_message", args);
103 } 129 }
130
131 public void RegisterScriptInvocation(object target, string meth)
132 {
133 MethodInfo mi = target.GetType().GetMethod(meth,
134 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
135 if (mi == null)
136 {
137 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
138 return;
139 }
140
141 RegisterScriptInvocation(target, mi);
142 }
143
144 public void RegisterScriptInvocation(object target, string[] meth)
145 {
146 foreach (string m in meth)
147 RegisterScriptInvocation(target, m);
148 }
149
150 public void RegisterScriptInvocation(object target, MethodInfo mi)
151 {
152 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
153
154 Type delegateType;
155 var typeArgs = mi.GetParameters()
156 .Select(p => p.ParameterType)
157 .ToList();
158
159 if (mi.ReturnType == typeof(void))
160 {
161 delegateType = Expression.GetActionType(typeArgs.ToArray());
162 }
163 else
164 {
165 typeArgs.Add(mi.ReturnType);
166 delegateType = Expression.GetFuncType(typeArgs.ToArray());
167 }
168
169 Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
170
171 lock (m_scriptInvocation)
172 {
173 ParameterInfo[] parameters = fcall.Method.GetParameters ();
174 if (parameters.Length < 2) // Must have two UUID params
175 return;
176
177 // Hide the first two parameters
178 Type[] parmTypes = new Type[parameters.Length - 2];
179 for (int i = 2 ; i < parameters.Length ; i++)
180 parmTypes[i - 2] = parameters[i].ParameterType;
181 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
182 }
183 }
184
185 public Delegate[] GetScriptInvocationList()
186 {
187 List<Delegate> ret = new List<Delegate>();
188
189 lock (m_scriptInvocation)
190 {
191 foreach (ScriptInvocationData d in m_scriptInvocation.Values)
192 ret.Add(d.ScriptInvocationDelegate);
193 }
194 return ret.ToArray();
195 }
196
197 public string LookupModInvocation(string fname)
198 {
199 lock (m_scriptInvocation)
200 {
201 ScriptInvocationData sid;
202 if (m_scriptInvocation.TryGetValue(fname,out sid))
203 {
204 if (sid.ReturnType == typeof(string))
205 return "modInvokeS";
206 else if (sid.ReturnType == typeof(int))
207 return "modInvokeI";
208 else if (sid.ReturnType == typeof(float))
209 return "modInvokeF";
210 else if (sid.ReturnType == typeof(UUID))
211 return "modInvokeK";
212 else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
213 return "modInvokeV";
214 else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
215 return "modInvokeR";
216 else if (sid.ReturnType == typeof(object[]))
217 return "modInvokeL";
218
219 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
220 }
221 }
222
223 return null;
224 }
225
226 public Delegate LookupScriptInvocation(string fname)
227 {
228 lock (m_scriptInvocation)
229 {
230 ScriptInvocationData sid;
231 if (m_scriptInvocation.TryGetValue(fname,out sid))
232 return sid.ScriptInvocationDelegate;
233 }
234
235 return null;
236 }
237
238 public Type[] LookupTypeSignature(string fname)
239 {
240 lock (m_scriptInvocation)
241 {
242 ScriptInvocationData sid;
243 if (m_scriptInvocation.TryGetValue(fname,out sid))
244 return sid.TypeSignature;
245 }
246
247 return null;
248 }
249
250 public Type LookupReturnType(string fname)
251 {
252 lock (m_scriptInvocation)
253 {
254 ScriptInvocationData sid;
255 if (m_scriptInvocation.TryGetValue(fname,out sid))
256 return sid.ReturnType;
257 }
258
259 return null;
260 }
261
262 public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
263 {
264 List<object> olist = new List<object>();
265 olist.Add(hostid);
266 olist.Add(scriptid);
267 foreach (object o in parms)
268 olist.Add(o);
269 Delegate fn = LookupScriptInvocation(fname);
270 return fn.DynamicInvoke(olist.ToArray());
271 }
272#endregion
273
104 } 274 }
105} 275}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index be0d56e..16ec34f 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -34,6 +34,9 @@ using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Region.CoreModules.World.Estate; 36using OpenSim.Region.CoreModules.World.Estate;
37using log4net;
38using System.Reflection;
39using System.Xml;
37 40
38namespace OpenSim.Region.OptionalModules.World.NPC 41namespace OpenSim.Region.OptionalModules.World.NPC
39{ 42{
@@ -130,11 +133,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
130 133
131 } 134 }
132 135
133 public UUID GetDefaultAnimation(string name)
134 {
135 return UUID.Zero;
136 }
137
138 public Vector3 Position 136 public Vector3 Position
139 { 137 {
140 get { return m_scene.Entities[m_uuid].AbsolutePosition; } 138 get { return m_scene.Entities[m_uuid].AbsolutePosition; }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 2052cdb..2b8379d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -88,22 +88,26 @@ namespace OpenSim.Region.OptionalModules.World.NPC
88 88
89 public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene) 89 public bool SetNPCAppearance(UUID agentId, AvatarAppearance appearance, Scene scene)
90 { 90 {
91 ScenePresence sp = scene.GetScenePresence(agentId); 91 ScenePresence npc = scene.GetScenePresence(agentId);
92 if (sp == null || sp.IsChildAgent) 92 if (npc == null || npc.IsChildAgent)
93 return false; 93 return false;
94 94
95 lock (m_avatars) 95 lock (m_avatars)
96 if (!m_avatars.ContainsKey(agentId)) 96 if (!m_avatars.ContainsKey(agentId))
97 return false; 97 return false;
98 98
99 // Delete existing sp attachments 99 // Delete existing npc attachments
100 scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); 100 scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
101 101
102 // Set new sp appearance. Also sends to clients. 102 // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
103 scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true)); 103 AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
104 npc.Appearance = npcAppearance;
104 105
105 // Rez needed sp attachments 106 // Rez needed npc attachments
106 scene.AttachmentsModule.RezAttachments(sp); 107 scene.AttachmentsModule.RezAttachments(npc);
108
109 IAvatarFactoryModule module = scene.RequestModuleInterface<IAvatarFactoryModule>();
110 module.SendAppearance(npc.UUID);
107 111
108 return true; 112 return true;
109 } 113 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index d507822..eea0b2e 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -50,10 +50,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
50 [TestFixture] 50 [TestFixture]
51 public class NPCModuleTests 51 public class NPCModuleTests
52 { 52 {
53 private TestScene scene; 53 private TestScene m_scene;
54 private AvatarFactoryModule afm; 54 private AvatarFactoryModule m_afMod;
55 private UserManagementModule umm; 55 private UserManagementModule m_umMod;
56 private AttachmentsModule am; 56 private AttachmentsModule m_attMod;
57 private NPCModule m_npcMod;
57 58
58 [TestFixtureSetUp] 59 [TestFixtureSetUp]
59 public void FixtureInit() 60 public void FixtureInit()
@@ -79,12 +80,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
79 config.AddConfig("Modules"); 80 config.AddConfig("Modules");
80 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 81 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
81 82
82 afm = new AvatarFactoryModule(); 83 m_afMod = new AvatarFactoryModule();
83 umm = new UserManagementModule(); 84 m_umMod = new UserManagementModule();
84 am = new AttachmentsModule(); 85 m_attMod = new AttachmentsModule();
86 m_npcMod = new NPCModule();
85 87
86 scene = SceneHelpers.SetupScene(); 88 m_scene = SceneHelpers.SetupScene();
87 SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule()); 89 SceneHelpers.SetupSceneModules(m_scene, config, m_afMod, m_umMod, m_attMod, m_npcMod, new BasicInventoryAccessModule());
88 } 90 }
89 91
90 [Test] 92 [Test]
@@ -93,7 +95,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
93 TestHelpers.InMethod(); 95 TestHelpers.InMethod();
94// log4net.Config.XmlConfigurator.Configure(); 96// log4net.Config.XmlConfigurator.Configure();
95 97
96 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 98 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
97// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 99// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
98 100
99 // 8 is the index of the first baked texture in AvatarAppearance 101 // 8 is the index of the first baked texture in AvatarAppearance
@@ -104,18 +106,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
104 106
105 // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell 107 // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
106 // ScenePresence.SendInitialData() to reset our entire appearance. 108 // ScenePresence.SendInitialData() to reset our entire appearance.
107 scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); 109 m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
108 110
109 afm.SetAppearance(sp, originalTe, null); 111 m_afMod.SetAppearance(sp, originalTe, null);
110 112
111 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 113 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
112 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
113 114
114 ScenePresence npc = scene.GetScenePresence(npcId); 115 ScenePresence npc = m_scene.GetScenePresence(npcId);
115 116
116 Assert.That(npc, Is.Not.Null); 117 Assert.That(npc, Is.Not.Null);
117 Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); 118 Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId));
118 Assert.That(umm.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname))); 119 Assert.That(m_umMod.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname)));
119 } 120 }
120 121
121 [Test] 122 [Test]
@@ -124,42 +125,83 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
124 TestHelpers.InMethod(); 125 TestHelpers.InMethod();
125// log4net.Config.XmlConfigurator.Configure(); 126// log4net.Config.XmlConfigurator.Configure();
126 127
127 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 128 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
128// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 129// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
129 130
130 Vector3 startPos = new Vector3(128, 128, 30); 131 Vector3 startPos = new Vector3(128, 128, 30);
131 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 132 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
132 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
133 133
134 npcModule.DeleteNPC(npcId, scene); 134 m_npcMod.DeleteNPC(npcId, m_scene);
135 135
136 ScenePresence deletedNpc = scene.GetScenePresence(npcId); 136 ScenePresence deletedNpc = m_scene.GetScenePresence(npcId);
137 137
138 Assert.That(deletedNpc, Is.Null); 138 Assert.That(deletedNpc, Is.Null);
139 } 139 }
140 140
141 [Test] 141 [Test]
142 public void TestAttachments() 142 public void TestCreateWithAttachments()
143 { 143 {
144 TestHelpers.InMethod(); 144 TestHelpers.InMethod();
145// log4net.Config.XmlConfigurator.Configure(); 145// log4net.Config.XmlConfigurator.Configure();
146 146
147 UUID userId = TestHelpers.ParseTail(0x1); 147 UUID userId = TestHelpers.ParseTail(0x1);
148 UserAccountHelpers.CreateUserWithInventory(scene, userId); 148 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
149 ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); 149 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
150 150
151 UUID attItemId = TestHelpers.ParseTail(0x2); 151 UUID attItemId = TestHelpers.ParseTail(0x2);
152 UUID attAssetId = TestHelpers.ParseTail(0x3); 152 UUID attAssetId = TestHelpers.ParseTail(0x3);
153 string attName = "att"; 153 string attName = "att";
154 154
155 UserInventoryHelpers.CreateInventoryItem(scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object); 155 UserInventoryHelpers.CreateInventoryItem(m_scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
156 156
157 am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest); 157 m_attMod.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
158 158
159 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 159 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
160 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
161 160
162 ScenePresence npc = scene.GetScenePresence(npcId); 161 ScenePresence npc = m_scene.GetScenePresence(npcId);
162
163 // Check scene presence status
164 Assert.That(npc.HasAttachments(), Is.True);
165 List<SceneObjectGroup> attachments = npc.GetAttachments();
166 Assert.That(attachments.Count, Is.EqualTo(1));
167 SceneObjectGroup attSo = attachments[0];
168
169 // Just for now, we won't test the name since this is (wrongly) the asset part name rather than the item
170 // name. TODO: Do need to fix ultimately since the item may be renamed before being passed on to an NPC.
171// Assert.That(attSo.Name, Is.EqualTo(attName));
172
173 Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
174 Assert.That(attSo.IsAttachment);
175 Assert.That(attSo.UsesPhysics, Is.False);
176 Assert.That(attSo.IsTemporary, Is.False);
177 Assert.That(attSo.OwnerID, Is.EqualTo(npc.UUID));
178 }
179
180 [Test]
181 public void TestLoadAppearance()
182 {
183 TestHelpers.InMethod();
184// log4net.Config.XmlConfigurator.Configure();
185
186 UUID userId = TestHelpers.ParseTail(0x1);
187 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
188 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
189
190 UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
191
192 // Now add the attachment to the original avatar and use that to load a new appearance
193 // TODO: Could also run tests loading from a notecard though this isn't much different for our purposes here
194 UUID attItemId = TestHelpers.ParseTail(0x2);
195 UUID attAssetId = TestHelpers.ParseTail(0x3);
196 string attName = "att";
197
198 UserInventoryHelpers.CreateInventoryItem(m_scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object);
199
200 m_attMod.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
201
202 m_npcMod.SetNPCAppearance(npcId, sp.Appearance, m_scene);
203
204 ScenePresence npc = m_scene.GetScenePresence(npcId);
163 205
164 // Check scene presence status 206 // Check scene presence status
165 Assert.That(npc.HasAttachments(), Is.True); 207 Assert.That(npc.HasAttachments(), Is.True);
@@ -184,31 +226,30 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
184 TestHelpers.InMethod(); 226 TestHelpers.InMethod();
185// log4net.Config.XmlConfigurator.Configure(); 227// log4net.Config.XmlConfigurator.Configure();
186 228
187 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 229 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
188// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); 230// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
189 231
190 Vector3 startPos = new Vector3(128, 128, 30); 232 Vector3 startPos = new Vector3(128, 128, 30);
191 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 233 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
192 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
193 234
194 ScenePresence npc = scene.GetScenePresence(npcId); 235 ScenePresence npc = m_scene.GetScenePresence(npcId);
195 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 236 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
196 237
197 // For now, we'll make the scene presence fly to simplify this test, but this needs to change. 238 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
198 npc.Flying = true; 239 npc.Flying = true;
199 240
200 scene.Update(); 241 m_scene.Update(1);
201 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 242 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
202 243
203 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 244 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
204 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); 245 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false);
205 246
206 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 247 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
207 //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)));
208 Assert.That( 249 Assert.That(
209 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); 250 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
210 251
211 scene.Update(); 252 m_scene.Update(1);
212 253
213 // We should really check the exact figure. 254 // We should really check the exact figure.
214 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); 255 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -216,8 +257,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
216 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 257 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
217 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); 258 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
218 259
219 for (int i = 0; i < 10; i++) 260 m_scene.Update(10);
220 scene.Update();
221 261
222 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); 262 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
223 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); 263 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
@@ -227,14 +267,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
227 // Try a second movement 267 // Try a second movement
228 startPos = npc.AbsolutePosition; 268 startPos = npc.AbsolutePosition;
229 targetPos = startPos + new Vector3(10, 0, 0); 269 targetPos = startPos + new Vector3(10, 0, 0);
230 npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); 270 m_npcMod.MoveToTarget(npc.UUID, m_scene, targetPos, false, false);
231 271
232 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 272 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
233// 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)));
234 Assert.That( 274 Assert.That(
235 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); 275 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
236 276
237 scene.Update(); 277 m_scene.Update(1);
238 278
239 // We should really check the exact figure. 279 // We should really check the exact figure.
240 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); 280 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -242,8 +282,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
242 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 282 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
243 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 283 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
244 284
245 for (int i = 0; i < 10; i++) 285 m_scene.Update(10);
246 scene.Update();
247 286
248 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); 287 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
249 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); 288 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");
@@ -256,17 +295,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
256 TestHelpers.InMethod(); 295 TestHelpers.InMethod();
257// log4net.Config.XmlConfigurator.Configure(); 296// log4net.Config.XmlConfigurator.Configure();
258 297
259 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 298 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
260 299
261 Vector3 startPos = new Vector3(128, 128, 30); 300 Vector3 startPos = new Vector3(128, 128, 30);
262 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 301 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
263 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
264 302
265 ScenePresence npc = scene.GetScenePresence(npcId); 303 ScenePresence npc = m_scene.GetScenePresence(npcId);
266 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 304 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
267 305
268 part.SitTargetPosition = new Vector3(0, 0, 1); 306 part.SitTargetPosition = new Vector3(0, 0, 1);
269 npcModule.Sit(npc.UUID, part.UUID, scene); 307 m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
270 308
271 Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId)); 309 Assert.That(part.SitTargetAvatar, Is.EqualTo(npcId));
272 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); 310 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
@@ -274,7 +312,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
274 npc.AbsolutePosition, 312 npc.AbsolutePosition,
275 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); 313 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
276 314
277 npcModule.Stand(npc.UUID, scene); 315 m_npcMod.Stand(npc.UUID, m_scene);
278 316
279 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 317 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
280 Assert.That(npc.ParentID, Is.EqualTo(0)); 318 Assert.That(npc.ParentID, Is.EqualTo(0));
@@ -286,19 +324,18 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
286 TestHelpers.InMethod(); 324 TestHelpers.InMethod();
287// log4net.Config.XmlConfigurator.Configure(); 325// log4net.Config.XmlConfigurator.Configure();
288 326
289 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 327 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
290 328
291 // FIXME: To get this to work for now, we are going to place the npc right next to the target so that 329 // FIXME: To get this to work for now, we are going to place the npc right next to the target so that
292 // the autopilot doesn't trigger 330 // the autopilot doesn't trigger
293 Vector3 startPos = new Vector3(1, 1, 1); 331 Vector3 startPos = new Vector3(1, 1, 1);
294 332
295 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 333 UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
296 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
297 334
298 ScenePresence npc = scene.GetScenePresence(npcId); 335 ScenePresence npc = m_scene.GetScenePresence(npcId);
299 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 336 SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
300 337
301 npcModule.Sit(npc.UUID, part.UUID, scene); 338 m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
302 339
303 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 340 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
304 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId)); 341 Assert.That(npc.ParentID, Is.EqualTo(part.LocalId));
@@ -311,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
311 npc.AbsolutePosition, 348 npc.AbsolutePosition,
312 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); 349 Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f)));
313 350
314 npcModule.Stand(npc.UUID, scene); 351 m_npcMod.Stand(npc.UUID, m_scene);
315 352
316 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); 353 Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
317 Assert.That(npc.ParentID, Is.EqualTo(0)); 354 Assert.That(npc.ParentID, Is.EqualTo(0));
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 0cab5d1..b08d5db 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -94,7 +94,7 @@ public class BSCharacter : PhysicsActor
94 _flying = isFlying; 94 _flying = isFlying;
95 _orientation = Quaternion.Identity; 95 _orientation = Quaternion.Identity;
96 _velocity = Vector3.Zero; 96 _velocity = Vector3.Zero;
97 _buoyancy = isFlying ? 1f : 0f; 97 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
98 _scale = new Vector3(1f, 1f, 1f); 98 _scale = new Vector3(1f, 1f, 1f);
99 _density = _scene.Params.avatarDensity; 99 _density = _scene.Params.avatarDensity;
100 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 100 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
@@ -110,7 +110,7 @@ public class BSCharacter : PhysicsActor
110 shapeData.Buoyancy = _buoyancy; 110 shapeData.Buoyancy = _buoyancy;
111 shapeData.Static = ShapeData.numericFalse; 111 shapeData.Static = ShapeData.numericFalse;
112 shapeData.Friction = _scene.Params.avatarFriction; 112 shapeData.Friction = _scene.Params.avatarFriction;
113 shapeData.Restitution = _scene.Params.defaultRestitution; 113 shapeData.Restitution = _scene.Params.avatarRestitution;
114 114
115 // do actual create at taint time 115 // do actual create at taint time
116 _scene.TaintedObject(delegate() 116 _scene.TaintedObject(delegate()
@@ -260,13 +260,13 @@ public class BSCharacter : PhysicsActor
260 get { return _flying; } 260 get { return _flying; }
261 set { 261 set {
262 _flying = value; 262 _flying = value;
263 _scene.TaintedObject(delegate() 263 // simulate flying by changing the effect of gravity
264 { 264 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
265 // simulate flying by changing the effect of gravity
266 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _flying ? 1f : 0f);
267 });
268 } 265 }
269 } 266 }
267 private float ComputeBuoyancyFromFlying(bool ifFlying) {
268 return ifFlying ? 1f : 0f;
269 }
270 public override bool 270 public override bool
271 SetAlwaysRun { 271 SetAlwaysRun {
272 get { return _setAlwaysRun; } 272 get { return _setAlwaysRun; }
@@ -299,6 +299,7 @@ public class BSCharacter : PhysicsActor
299 get { return _kinematic; } 299 get { return _kinematic; }
300 set { _kinematic = value; } 300 set { _kinematic = value; }
301 } 301 }
302 // neg=fall quickly, 0=1g, 1=0g, pos=float up
302 public override float Buoyancy { 303 public override float Buoyancy {
303 get { return _buoyancy; } 304 get { return _buoyancy; }
304 set { _buoyancy = value; 305 set { _buoyancy = value;
@@ -355,7 +356,7 @@ public class BSCharacter : PhysicsActor
355 } 356 }
356 else 357 else
357 { 358 {
358 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); 359 m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader);
359 } 360 }
360 //m_lastUpdateSent = false; 361 //m_lastUpdateSent = false;
361 } 362 }
@@ -425,6 +426,8 @@ public class BSCharacter : PhysicsActor
425 } 426 }
426 } 427 }
427 428
429 // Called by the scene when a collision with this object is reported
430 CollisionEventUpdate collisionCollection = null;
428 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) 431 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
429 { 432 {
430 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 433 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
@@ -442,10 +445,24 @@ public class BSCharacter : PhysicsActor
442 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; 445 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
443 _lastCollisionTime = nowTime; 446 _lastCollisionTime = nowTime;
444 447
445 Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>(); 448 if (collisionCollection == null)
446 contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 449 collisionCollection = new CollisionEventUpdate();
447 CollisionEventUpdate args = new CollisionEventUpdate(contactPoints); 450 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
448 base.SendCollisionUpdate(args); 451 }
452
453 public void SendCollisions()
454 {
455 // if (collisionCollection != null)
456 // {
457 // base.SendCollisionUpdate(collisionCollection);
458 // collisionCollection = null;
459 // }
460 // Kludge to make a collision call even if there are no collisions.
461 // This causes the avatar animation to get updated.
462 if (collisionCollection == null)
463 collisionCollection = new CollisionEventUpdate();
464 base.SendCollisionUpdate(collisionCollection);
465 collisionCollection = null;
449 } 466 }
450 467
451} 468}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 046726d..eb20eb3 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -821,7 +821,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
821 */ 821 */
822 822
823 // Get what the body is doing, this includes 'external' influences 823 // Get what the body is doing, this includes 'external' influences
824 Vector3 angularVelocity = m_prim.AngularVelocity; 824 Vector3 angularVelocity = m_prim.RotationalVelocity;
825 // Vector3 angularVelocity = Vector3.Zero; 825 // Vector3 angularVelocity = Vector3.Zero;
826 826
827 if (m_angularMotorApply > 0) 827 if (m_angularMotorApply > 0)
@@ -910,7 +910,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
910 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; 910 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
911 911
912 // Apply to the body 912 // Apply to the body
913 m_prim.AngularVelocity = m_lastAngularVelocity; 913 m_prim.RotationalVelocity = m_lastAngularVelocity;
914 914
915 } //end MoveAngular 915 } //end MoveAngular
916 internal void LimitRotation(float timestep) 916 internal void LimitRotation(float timestep)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 898436b..248d1f2 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -85,7 +85,6 @@ public sealed class BSPrim : PhysicsActor
85 private OMV.Vector3 _rotationalVelocity; 85 private OMV.Vector3 _rotationalVelocity;
86 private bool _kinematic; 86 private bool _kinematic;
87 private float _buoyancy; 87 private float _buoyancy;
88 private OMV.Vector3 _angularVelocity;
89 88
90 private List<BSPrim> _childrenPrims; 89 private List<BSPrim> _childrenPrims;
91 private BSPrim _parentPrim; 90 private BSPrim _parentPrim;
@@ -119,7 +118,6 @@ public sealed class BSPrim : PhysicsActor
119 _buoyancy = 1f; 118 _buoyancy = 1f;
120 _velocity = OMV.Vector3.Zero; 119 _velocity = OMV.Vector3.Zero;
121 _rotationalVelocity = OMV.Vector3.Zero; 120 _rotationalVelocity = OMV.Vector3.Zero;
122 _angularVelocity = OMV.Vector3.Zero;
123 _hullKey = 0; 121 _hullKey = 0;
124 _meshKey = 0; 122 _meshKey = 0;
125 _pbs = pbs; 123 _pbs = pbs;
@@ -146,7 +144,7 @@ public sealed class BSPrim : PhysicsActor
146 // called when this prim is being destroyed and we should free all the resources 144 // called when this prim is being destroyed and we should free all the resources
147 public void Destroy() 145 public void Destroy()
148 { 146 {
149 // m_log.DebugFormat("{0}: Destroy", LogHeader); 147 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
150 // Undo any vehicle properties 148 // Undo any vehicle properties
151 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE); 149 _vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
152 _scene.RemoveVehiclePrim(this); // just to make sure 150 _scene.RemoveVehiclePrim(this); // just to make sure
@@ -203,7 +201,7 @@ public sealed class BSPrim : PhysicsActor
203 201
204 // link me to the specified parent 202 // link me to the specified parent
205 public override void link(PhysicsActor obj) { 203 public override void link(PhysicsActor obj) {
206 BSPrim parent = (BSPrim)obj; 204 BSPrim parent = obj as BSPrim;
207 // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); 205 // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
208 // TODO: decide if this parent checking needs to happen at taint time 206 // TODO: decide if this parent checking needs to happen at taint time
209 if (_parentPrim == null) 207 if (_parentPrim == null)
@@ -527,10 +525,6 @@ public sealed class BSPrim : PhysicsActor
527 }); 525 });
528 } 526 }
529 } 527 }
530 public OMV.Vector3 AngularVelocity {
531 get { return _angularVelocity; }
532 set { _angularVelocity = value; }
533 }
534 public override bool Kinematic { 528 public override bool Kinematic {
535 get { return _kinematic; } 529 get { return _kinematic; }
536 set { _kinematic = value; 530 set { _kinematic = value;
@@ -993,7 +987,7 @@ public sealed class BSPrim : PhysicsActor
993 } 987 }
994 988
995 // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", 989 // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
996 // LogHeader, _localID, _meshKey, indices.Length, vertices.Count); 990 // LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
997 BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, 991 BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices,
998 vertices.Count, verticesAsFloats); 992 vertices.Count, verticesAsFloats);
999 993
@@ -1127,7 +1121,7 @@ public sealed class BSPrim : PhysicsActor
1127 return; 1121 return;
1128 } 1122 }
1129 1123
1130 // Create an object in Bullet 1124 // Create an object in Bullet if it has not already been created
1131 // No locking here because this is done when the physics engine is not simulating 1125 // No locking here because this is done when the physics engine is not simulating
1132 private void CreateObject() 1126 private void CreateObject()
1133 { 1127 {
@@ -1324,13 +1318,15 @@ public sealed class BSPrim : PhysicsActor
1324 _velocity = entprop.Velocity; 1318 _velocity = entprop.Velocity;
1325 _acceleration = entprop.Acceleration; 1319 _acceleration = entprop.Acceleration;
1326 _rotationalVelocity = entprop.RotationalVelocity; 1320 _rotationalVelocity = entprop.RotationalVelocity;
1327 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); 1321 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
1322 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1328 base.RequestPhysicsterseUpdate(); 1323 base.RequestPhysicsterseUpdate();
1329 } 1324 }
1330 } 1325 }
1331 } 1326 }
1332 1327
1333 // I've collided with something 1328 // I've collided with something
1329 CollisionEventUpdate collisionCollection = null;
1334 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1330 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1335 { 1331 {
1336 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1332 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
@@ -1348,11 +1344,18 @@ public sealed class BSPrim : PhysicsActor
1348 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return; 1344 if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
1349 _lastCollisionTime = nowTime; 1345 _lastCollisionTime = nowTime;
1350 1346
1351 // create the event for the collision 1347 if (collisionCollection == null)
1352 Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>(); 1348 collisionCollection = new CollisionEventUpdate();
1353 contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 1349 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
1354 CollisionEventUpdate args = new CollisionEventUpdate(contactPoints); 1350 }
1355 base.SendCollisionUpdate(args); 1351
1352 public void SendCollisions()
1353 {
1354 if (collisionCollection != null)
1355 {
1356 base.SendCollisionUpdate(collisionCollection);
1357 collisionCollection = null;
1358 }
1356 } 1359 }
1357} 1360}
1358} 1361}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index e9a849c..94a0ccf 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -37,14 +37,18 @@ using OpenMetaverse;
37using OpenSim.Region.Framework; 37using OpenSim.Region.Framework;
38 38
39// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) 39// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
40// Debug linkset
41// Test with multiple regions in one simulator
40// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) 42// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
41// Test sculpties 43// Test sculpties
42// Compute physics FPS reasonably 44// Compute physics FPS reasonably
43// Based on material, set density and friction 45// Based on material, set density and friction
44// More efficient memory usage in passing hull information from BSPrim to BulletSim 46// More efficient memory usage when passing hull information from BSPrim to BulletSim
45// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? 47// Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly?
46// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) 48// In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground)
47// At the moment, physical and phantom causes object to drop through the terrain 49// At the moment, physical and phantom causes object to drop through the terrain
50// Physical phantom objects and related typing (collision options )
51// Check out llVolumeDetect. Must do something for that.
48// Should prim.link() and prim.delink() membership checking happen at taint time? 52// Should prim.link() and prim.delink() membership checking happen at taint time?
49// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once 53// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
50// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect 54// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
@@ -52,6 +56,16 @@ using OpenSim.Region.Framework;
52// Implement LockAngularMotion 56// Implement LockAngularMotion
53// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) 57// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
54// Does NeedsMeshing() really need to exclude all the different shapes? 58// Does NeedsMeshing() really need to exclude all the different shapes?
59// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet.
60// Add PID movement operations. What does ScenePresence.MoveToTarget do?
61// Check terrain size. 128 or 127?
62// Multiple contact points on collision?
63// See code in ode::near... calls to collision_accounting_events()
64// (This might not be a problem. ODE collects all the collisions with one object in one tick.)
65// Use collision masks for collision with terrain and phantom objects
66// Figure out how to not allocate a new Dictionary and List for every collision
67// in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused?
68// Raycast
55// 69//
56namespace OpenSim.Region.Physics.BulletSPlugin 70namespace OpenSim.Region.Physics.BulletSPlugin
57{ 71{
@@ -64,6 +78,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
64 78
65 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 79 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
66 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 80 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
81 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
82 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
67 private List<BSPrim> m_vehicles = new List<BSPrim>(); 83 private List<BSPrim> m_vehicles = new List<BSPrim>();
68 private float[] m_heightMap; 84 private float[] m_heightMap;
69 private float m_waterLevel; 85 private float m_waterLevel;
@@ -164,6 +180,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
164 if (m_log.IsDebugEnabled) 180 if (m_log.IsDebugEnabled)
165 { 181 {
166 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 182 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
183 // the handle is saved to it doesn't get freed after this call
167 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 184 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
168 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); 185 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
169 } 186 }
@@ -172,7 +189,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
172 189
173 mesher = meshmerizer; 190 mesher = meshmerizer;
174 // The bounding box for the simulated world 191 // The bounding box for the simulated world
175 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 4096f); 192 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
176 193
177 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 194 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
178 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), 195 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
@@ -220,10 +237,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters
220 parms.terrainFriction = 0.5f; 237 parms.terrainFriction = 0.5f;
221 parms.terrainHitFraction = 0.8f; 238 parms.terrainHitFraction = 0.8f;
222 parms.terrainRestitution = 0f; 239 parms.terrainRestitution = 0f;
223 parms.avatarFriction = 0.0f; 240 parms.avatarFriction = 0.5f;
241 parms.avatarRestitution = 0.0f;
224 parms.avatarDensity = 60f; 242 parms.avatarDensity = 60f;
225 parms.avatarCapsuleRadius = 0.37f; 243 parms.avatarCapsuleRadius = 0.37f;
226 parms.avatarCapsuleHeight = 1.5f; // 2.140599f 244 parms.avatarCapsuleHeight = 1.5f; // 2.140599f
245 parms.avatarContactProcessingThreshold = 0.1f;
246
247 parms.maxPersistantManifoldPoolSize = 0f;
248 parms.shouldDisableContactPoolDynamicAllocation = ConfigurationParameters.numericTrue;
249 parms.shouldForceUpdateAllAabbs = ConfigurationParameters.numericFalse;
250 parms.shouldRandomizeSolverOrder = ConfigurationParameters.numericFalse;
251 parms.shouldSplitSimulationIslands = ConfigurationParameters.numericFalse;
252 parms.shouldEnableFrictionCaching = ConfigurationParameters.numericFalse;
253 parms.numberOfSolverIterations = 0f; // means use default
227 254
228 if (config != null) 255 if (config != null)
229 { 256 {
@@ -265,14 +292,40 @@ public class BSScene : PhysicsScene, IPhysicsParameters
265 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); 292 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
266 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution); 293 parms.terrainRestitution = pConfig.GetFloat("TerrainRestitution", parms.terrainRestitution);
267 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction); 294 parms.avatarFriction = pConfig.GetFloat("AvatarFriction", parms.avatarFriction);
295 parms.avatarRestitution = pConfig.GetFloat("AvatarRestitution", parms.avatarRestitution);
268 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity); 296 parms.avatarDensity = pConfig.GetFloat("AvatarDensity", parms.avatarDensity);
269 parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius); 297 parms.avatarCapsuleRadius = pConfig.GetFloat("AvatarCapsuleRadius", parms.avatarCapsuleRadius);
270 parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight); 298 parms.avatarCapsuleHeight = pConfig.GetFloat("AvatarCapsuleHeight", parms.avatarCapsuleHeight);
299 parms.avatarContactProcessingThreshold = pConfig.GetFloat("AvatarContactProcessingThreshold", parms.avatarContactProcessingThreshold);
300
301 parms.maxPersistantManifoldPoolSize = pConfig.GetFloat("MaxPersistantManifoldPoolSize", parms.maxPersistantManifoldPoolSize);
302 parms.shouldDisableContactPoolDynamicAllocation = ParamBoolean(pConfig, "ShouldDisableContactPoolDynamicAllocation", parms.shouldDisableContactPoolDynamicAllocation);
303 parms.shouldForceUpdateAllAabbs = ParamBoolean(pConfig, "ShouldForceUpdateAllAabbs", parms.shouldForceUpdateAllAabbs);
304 parms.shouldRandomizeSolverOrder = ParamBoolean(pConfig, "ShouldRandomizeSolverOrder", parms.shouldRandomizeSolverOrder);
305 parms.shouldSplitSimulationIslands = ParamBoolean(pConfig, "ShouldSplitSimulationIslands", parms.shouldSplitSimulationIslands);
306 parms.shouldEnableFrictionCaching = ParamBoolean(pConfig, "ShouldEnableFrictionCaching", parms.shouldEnableFrictionCaching);
307 parms.numberOfSolverIterations = pConfig.GetFloat("NumberOfSolverIterations", parms.numberOfSolverIterations);
271 } 308 }
272 } 309 }
273 m_params[0] = parms; 310 m_params[0] = parms;
274 } 311 }
275 312
313 // A helper function that handles a true/false parameter and returns the proper float number encoding
314 float ParamBoolean(IConfig config, string parmName, float deflt)
315 {
316 float ret = deflt;
317 if (config.Contains(parmName))
318 {
319 ret = ConfigurationParameters.numericFalse;
320 if (config.GetBoolean(parmName, false))
321 {
322 ret = ConfigurationParameters.numericTrue;
323 }
324 }
325 return ret;
326 }
327
328
276 // Called directly from unmanaged code so don't do much 329 // Called directly from unmanaged code so don't do much
277 private void BulletLogger(string msg) 330 private void BulletLogger(string msg)
278 { 331 {
@@ -384,6 +437,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
384 } 437 }
385 } 438 }
386 439
440 // The SendCollision's batch up the collisions on the objects. Now push the collisions into the simulator.
441 foreach (BSPrim bsp in m_primsWithCollisions)
442 bsp.SendCollisions();
443 m_primsWithCollisions.Clear();
444 // foreach (BSCharacter bsc in m_avatarsWithCollisions)
445 // bsc.SendCollisions();
446 // This is a kludge to get avatar movement updated. ODE sends collisions even if there isn't any
447 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
448 kvp.Value.SendCollisions();
449 m_avatarsWithCollisions.Clear();
450
387 // If any of the objects had updated properties, tell the object it has been changed by the physics engine 451 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
388 if (updatedEntityCount > 0) 452 if (updatedEntityCount > 0)
389 { 453 {
@@ -391,16 +455,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
391 { 455 {
392 EntityProperties entprop = m_updateArray[ii]; 456 EntityProperties entprop = m_updateArray[ii];
393 // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position); 457 // m_log.DebugFormat("{0}: entprop[{1}]: id={2}, pos={3}", LogHeader, ii, entprop.ID, entprop.Position);
394 BSCharacter actor;
395 if (m_avatars.TryGetValue(entprop.ID, out actor))
396 {
397 actor.UpdateProperties(entprop);
398 continue;
399 }
400 BSPrim prim; 458 BSPrim prim;
401 if (m_prims.TryGetValue(entprop.ID, out prim)) 459 if (m_prims.TryGetValue(entprop.ID, out prim))
402 { 460 {
403 prim.UpdateProperties(entprop); 461 prim.UpdateProperties(entprop);
462 continue;
463 }
464 BSCharacter actor;
465 if (m_avatars.TryGetValue(entprop.ID, out actor))
466 {
467 actor.UpdateProperties(entprop);
404 } 468 }
405 } 469 }
406 } 470 }
@@ -434,11 +498,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
434 BSPrim prim; 498 BSPrim prim;
435 if (m_prims.TryGetValue(localID, out prim)) { 499 if (m_prims.TryGetValue(localID, out prim)) {
436 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 500 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
501 m_primsWithCollisions.Add(prim);
437 return; 502 return;
438 } 503 }
439 BSCharacter actor; 504 BSCharacter actor;
440 if (m_avatars.TryGetValue(localID, out actor)) { 505 if (m_avatars.TryGetValue(localID, out actor)) {
441 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 506 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
507 m_avatarsWithCollisions.Add(actor);
442 return; 508 return;
443 } 509 }
444 return; 510 return;
@@ -470,12 +536,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
470 536
471 public override void DeleteTerrain() 537 public override void DeleteTerrain()
472 { 538 {
473 m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 539 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
474 } 540 }
475 541
476 public override void Dispose() 542 public override void Dispose()
477 { 543 {
478 m_log.DebugFormat("{0}: Dispose()", LogHeader); 544 // m_log.DebugFormat("{0}: Dispose()", LogHeader);
479 } 545 }
480 546
481 public override Dictionary<uint, float> GetTopColliders() 547 public override Dictionary<uint, float> GetTopColliders()
@@ -699,9 +765,23 @@ public class BSScene : PhysicsScene, IPhysicsParameters
699 new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ), 765 new PhysParameterEntry("DeactivationTime", "Seconds before considering an object potentially static" ),
700 new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ), 766 new PhysParameterEntry("LinearSleepingThreshold", "Seconds to measure linear movement before considering static" ),
701 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), 767 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
702 // new PhysParameterEntry("CcdMotionThreshold", "" ), 768 new PhysParameterEntry("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ),
703 // new PhysParameterEntry("CcdSweptSphereRadius", "" ), 769 new PhysParameterEntry("CcdSweptSphereRadius", "Continuious collision detection test radius" ),
704 new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ), 770 new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ),
771 // Can only change the following at initialization time. Change the INI file and reboot.
772 new PhysParameterEntry("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)"),
773 new PhysParameterEntry("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count"),
774 new PhysParameterEntry("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step"),
775 new PhysParameterEntry("ShouldRandomizeSolverOrder", "Enable for slightly better stacking interaction"),
776 new PhysParameterEntry("ShouldSplitSimulationIslands", "Enable splitting active object scanning islands"),
777 new PhysParameterEntry("ShouldEnableFrictionCaching", "Enable friction computation caching"),
778 new PhysParameterEntry("NumberOfSolverIterations", "Number of internal iterations (0 means default)"),
779
780 new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
781 new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
782
783 new PhysParameterEntry("Friction", "Set friction parameter for a specific object" ),
784 new PhysParameterEntry("Restitution", "Set restitution parameter for a specific object" ),
705 785
706 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), 786 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
707 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), 787 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
@@ -710,7 +790,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
710 new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ), 790 new PhysParameterEntry("AvatarDensity", "Density of an avatar. Changed on avatar recreation." ),
711 new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ), 791 new PhysParameterEntry("AvatarRestitution", "Bouncyness. Changed on avatar recreation." ),
712 new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ), 792 new PhysParameterEntry("AvatarCapsuleRadius", "Radius of space around an avatar" ),
713 new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ) 793 new PhysParameterEntry("AvatarCapsuleHeight", "Default height of space around avatar" ),
794 new PhysParameterEntry("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions")
795
714 }; 796 };
715 797
716 #region IPhysicsParameters 798 #region IPhysicsParameters
@@ -733,6 +815,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
733 switch (lparm) 815 switch (lparm)
734 { 816 {
735 case "detailedstats": m_detailedStatsStep = (int)val; break; 817 case "detailedstats": m_detailedStatsStep = (int)val; break;
818
736 case "meshlod": m_meshLOD = (int)val; break; 819 case "meshlod": m_meshLOD = (int)val; break;
737 case "sculptlod": m_sculptLOD = (int)val; break; 820 case "sculptlod": m_sculptLOD = (int)val; break;
738 case "maxsubstep": m_maxSubSteps = (int)val; break; 821 case "maxsubstep": m_maxSubSteps = (int)val; break;
@@ -743,7 +826,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
743 case "defaultdensity": m_params[0].defaultDensity = val; break; 826 case "defaultdensity": m_params[0].defaultDensity = val; break;
744 case "defaultrestitution": m_params[0].defaultRestitution = val; break; 827 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
745 case "collisionmargin": m_params[0].collisionMargin = val; break; 828 case "collisionmargin": m_params[0].collisionMargin = val; break;
746 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; 829 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, localID, val); break;
747 830
748 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; 831 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
749 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; 832 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
@@ -753,6 +836,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
753 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; 836 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
754 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; 837 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
755 case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break; 838 case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break;
839 // the following are used only at initialization time so setting them makes no sense
840 // case "maxPersistantmanifoldpoolSize": m_params[0].maxPersistantManifoldPoolSize = val; break;
841 // case "shoulddisablecontactpooldynamicallocation": m_params[0].shouldDisableContactPoolDynamicAllocation = val; break;
842 // case "shouldforceupdateallaabbs": m_params[0].shouldForceUpdateAllAabbs = val; break;
843 // case "shouldrandomizesolverorder": m_params[0].shouldRandomizeSolverOrder = val; break;
844 // case "shouldsplitsimulationislands": m_params[0].shouldSplitSimulationIslands = val; break;
845 // case "shouldenablefrictioncaching": m_params[0].shouldEnableFrictionCaching = val; break;
846 // case "numberofsolveriterations": m_params[0].numberOfSolverIterations = val; break;
847
848 case "friction": TaintedUpdateParameter(lparm, localID, val); break;
849 case "restitution": TaintedUpdateParameter(lparm, localID, val); break;
756 850
757 // set a terrain physical feature and cause terrain to be recalculated 851 // set a terrain physical feature and cause terrain to be recalculated
758 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; 852 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
@@ -764,6 +858,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
764 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; 858 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
765 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; 859 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
766 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; 860 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
861 case "avatarcontactprocessingthreshold": UpdateParameterAvatars(ref m_params[0].avatarContactProcessingThreshold, "avatar", localID, val); break;
767 862
768 default: ret = false; break; 863 default: ret = false; break;
769 } 864 }
@@ -856,6 +951,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
856 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; 951 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
857 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; 952 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
858 case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break; 953 case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break;
954 case "maxPersistantmanifoldpoolSize": val = m_params[0].maxPersistantManifoldPoolSize; break;
955 case "shoulddisablecontactpooldynamicallocation": val = m_params[0].shouldDisableContactPoolDynamicAllocation; break;
956 case "shouldforceupdateallaabbs": val = m_params[0].shouldForceUpdateAllAabbs; break;
957 case "shouldrandomizesolverorder": val = m_params[0].shouldRandomizeSolverOrder; break;
958 case "shouldsplitsimulationislands": val = m_params[0].shouldSplitSimulationIslands; break;
959 case "shouldenablefrictioncaching": val = m_params[0].shouldEnableFrictionCaching; break;
960 case "numberofsolveriterations": val = m_params[0].numberOfSolverIterations; break;
859 961
860 case "terrainfriction": val = m_params[0].terrainFriction; break; 962 case "terrainfriction": val = m_params[0].terrainFriction; break;
861 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; 963 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
@@ -866,6 +968,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
866 case "avatarrestitution": val = m_params[0].avatarRestitution; break; 968 case "avatarrestitution": val = m_params[0].avatarRestitution; break;
867 case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break; 969 case "avatarcapsuleradius": val = m_params[0].avatarCapsuleRadius; break;
868 case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break; 970 case "avatarcapsuleheight": val = m_params[0].avatarCapsuleHeight; break;
971 case "avatarcontactprocessingthreshold": val = m_params[0].avatarContactProcessingThreshold; break;
869 default: ret = false; break; 972 default: ret = false; break;
870 973
871 } 974 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index d12bd7d..086f0dc 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -132,6 +132,15 @@ public struct ConfigurationParameters
132 public float avatarRestitution; 132 public float avatarRestitution;
133 public float avatarCapsuleRadius; 133 public float avatarCapsuleRadius;
134 public float avatarCapsuleHeight; 134 public float avatarCapsuleHeight;
135 public float avatarContactProcessingThreshold;
136
137 public float maxPersistantManifoldPoolSize;
138 public float shouldDisableContactPoolDynamicAllocation;
139 public float shouldForceUpdateAllAabbs;
140 public float shouldRandomizeSolverOrder;
141 public float shouldSplitSimulationIslands;
142 public float shouldEnableFrictionCaching;
143 public float numberOfSolverIterations;
135 144
136 public const float numericTrue = 1f; 145 public const float numericTrue = 1f;
137 public const float numericFalse = 0f; 146 public const float numericFalse = 0f;
@@ -149,16 +158,16 @@ public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
149 int maxUpdates, IntPtr updateArray); 158 int maxUpdates, IntPtr updateArray);
150 159
151[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 160[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
152public static extern bool UpdateParameter(uint worldID, uint localID,
153 [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
154
155[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
156public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); 161public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
157 162
158[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 163[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
159public static extern void Shutdown(uint worldID); 164public static extern void Shutdown(uint worldID);
160 165
166[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
167public static extern bool UpdateParameter(uint worldID, uint localID,
168 [MarshalAs(UnmanagedType.LPStr)]string paramCode, float value);
161 169
170// ===============================================================================
162[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 171[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
163public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep, 172public static extern int PhysicsStep(uint worldID, float timeStep, int maxSubSteps, float fixedTimeStep,
164 out int updatedEntityCount, 173 out int updatedEntityCount,
@@ -240,6 +249,7 @@ public static extern bool HasObject(uint worldID, uint id);
240[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 249[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
241public static extern bool DestroyObject(uint worldID, uint id); 250public static extern bool DestroyObject(uint worldID, uint id);
242 251
252// ===============================================================================
243[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 253[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
244public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin); 254public static extern SweepHit ConvexSweepTest(uint worldID, uint id, Vector3 to, float extraMargin);
245 255
@@ -249,6 +259,7 @@ public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vec
249[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 259[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
250public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); 260public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
251 261
262// ===============================================================================
252[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 263[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
253public static extern void DumpBulletStatistics(); 264public static extern void DumpBulletStatistics();
254 265
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 6f6ed7f..3bd15ce 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.Physics.Meshing
358 358
359 if (physicsParms == null) 359 if (physicsParms == null)
360 { 360 {
361 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 361 m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
362 return false; 362 return false;
363 } 363 }
364 364
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6d1f41d..8397eb4 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -115,6 +115,11 @@ namespace OpenSim.Region.Physics.OdePlugin
115 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. 115 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
116 116
117 /// <summary> 117 /// <summary>
118 /// Base movement for calculating tilt.
119 /// </summary>
120 private float m_tiltBaseMovement = (float)Math.Sqrt(2);
121
122 /// <summary>
118 /// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider 123 /// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
119 /// </summary> 124 /// </summary>
120 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; 125 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f;
@@ -524,14 +529,14 @@ namespace OpenSim.Region.Physics.OdePlugin
524 if (movementVector.Y > 0) 529 if (movementVector.Y > 0)
525 { 530 {
526 // northeast 531 // northeast
527 movementVector.X = (float)Math.Sqrt(2.0); 532 movementVector.X = m_tiltBaseMovement;
528 movementVector.Y = (float)Math.Sqrt(2.0); 533 movementVector.Y = m_tiltBaseMovement;
529 } 534 }
530 else 535 else
531 { 536 {
532 // southeast 537 // southeast
533 movementVector.X = (float)Math.Sqrt(2.0); 538 movementVector.X = m_tiltBaseMovement;
534 movementVector.Y = -(float)Math.Sqrt(2.0); 539 movementVector.Y = -m_tiltBaseMovement;
535 } 540 }
536 } 541 }
537 else 542 else
@@ -540,14 +545,14 @@ namespace OpenSim.Region.Physics.OdePlugin
540 if (movementVector.Y > 0) 545 if (movementVector.Y > 0)
541 { 546 {
542 // northwest 547 // northwest
543 movementVector.X = -(float)Math.Sqrt(2.0); 548 movementVector.X = -m_tiltBaseMovement;
544 movementVector.Y = (float)Math.Sqrt(2.0); 549 movementVector.Y = m_tiltBaseMovement;
545 } 550 }
546 else 551 else
547 { 552 {
548 // southwest 553 // southwest
549 movementVector.X = -(float)Math.Sqrt(2.0); 554 movementVector.X = -m_tiltBaseMovement;
550 movementVector.Y = -(float)Math.Sqrt(2.0); 555 movementVector.Y = -m_tiltBaseMovement;
551 } 556 }
552 } 557 }
553 558
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 97890ee..1f79cd8 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -842,17 +842,23 @@ namespace OpenSim.Region.Physics.OdePlugin
842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
843 843
844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
845 if (m_MeshToTriMeshMap.ContainsKey(mesh))
846 {
847 _triMeshData = m_MeshToTriMeshMap[mesh];
848 }
849 else
850 {
851 _triMeshData = d.GeomTriMeshDataCreate();
852 845
853 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 846 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
854 d.GeomTriMeshDataPreprocess(_triMeshData); 847 // the same time.
855 m_MeshToTriMeshMap[mesh] = _triMeshData; 848 lock (m_MeshToTriMeshMap)
849 {
850 if (m_MeshToTriMeshMap.ContainsKey(mesh))
851 {
852 _triMeshData = m_MeshToTriMeshMap[mesh];
853 }
854 else
855 {
856 _triMeshData = d.GeomTriMeshDataCreate();
857
858 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
859 d.GeomTriMeshDataPreprocess(_triMeshData);
860 m_MeshToTriMeshMap[mesh] = _triMeshData;
861 }
856 } 862 }
857 863
858// _parent_scene.waitForSpaceUnlock(m_targetSpace); 864// _parent_scene.waitForSpaceUnlock(m_targetSpace);
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 598530c..842ff91 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -181,8 +181,15 @@ namespace OpenSim.Region.Physics.OdePlugin
181 private float avPIDP = 1400f; 181 private float avPIDP = 1400f;
182 private float avCapRadius = 0.37f; 182 private float avCapRadius = 0.37f;
183 private float avStandupTensor = 2000000f; 183 private float avStandupTensor = 2000000f;
184 private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode 184
185 public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } } 185 /// <summary>
186 /// true = old compatibility mode with leaning capsule; false = new corrected mode
187 /// </summary>
188 /// <remarks>
189 /// Even when set to false, the capsule still tilts but this is done in a different way.
190 /// </remarks>
191 public bool IsAvCapsuleTilted { get; private set; }
192
186 private float avDensity = 80f; 193 private float avDensity = 80f;
187// private float avHeightFudgeFactor = 0.52f; 194// private float avHeightFudgeFactor = 0.52f;
188 private float avMovementDivisorWalk = 1.3f; 195 private float avMovementDivisorWalk = 1.3f;
@@ -501,7 +508,7 @@ namespace OpenSim.Region.Physics.OdePlugin
501 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); 508 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
502 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); 509 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
503 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 510 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
504 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); 511 IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false);
505 512
506 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 513 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
507 514
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index 09da97a..a142f26 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -712,33 +712,16 @@ namespace OpenSim.Region.RegionCombinerModule
712 712
713 List<Vector3> CoarseLocations = new List<Vector3>(); 713 List<Vector3> CoarseLocations = new List<Vector3>();
714 List<UUID> AvatarUUIDs = new List<UUID>(); 714 List<UUID> AvatarUUIDs = new List<UUID>();
715
715 connectiondata.RegionScene.ForEachRootScenePresence(delegate(ScenePresence sp) 716 connectiondata.RegionScene.ForEachRootScenePresence(delegate(ScenePresence sp)
716 { 717 {
717 if (sp.UUID != presence.UUID) 718 if (sp.UUID != presence.UUID)
718 { 719 {
719 if (sp.ParentID != 0) 720 CoarseLocations.Add(sp.AbsolutePosition);
720 { 721 AvatarUUIDs.Add(sp.UUID);
721 // sitting avatar
722 SceneObjectPart sop = connectiondata.RegionScene.GetSceneObjectPart(sp.ParentID);
723 if (sop != null)
724 {
725 CoarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition);
726 AvatarUUIDs.Add(sp.UUID);
727 }
728 else
729 {
730 // we can't find the parent.. ! arg!
731 CoarseLocations.Add(sp.AbsolutePosition);
732 AvatarUUIDs.Add(sp.UUID);
733 }
734 }
735 else
736 {
737 CoarseLocations.Add(sp.AbsolutePosition);
738 AvatarUUIDs.Add(sp.UUID);
739 }
740 } 722 }
741 }); 723 });
724
742 DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence); 725 DistributeCourseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
743 } 726 }
744 727
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index d3200d5..b04f6b6 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -68,14 +68,48 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
68 /// </summary> 68 /// </summary>
69 bool Suspended { get; set; } 69 bool Suspended { get; set; }
70 70
71 /// <summary>
72 /// Is the script shutting down?
73 /// </summary>
71 bool ShuttingDown { get; set; } 74 bool ShuttingDown { get; set; }
75
76 /// <summary>
77 /// Script state
78 /// </summary>
72 string State { get; set; } 79 string State { get; set; }
80
81 /// <summary>
82 /// Time the script was last started
83 /// </summary>
84 DateTime TimeStarted { get; }
85
86 /// <summary>
87 /// Tick the last measurement period was started.
88 /// </summary>
89 long MeasurementPeriodTickStart { get; }
90
91 /// <summary>
92 /// Ticks spent executing in the last measurement period.
93 /// </summary>
94 long MeasurementPeriodExecutionTime { get; }
95
73 IScriptEngine Engine { get; } 96 IScriptEngine Engine { get; }
74 UUID AppDomain { get; set; } 97 UUID AppDomain { get; set; }
75 string PrimName { get; } 98 string PrimName { get; }
76 string ScriptName { get; } 99 string ScriptName { get; }
77 UUID ItemID { get; } 100 UUID ItemID { get; }
78 UUID ObjectID { get; } 101 UUID ObjectID { get; }
102
103 /// <summary>
104 /// UUID of the root object for the linkset that the script is in.
105 /// </summary>
106 UUID RootObjectID { get; }
107
108 /// <summary>
109 /// Local id of the root object for the linkset that the script is in.
110 /// </summary>
111 uint RootLocalID { get; }
112
79 uint LocalID { get; } 113 uint LocalID { get; }
80 UUID AssetID { get; } 114 UUID AssetID { get; }
81 Queue EventQueue { get; } 115 Queue EventQueue { get; }
@@ -89,7 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
89 void Start(); 123 void Start();
90 124
91 /// <summary> 125 /// <summary>
92 /// Stop the script. 126 /// Stop the script instance.
93 /// </summary> 127 /// </summary>
94 /// <param name="timeout"></param> 128 /// <param name="timeout"></param>
95 /// <returns>true if the script was successfully stopped, false otherwise</returns> 129 /// <returns>true if the script was successfully stopped, false otherwise</returns>
@@ -97,13 +131,17 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
97 131
98 void SetState(string state); 132 void SetState(string state);
99 133
134 /// <summary>
135 /// Post an event to this script instance.
136 /// </summary>
137 /// <param name="data"></param>
100 void PostEvent(EventParams data); 138 void PostEvent(EventParams data);
101 139
102 void Suspend(); 140 void Suspend();
103 void Resume(); 141 void Resume();
104 142
105 /// <summary> 143 /// <summary>
106 /// Process the next event queued for this script 144 /// Process the next event queued for this script instance.
107 /// </summary> 145 /// </summary>
108 /// <returns></returns> 146 /// <returns></returns>
109 object EventProcessor(); 147 object EventProcessor();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 14edde4..993d10f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -247,7 +247,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
247 247
248 // Remove Sensors 248 // Remove Sensors
249 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); 249 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
250 }
251
252 /// <summary>
253 /// Get the sensor repeat plugin for this script engine.
254 /// </summary>
255 /// <param name="engine"></param>
256 /// <returns></returns>
257 public static SensorRepeat GetSensorRepeatPlugin(IScriptEngine engine)
258 {
259 if (m_SensorRepeat.ContainsKey(engine))
260 return m_SensorRepeat[engine];
261 else
262 return null;
263 }
250 264
265 /// <summary>
266 /// Get the dataserver plugin for this script engine.
267 /// </summary>
268 /// <param name="engine"></param>
269 /// <returns></returns>
270 public static Dataserver GetDataserverPlugin(IScriptEngine engine)
271 {
272 if (m_Dataserver.ContainsKey(engine))
273 return m_Dataserver[engine];
274 else
275 return null;
276 }
277
278 /// <summary>
279 /// Get the timer plugin for this script engine.
280 /// </summary>
281 /// <param name="engine"></param>
282 /// <returns></returns>
283 public static Timer GetTimerPlugin(IScriptEngine engine)
284 {
285 if (m_Timer.ContainsKey(engine))
286 return m_Timer[engine];
287 else
288 return null;
289 }
290
291 /// <summary>
292 /// Get the listener plugin for this script engine.
293 /// </summary>
294 /// <param name="engine"></param>
295 /// <returns></returns>
296 public static Listener GetListenerPlugin(IScriptEngine engine)
297 {
298 if (m_Listener.ContainsKey(engine))
299 return m_Listener[engine];
300 else
301 return null;
251 } 302 }
252 303
253 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
@@ -270,7 +321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
270 data.AddRange(timers); 321 data.AddRange(timers);
271 } 322 }
272 323
273 Object[] sensors=m_SensorRepeat[engine].GetSerializationData(itemID); 324 Object[] sensors = m_SensorRepeat[engine].GetSerializationData(itemID);
274 if (sensors.Length > 0) 325 if (sensors.Length > 0)
275 { 326 {
276 data.Add("sensor"); 327 data.Add("sensor");
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0003515..d7a629b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2771,64 +2771,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2771 { 2771 {
2772 m_host.AddScriptLPS(1); 2772 m_host.AddScriptLPS(1);
2773 2773
2774 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) 2774 Util.FireAndForget(delegate (object x)
2775 return; 2775 {
2776 float dist = (float)llVecDist(llGetPos(), pos); 2776 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
2777 return;
2778 float dist = (float)llVecDist(llGetPos(), pos);
2777 2779
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2780 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2781 return;
2780 2782
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2783 //Clone is thread-safe
2784 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2785
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2786 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
2784 {
2785 if (inv.Value.Name == inventory)
2786 { 2787 {
2787 // make sure we're an object. 2788 if (inv.Value.Name == inventory)
2788 if (inv.Value.InvType != (int)InventoryType.Object)
2789 { 2789 {
2790 llSay(0, "Unable to create requested object. Object is missing from database."); 2790 // make sure we're an object.
2791 return; 2791 if (inv.Value.InvType != (int)InventoryType.Object)
2792 } 2792 {
2793 llSay(0, "Unable to create requested object. Object is missing from database.");
2794 return;
2795 }
2793 2796
2794 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); 2797 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
2795 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); 2798 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
2796 2799
2797 // need the magnitude later 2800 // need the magnitude later
2798 float velmag = (float)Util.GetMagnitude(llvel); 2801 // float velmag = (float)Util.GetMagnitude(llvel);
2799 2802
2800 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param); 2803 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
2801 2804
2802 // If either of these are null, then there was an unknown error. 2805 // If either of these are null, then there was an unknown error.
2803 if (new_group == null) 2806 if (new_group == null)
2804 continue; 2807 continue;
2805 2808
2806 // objects rezzed with this method are die_at_edge by default. 2809 // objects rezzed with this method are die_at_edge by default.
2807 new_group.RootPart.SetDieAtEdge(true); 2810 new_group.RootPart.SetDieAtEdge(true);
2808 2811
2809 new_group.ResumeScripts(); 2812 new_group.ResumeScripts();
2810 2813
2811 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( 2814 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
2812 "object_rez", new Object[] { 2815 "object_rez", new Object[] {
2813 new LSL_String( 2816 new LSL_String(
2814 new_group.RootPart.UUID.ToString()) }, 2817 new_group.RootPart.UUID.ToString()) },
2815 new DetectParams[0])); 2818 new DetectParams[0]));
2816 2819
2817 float groupmass = new_group.GetMass(); 2820 float groupmass = new_group.GetMass();
2818 2821
2819 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero) 2822 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
2820 { 2823 {
2821 //Recoil. 2824 //Recoil.
2822 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 2825 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
2826 }
2827 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
2828 return;
2823 } 2829 }
2824 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
2825 ScriptSleep((int)((groupmass * velmag) / 10));
2826 ScriptSleep(100);
2827 return;
2828 } 2830 }
2829 }
2830 2831
2831 llSay(0, "Could not find object " + inventory); 2832 llSay(0, "Could not find object " + inventory);
2833 });
2834
2835 //ScriptSleep((int)((groupmass * velmag) / 10));
2836 ScriptSleep(100);
2832 } 2837 }
2833 2838
2834 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 2839 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
@@ -3820,7 +3825,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3820 List<String> nametable = new List<String>(); 3825 List<String> nametable = new List<String>();
3821 World.ForEachRootScenePresence(delegate(ScenePresence presence) 3826 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3822 { 3827 {
3823 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID)) 3828 SceneObjectPart sitPart = presence.ParentPart;
3829 if (sitPart != null && m_host.ParentGroup.HasChildPrim(sitPart.LocalId))
3824 nametable.Add(presence.ControllingClient.Name); 3830 nametable.Add(presence.ControllingClient.Name);
3825 }); 3831 });
3826 3832
@@ -4308,7 +4314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4308 4314
4309 if (m_host.RegionHandle == presence.RegionHandle) 4315 if (m_host.RegionHandle == presence.RegionHandle)
4310 { 4316 {
4311 Dictionary<UUID, string> animationstateNames = AnimationSet.Animations.AnimStateNames; 4317 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4312 4318
4313 if (presence != null) 4319 if (presence != null)
4314 { 4320 {
@@ -4388,22 +4394,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4388 4394
4389 // Find pushee position 4395 // Find pushee position
4390 // Pushee Linked? 4396 // Pushee Linked?
4391 if (pusheeav.ParentID != 0) 4397 SceneObjectPart sitPart = pusheeav.ParentPart;
4392 { 4398 if (sitPart != null)
4393 SceneObjectPart parentobj = World.GetSceneObjectPart(pusheeav.ParentID); 4399 PusheePos = sitPart.AbsolutePosition;
4394 if (parentobj != null)
4395 {
4396 PusheePos = parentobj.AbsolutePosition;
4397 }
4398 else
4399 {
4400 PusheePos = pusheeav.AbsolutePosition;
4401 }
4402 }
4403 else 4400 else
4404 {
4405 PusheePos = pusheeav.AbsolutePosition; 4401 PusheePos = pusheeav.AbsolutePosition;
4406 }
4407 } 4402 }
4408 4403
4409 if (!pusheeIsAvatar) 4404 if (!pusheeIsAvatar)
@@ -5598,14 +5593,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5598 flags |= ScriptBaseClass.AGENT_IN_AIR; 5593 flags |= ScriptBaseClass.AGENT_IN_AIR;
5599 } 5594 }
5600 5595
5601 if (agent.ParentID != 0) 5596 if (agent.ParentPart != null)
5602 { 5597 {
5603 flags |= ScriptBaseClass.AGENT_ON_OBJECT; 5598 flags |= ScriptBaseClass.AGENT_ON_OBJECT;
5604 flags |= ScriptBaseClass.AGENT_SITTING; 5599 flags |= ScriptBaseClass.AGENT_SITTING;
5605 } 5600 }
5606 5601
5607 if (agent.Animator.Animations.DefaultAnimation.AnimID 5602 if (agent.Animator.Animations.DefaultAnimation.AnimID
5608 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 5603 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
5609 { 5604 {
5610 flags |= ScriptBaseClass.AGENT_SITTING; 5605 flags |= ScriptBaseClass.AGENT_SITTING;
5611 } 5606 }
@@ -7687,7 +7682,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7687 World.ForEachRootScenePresence(delegate(ScenePresence presence) 7682 World.ForEachRootScenePresence(delegate(ScenePresence presence)
7688 { 7683 {
7689 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID)) 7684 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7690 avatarCount++; 7685 avatarCount++;
7691 }); 7686 });
7692 7687
7693 return m_host.ParentGroup.PrimCount + avatarCount; 7688 return m_host.ParentGroup.PrimCount + avatarCount;
@@ -7719,7 +7714,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7719 LSL_Vector lower; 7714 LSL_Vector lower;
7720 LSL_Vector upper; 7715 LSL_Vector upper;
7721 if (presence.Animator.Animations.DefaultAnimation.AnimID 7716 if (presence.Animator.Animations.DefaultAnimation.AnimID
7722 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7717 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7723 { 7718 {
7724 // This is for ground sitting avatars 7719 // This is for ground sitting avatars
7725 float height = presence.Appearance.AvatarHeight / 2.66666667f; 7720 float height = presence.Appearance.AvatarHeight / 2.66666667f;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index d4facdd..7c07e15 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -116,6 +116,159 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
116 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 116 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
117 } 117 }
118 118
119 /// <summary>
120 ///
121 /// </summary>
122 /// <param name="fname">The name of the function to invoke</param>
123 /// <param name="parms">List of parameters</param>
124 /// <returns>string result of the invocation</returns>
125 public void modInvokeN(string fname, params object[] parms)
126 {
127 Type returntype = m_comms.LookupReturnType(fname);
128 if (returntype != typeof(string))
129 MODError(String.Format("return type mismatch for {0}",fname));
130
131 modInvoke(fname,parms);
132 }
133
134 public LSL_String modInvokeS(string fname, params object[] parms)
135 {
136 Type returntype = m_comms.LookupReturnType(fname);
137 if (returntype != typeof(string))
138 MODError(String.Format("return type mismatch for {0}",fname));
139
140 string result = (string)modInvoke(fname,parms);
141 return new LSL_String(result);
142 }
143
144 public LSL_Integer modInvokeI(string fname, params object[] parms)
145 {
146 Type returntype = m_comms.LookupReturnType(fname);
147 if (returntype != typeof(int))
148 MODError(String.Format("return type mismatch for {0}",fname));
149
150 int result = (int)modInvoke(fname,parms);
151 return new LSL_Integer(result);
152 }
153
154 public LSL_Float modInvokeF(string fname, params object[] parms)
155 {
156 Type returntype = m_comms.LookupReturnType(fname);
157 if (returntype != typeof(float))
158 MODError(String.Format("return type mismatch for {0}",fname));
159
160 float result = (float)modInvoke(fname,parms);
161 return new LSL_Float(result);
162 }
163
164 public LSL_Key modInvokeK(string fname, params object[] parms)
165 {
166 Type returntype = m_comms.LookupReturnType(fname);
167 if (returntype != typeof(UUID))
168 MODError(String.Format("return type mismatch for {0}",fname));
169
170 UUID result = (UUID)modInvoke(fname,parms);
171 return new LSL_Key(result.ToString());
172 }
173
174 public LSL_Vector modInvokeV(string fname, params object[] parms)
175 {
176 Type returntype = m_comms.LookupReturnType(fname);
177 if (returntype != typeof(OpenMetaverse.Vector3))
178 MODError(String.Format("return type mismatch for {0}",fname));
179
180 OpenMetaverse.Vector3 result = (OpenMetaverse.Vector3)modInvoke(fname,parms);
181 return new LSL_Vector(result.X,result.Y,result.Z);
182 }
183
184 public LSL_Rotation modInvokeR(string fname, params object[] parms)
185 {
186 Type returntype = m_comms.LookupReturnType(fname);
187 if (returntype != typeof(OpenMetaverse.Quaternion))
188 MODError(String.Format("return type mismatch for {0}",fname));
189
190 OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname,parms);
191 return new LSL_Rotation(result.X,result.Y,result.Z,result.W);
192 }
193
194 public LSL_List modInvokeL(string fname, params object[] parms)
195 {
196 Type returntype = m_comms.LookupReturnType(fname);
197 if (returntype != typeof(object[]))
198 MODError(String.Format("return type mismatch for {0}",fname));
199
200 object[] result = (object[])modInvoke(fname,parms);
201 object[] llist = new object[result.Length];
202 for (int i = 0; i < result.Length; i++)
203 {
204 if (result[i] is string)
205 llist[i] = new LSL_String((string)result[i]);
206 else if (result[i] is int)
207 llist[i] = new LSL_Integer((int)result[i]);
208 else if (result[i] is float)
209 llist[i] = new LSL_Float((float)result[i]);
210 else if (result[i] is OpenMetaverse.Vector3)
211 {
212 OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i];
213 llist[i] = new LSL_Vector(vresult.X,vresult.Y,vresult.Z);
214 }
215 else if (result[i] is OpenMetaverse.Quaternion)
216 {
217 OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i];
218 llist[i] = new LSL_Rotation(qresult.X,qresult.Y,qresult.Z,qresult.W);
219 }
220 else
221 {
222 MODError(String.Format("unknown list element returned by {0}",fname));
223 }
224 }
225
226 return new LSL_List(llist);
227 }
228
229 /// <summary>
230 /// Invokes a preregistered function through the ScriptModuleComms class
231 /// </summary>
232 /// <param name="fname">The name of the function to invoke</param>
233 /// <param name="fname">List of parameters</param>
234 /// <returns>string result of the invocation</returns>
235 protected object modInvoke(string fname, params object[] parms)
236 {
237 if (!m_MODFunctionsEnabled)
238 {
239 MODShoutError("Module command functions not enabled");
240 return "";
241 }
242
243 Type[] signature = m_comms.LookupTypeSignature(fname);
244 if (signature.Length != parms.Length)
245 MODError(String.Format("wrong number of parameters to function {0}",fname));
246
247 object[] convertedParms = new object[parms.Length];
248 for (int i = 0; i < parms.Length; i++)
249 convertedParms[i] = ConvertFromLSL(parms[i],signature[i]);
250
251 // now call the function, the contract with the function is that it will always return
252 // non-null but don't trust it completely
253 try
254 {
255 object result = m_comms.InvokeOperation(m_host.UUID, m_itemID, fname, convertedParms);
256 if (result != null)
257 return result;
258
259 MODError(String.Format("Invocation of {0} failed; null return value",fname));
260 }
261 catch (Exception e)
262 {
263 MODError(String.Format("Invocation of {0} failed; {1}",fname,e.Message));
264 }
265
266 return null;
267 }
268
269 /// <summary>
270 /// Send a command to functions registered on an event
271 /// </summary>
119 public string modSendCommand(string module, string command, string k) 272 public string modSendCommand(string module, string command, string k)
120 { 273 {
121 if (!m_MODFunctionsEnabled) 274 if (!m_MODFunctionsEnabled)
@@ -130,5 +283,101 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
130 283
131 return req.ToString(); 284 return req.ToString();
132 } 285 }
286
287 /// <summary>
288 /// </summary>
289 protected object ConvertFromLSL(object lslparm, Type type)
290 {
291 // ---------- String ----------
292 if (lslparm is LSL_String)
293 {
294 if (type == typeof(string))
295 return (string)(LSL_String)lslparm;
296
297 // Need to check for UUID since keys are often treated as strings
298 if (type == typeof(UUID))
299 return new UUID((string)(LSL_String)lslparm);
300 }
301
302 // ---------- Integer ----------
303 else if (lslparm is LSL_Integer)
304 {
305 if (type == typeof(int))
306 return (int)(LSL_Integer)lslparm;
307 }
308
309 // ---------- Float ----------
310 else if (lslparm is LSL_Float)
311 {
312 if (type == typeof(float))
313 return (float)(LSL_Float)lslparm;
314 }
315
316 // ---------- Key ----------
317 else if (lslparm is LSL_Key)
318 {
319 if (type == typeof(UUID))
320 return new UUID((LSL_Key)lslparm);
321 }
322
323 // ---------- Rotation ----------
324 else if (lslparm is LSL_Rotation)
325 {
326 if (type == typeof(OpenMetaverse.Quaternion))
327 {
328 LSL_Rotation rot = (LSL_Rotation)lslparm;
329 return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
330 }
331 }
332
333 // ---------- Vector ----------
334 else if (lslparm is LSL_Vector)
335 {
336 if (type == typeof(OpenMetaverse.Vector3))
337 {
338 LSL_Vector vect = (LSL_Vector)lslparm;
339 return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
340 }
341 }
342
343 // ---------- List ----------
344 else if (lslparm is LSL_List)
345 {
346 if (type == typeof(object[]))
347 {
348 object[] plist = (lslparm as LSL_List).Data;
349 object[] result = new object[plist.Length];
350 for (int i = 0; i < plist.Length; i++)
351 {
352 if (plist[i] is LSL_String)
353 result[i] = (string)(LSL_String)plist[i];
354 else if (plist[i] is LSL_Integer)
355 result[i] = (int)(LSL_Integer)plist[i];
356 else if (plist[i] is LSL_Float)
357 result[i] = (float)(LSL_Float)plist[i];
358 else if (plist[i] is LSL_Key)
359 result[i] = new UUID((LSL_Key)plist[i]);
360 else if (plist[i] is LSL_Rotation)
361 {
362 LSL_Rotation rot = (LSL_Rotation)plist[i];
363 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
364 }
365 else if (plist[i] is LSL_Vector)
366 {
367 LSL_Vector vect = (LSL_Vector)plist[i];
368 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
369 }
370 else
371 MODError("unknown LSL list element type");
372 }
373
374 return result;
375 }
376 }
377
378 MODError(String.Format("parameter type mismatch; expecting {0}",type.Name));
379 return null;
380 }
381
133 } 382 }
134} 383}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8edd146..2ecd890 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2093,6 +2093,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2093 return HomeURI; 2093 return HomeURI;
2094 } 2094 }
2095 2095
2096 public string osGetGridGatekeeperURI()
2097 {
2098 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI");
2099 m_host.AddScriptLPS(1);
2100
2101 string gatekeeperURI = String.Empty;
2102 IConfigSource config = m_ScriptEngine.ConfigSource;
2103
2104 if (config.Configs["GridService"] != null)
2105 gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI);
2106
2107 return gatekeeperURI;
2108 }
2109
2096 public string osGetGridCustom(string key) 2110 public string osGetGridCustom(string key)
2097 { 2111 {
2098 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom"); 2112 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom");
@@ -2943,5 +2957,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2943 2957
2944 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2958 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2945 } 2959 }
2960
2961 /// <summary>
2962 /// Get the description from an inventory item
2963 /// </summary>
2964 /// <param name="inventoryName"></param>
2965 /// <returns>Item description</returns>
2966 public LSL_String osGetInventoryDesc(string item)
2967 {
2968 m_host.AddScriptLPS(1);
2969
2970 lock (m_host.TaskInventory)
2971 {
2972 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
2973 {
2974 if (inv.Value.Name == item)
2975 {
2976 return inv.Value.Description.ToString();
2977 }
2978 }
2979 }
2980
2981 return String.Empty;
2982 }
2946 } 2983 }
2947} \ No newline at end of file 2984} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs
index 7fa19b1..9f78a49 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs
@@ -38,6 +38,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
38 { 38 {
39 public AsyncCommandManager m_CmdManager; 39 public AsyncCommandManager m_CmdManager;
40 40
41 public int DataserverRequestsCount
42 {
43 get
44 {
45 lock (DataserverRequests)
46 return DataserverRequests.Count;
47 }
48 }
49
41 private Dictionary<string, DataserverRequest> DataserverRequests = 50 private Dictionary<string, DataserverRequest> DataserverRequests =
42 new Dictionary<string, DataserverRequest>(); 51 new Dictionary<string, DataserverRequest>();
43 52
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs
index 740816f..93e0261 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Listener.cs
@@ -42,22 +42,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
42 42
43 public AsyncCommandManager m_CmdManager; 43 public AsyncCommandManager m_CmdManager;
44 44
45 private IWorldComm m_commsPlugin;
46
47 public int ListenerCount
48 {
49 get { return m_commsPlugin.ListenerCount; }
50 }
51
45 public Listener(AsyncCommandManager CmdManager) 52 public Listener(AsyncCommandManager CmdManager)
46 { 53 {
47 m_CmdManager = CmdManager; 54 m_CmdManager = CmdManager;
55 m_commsPlugin = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
48 } 56 }
49 57
50 public void CheckListeners() 58 public void CheckListeners()
51 { 59 {
52 if (m_CmdManager.m_ScriptEngine.World == null) 60 if (m_CmdManager.m_ScriptEngine.World == null)
53 return; 61 return;
54 IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
55 62
56 if (comms != null) 63 if (m_commsPlugin != null)
57 { 64 {
58 while (comms.HasMessages()) 65 while (m_commsPlugin.HasMessages())
59 { 66 {
60 ListenerInfo lInfo = (ListenerInfo)comms.GetNextMessage(); 67 ListenerInfo lInfo = (ListenerInfo)m_commsPlugin.GetNextMessage();
61 68
62 //Deliver data to prim's listen handler 69 //Deliver data to prim's listen handler
63 object[] resobj = new object[] 70 object[] resobj = new object[]
@@ -81,17 +88,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
81 88
82 public Object[] GetSerializationData(UUID itemID) 89 public Object[] GetSerializationData(UUID itemID)
83 { 90 {
84 IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 91 return m_commsPlugin.GetSerializationData(itemID);
85
86 return comms.GetSerializationData(itemID);
87 } 92 }
88 93
89 public void CreateFromData(uint localID, UUID itemID, UUID hostID, 94 public void CreateFromData(uint localID, UUID itemID, UUID hostID,
90 Object[] data) 95 Object[] data)
91 { 96 {
92 IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 97 m_commsPlugin.CreateFromData(localID, itemID, hostID, data);
93
94 comms.CreateFromData(localID, itemID, hostID, data);
95 } 98 }
96 } 99 }
97} 100} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fbb7c39..1c272f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -44,6 +44,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
44 44
45 public AsyncCommandManager m_CmdManager; 45 public AsyncCommandManager m_CmdManager;
46 46
47 /// <summary>
48 /// Number of sensors active.
49 /// </summary>
50 public int SensorsCount
51 {
52 get
53 {
54 lock (SenseRepeatListLock)
55 return SenseRepeaters.Count;
56 }
57 }
58
47 public SensorRepeat(AsyncCommandManager CmdManager) 59 public SensorRepeat(AsyncCommandManager CmdManager)
48 { 60 {
49 m_CmdManager = CmdManager; 61 m_CmdManager = CmdManager;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..bc63030 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -37,6 +37,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
37 { 37 {
38 public AsyncCommandManager m_CmdManager; 38 public AsyncCommandManager m_CmdManager;
39 39
40 public int TimersCount
41 {
42 get
43 {
44 lock (TimerListLock)
45 return Timers.Count;
46 }
47 }
48
40 public Timer(AsyncCommandManager CmdManager) 49 public Timer(AsyncCommandManager CmdManager)
41 { 50 {
42 m_CmdManager = CmdManager; 51 m_CmdManager = CmdManager;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
index e08eca5..aa78aaa 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
@@ -28,18 +28,28 @@
28using System.Collections; 28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces; 29using OpenSim.Region.ScriptEngine.Interfaces;
30 30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 31using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 32using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 33using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 36using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 37using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38 38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{ 40{
41 public interface IMOD_Api 41 public interface IMOD_Api
42 { 42 {
43 // Invocation functions
44 void modInvokeN(string fname, params object[] parms);
45 LSL_String modInvokeS(string fname, params object[] parms);
46 LSL_Integer modInvokeI(string fname, params object[] parms);
47 LSL_Float modInvokeF(string fname, params object[] parms);
48 LSL_Key modInvokeK(string fname, params object[] parms);
49 LSL_Vector modInvokeV(string fname, params object[] parms);
50 LSL_Rotation modInvokeR(string fname, params object[] parms);
51 LSL_List modInvokeL(string fname, params object[] parms);
52
43 //Module functions 53 //Module functions
44 string modSendCommand(string modules, string command, string k); 54 string modSendCommand(string modules, string command, string k);
45 } 55 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 82a6caf..8f9efc0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -161,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
161 string osGetGridName(); 161 string osGetGridName();
162 string osGetGridLoginURI(); 162 string osGetGridLoginURI();
163 string osGetGridHomeURI(); 163 string osGetGridHomeURI();
164 string osGetGridGatekeeperURI();
164 string osGetGridCustom(string key); 165 string osGetGridCustom(string key);
165 166
166 LSL_String osFormatString(string str, LSL_List strings); 167 LSL_String osFormatString(string str, LSL_List strings);
@@ -228,5 +229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
228 LSL_List osGetAvatarList(); 229 LSL_List osGetAvatarList();
229 230
230 LSL_String osUnixTimeToTimestamp(long time); 231 LSL_String osUnixTimeToTimestamp(long time);
232
233 LSL_String osGetInventoryDesc(string item);
231 } 234 }
232} 235}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
index 6525c76..1c47138 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
@@ -39,10 +39,14 @@ using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 42
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 43using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 44using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
45using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
46using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
47using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
48using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
46 50
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 51namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{ 52{
@@ -58,6 +62,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
58 m_MOD_Functions = (IMOD_Api)api; 62 m_MOD_Functions = (IMOD_Api)api;
59 } 63 }
60 64
65 public void modInvokeN(string fname, params object[] parms)
66 {
67 m_MOD_Functions.modInvokeN(fname, parms);
68 }
69
70 public LSL_String modInvokeS(string fname, params object[] parms)
71 {
72 return m_MOD_Functions.modInvokeS(fname, parms);
73 }
74
75 public LSL_Integer modInvokeI(string fname, params object[] parms)
76 {
77 return m_MOD_Functions.modInvokeI(fname, parms);
78 }
79
80 public LSL_Float modInvokeF(string fname, params object[] parms)
81 {
82 return m_MOD_Functions.modInvokeF(fname, parms);
83 }
84
85 public LSL_Key modInvokeK(string fname, params object[] parms)
86 {
87 return m_MOD_Functions.modInvokeK(fname, parms);
88 }
89
90 public LSL_Vector modInvokeV(string fname, params object[] parms)
91 {
92 return m_MOD_Functions.modInvokeV(fname, parms);
93 }
94
95 public LSL_Rotation modInvokeR(string fname, params object[] parms)
96 {
97 return m_MOD_Functions.modInvokeR(fname, parms);
98 }
99
100 public LSL_List modInvokeL(string fname, params object[] parms)
101 {
102 return m_MOD_Functions.modInvokeL(fname, parms);
103 }
104
61 public string modSendCommand(string module, string command, string k) 105 public string modSendCommand(string module, string command, string k)
62 { 106 {
63 return m_MOD_Functions.modSendCommand(module, command, k); 107 return m_MOD_Functions.modSendCommand(module, command, k);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 4341246..09e5992 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -457,6 +457,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
457 return m_OSSL_Functions.osGetGridHomeURI(); 457 return m_OSSL_Functions.osGetGridHomeURI();
458 } 458 }
459 459
460 public string osGetGridGatekeeperURI()
461 {
462 return m_OSSL_Functions.osGetGridGatekeeperURI();
463 }
464
460 public string osGetGridCustom(string key) 465 public string osGetGridCustom(string key)
461 { 466 {
462 return m_OSSL_Functions.osGetGridCustom(key); 467 return m_OSSL_Functions.osGetGridCustom(key);
@@ -858,5 +863,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
858 { 863 {
859 return m_OSSL_Functions.osUnixTimeToTimestamp(time); 864 return m_OSSL_Functions.osUnixTimeToTimestamp(time);
860 } 865 }
866
867 public LSL_String osGetInventoryDesc(string item)
868 {
869 return m_OSSL_Functions.osGetInventoryDesc(item);
870 }
861 } 871 }
862} 872}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs
index 04357a9..09a9a08 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/IndexedAnswers.cs
@@ -226,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
226 break; 226 break;
227 } 227 }
228 } 228 }
229 229 int z = 0;
230 try 230 try
231 { 231 {
232 if (gotMatch) 232 if (gotMatch)
@@ -235,8 +235,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
235 finally 235 finally
236 { 236 {
237 // Manually finalize all the iterators. 237 // Manually finalize all the iterators.
238 for (int i = 0; i < nIterators; ++i) 238 for (z = 0; z < nIterators; ++z)
239 iterators[i].Dispose(); 239 iterators[z].Dispose();
240 } 240 }
241 } 241 }
242 } 242 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs
index d8f44c1..f2171dd 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/YieldProlog/YP.cs
@@ -576,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
576 break; 576 break;
577 } 577 }
578 } 578 }
579 579 int z = 0;
580 try 580 try
581 { 581 {
582 if (gotMatch) 582 if (gotMatch)
@@ -585,8 +585,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.YieldProlog
585 finally 585 finally
586 { 586 {
587 // Manually finalize all the iterators. 587 // Manually finalize all the iterators.
588 for (int i = 0; i < nIterators; ++i) 588 for (z = 0; z < nIterators; ++z)
589 iterators[i].Dispose(); 589 iterators[z].Dispose();
590 } 590 }
591 } 591 }
592 592
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 8b88588..b24f016 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -32,6 +32,8 @@ using System.Reflection;
32using log4net; 32using log4net;
33using Tools; 33using Tools;
34 34
35using OpenSim.Region.Framework.Interfaces;
36
35namespace OpenSim.Region.ScriptEngine.Shared.CodeTools 37namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
36{ 38{
37 public class CSCodeGenerator : ICodeConverter 39 public class CSCodeGenerator : ICodeConverter
@@ -45,12 +47,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
45 private int m_CSharpLine; // the current line of generated C# code 47 private int m_CSharpLine; // the current line of generated C# code
46 private int m_CSharpCol; // the current column of generated C# code 48 private int m_CSharpCol; // the current column of generated C# code
47 private List<string> m_warnings = new List<string>(); 49 private List<string> m_warnings = new List<string>();
50 private IScriptModuleComms m_comms = null;
48 51
49 /// <summary> 52 /// <summary>
50 /// Creates an 'empty' CSCodeGenerator instance. 53 /// Creates an 'empty' CSCodeGenerator instance.
51 /// </summary> 54 /// </summary>
52 public CSCodeGenerator() 55 public CSCodeGenerator()
53 { 56 {
57 m_comms = null;
58 ResetCounters();
59 }
60
61 public CSCodeGenerator(IScriptModuleComms comms)
62 {
63 m_comms = comms;
54 ResetCounters(); 64 ResetCounters();
55 } 65 }
56 66
@@ -118,7 +128,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
118 emessage = emessage.Substring(slinfo.Length+2); 128 emessage = emessage.Substring(slinfo.Length+2);
119 129
120 message = String.Format("({0},{1}) {2}", 130 message = String.Format("({0},{1}) {2}",
121 e.slInfo.lineNumber - 2, 131 e.slInfo.lineNumber - 1,
122 e.slInfo.charPosition - 1, emessage); 132 e.slInfo.charPosition - 1, emessage);
123 133
124 throw new Exception(message); 134 throw new Exception(message);
@@ -866,8 +876,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
866 { 876 {
867 string retstr = String.Empty; 877 string retstr = String.Empty;
868 878
869 retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); 879 string modinvoke = null;
870 880 if (m_comms != null)
881 modinvoke = m_comms.LookupModInvocation(fc.Id);
882
883 if (modinvoke != null)
884 {
885 if (fc.kids[0] is ArgumentList)
886 {
887 if ((fc.kids[0] as ArgumentList).kids.Count == 0)
888 retstr += Generate(String.Format("{0}(\"{1}\"",modinvoke,fc.Id), fc);
889 else
890 retstr += Generate(String.Format("{0}(\"{1}\",",modinvoke,fc.Id), fc);
891 }
892 }
893 else
894 {
895 retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc);
896 }
897
871 foreach (SYMBOL kid in fc.kids) 898 foreach (SYMBOL kid in fc.kids)
872 retstr += GenerateNode(kid); 899 retstr += GenerateNode(kid);
873 900
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index c10143b..8f2ec49 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -35,6 +35,7 @@ using Microsoft.CSharp;
35//using Microsoft.JScript; 35//using Microsoft.JScript;
36using Microsoft.VisualBasic; 36using Microsoft.VisualBasic;
37using log4net; 37using log4net;
38
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.ScriptEngine.Interfaces; 40using OpenSim.Region.ScriptEngine.Interfaces;
40using OpenMetaverse; 41using OpenMetaverse;
@@ -293,6 +294,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
293 { 294 {
294// m_log.DebugFormat("[Compiler]: Compiling script\n{0}", Script); 295// m_log.DebugFormat("[Compiler]: Compiling script\n{0}", Script);
295 296
297 IScriptModuleComms comms = m_scriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
298
296 linemap = null; 299 linemap = null;
297 m_warnings.Clear(); 300 m_warnings.Clear();
298 301
@@ -382,7 +385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
382 if (language == enumCompileType.lsl) 385 if (language == enumCompileType.lsl)
383 { 386 {
384 // Its LSL, convert it to C# 387 // Its LSL, convert it to C#
385 LSL_Converter = (ICodeConverter)new CSCodeGenerator(); 388 LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms);
386 compileScript = LSL_Converter.Convert(Script); 389 compileScript = LSL_Converter.Convert(Script);
387 390
388 // copy converter warnings into our warnings. 391 // copy converter warnings into our warnings.
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs
index 63afb0b..7763619 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CSCodeGeneratorTest.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
29using System.Text.RegularExpressions; 29using System.Text.RegularExpressions;
30using NUnit.Framework; 30using NUnit.Framework;
31using OpenSim.Region.ScriptEngine.Shared.CodeTools; 31using OpenSim.Region.ScriptEngine.Shared.CodeTools;
32using OpenSim.Tests.Common;
32 33
33namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests 34namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
34{ 35{
@@ -43,6 +44,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
43 [Test] 44 [Test]
44 public void TestDefaultState() 45 public void TestDefaultState()
45 { 46 {
47 TestHelpers.InMethod();
48
46 string input = @"default 49 string input = @"default
47{ 50{
48 state_entry() 51 state_entry()
@@ -63,6 +66,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
63 [Test] 66 [Test]
64 public void TestCustomState() 67 public void TestCustomState()
65 { 68 {
69 TestHelpers.InMethod();
70
66 string input = @"default 71 string input = @"default
67{ 72{
68 state_entry() 73 state_entry()
@@ -93,6 +98,8 @@ state another_state
93 [Test] 98 [Test]
94 public void TestEventWithArguments() 99 public void TestEventWithArguments()
95 { 100 {
101 TestHelpers.InMethod();
102
96 string input = @"default 103 string input = @"default
97{ 104{
98 at_rot_target(integer tnum, rotation targetrot, rotation ourrot) 105 at_rot_target(integer tnum, rotation targetrot, rotation ourrot)
@@ -113,6 +120,8 @@ state another_state
113 [Test] 120 [Test]
114 public void TestIntegerDeclaration() 121 public void TestIntegerDeclaration()
115 { 122 {
123 TestHelpers.InMethod();
124
116 string input = @"default 125 string input = @"default
117{ 126{
118 touch_start(integer num_detected) 127 touch_start(integer num_detected)
@@ -135,6 +144,8 @@ state another_state
135 [Test] 144 [Test]
136 public void TestLoneIdent() 145 public void TestLoneIdent()
137 { 146 {
147 TestHelpers.InMethod();
148
138 // A lone ident should be removed completely as it's an error in C# 149 // A lone ident should be removed completely as it's an error in C#
139 // (MONO at least). 150 // (MONO at least).
140 string input = @"default 151 string input = @"default
@@ -161,6 +172,8 @@ state another_state
161 [Test] 172 [Test]
162 public void TestAssignments() 173 public void TestAssignments()
163 { 174 {
175 TestHelpers.InMethod();
176
164 string input = @"default 177 string input = @"default
165{ 178{
166 touch_start(integer num_detected) 179 touch_start(integer num_detected)
@@ -187,6 +200,8 @@ state another_state
187 [Test] 200 [Test]
188 public void TestAdditionSubtractionOperator() 201 public void TestAdditionSubtractionOperator()
189 { 202 {
203 TestHelpers.InMethod();
204
190 string input = @"default 205 string input = @"default
191{ 206{
192 touch_start(integer num_detected) 207 touch_start(integer num_detected)
@@ -215,6 +230,8 @@ state another_state
215 [Test] 230 [Test]
216 public void TestStrings() 231 public void TestStrings()
217 { 232 {
233 TestHelpers.InMethod();
234
218 string input = @"default 235 string input = @"default
219{ 236{
220 touch_start(integer num_detected) 237 touch_start(integer num_detected)
@@ -242,6 +259,8 @@ state another_state
242 [Test] 259 [Test]
243 public void TestBinaryExpression() 260 public void TestBinaryExpression()
244 { 261 {
262 TestHelpers.InMethod();
263
245 string input = @"default 264 string input = @"default
246{ 265{
247 touch_start(integer num_detected) 266 touch_start(integer num_detected)
@@ -284,6 +303,8 @@ state another_state
284 [Test] 303 [Test]
285 public void TestFloatConstants() 304 public void TestFloatConstants()
286 { 305 {
306 TestHelpers.InMethod();
307
287 string input = @"default 308 string input = @"default
288{ 309{
289 touch_start(integer num_detected) 310 touch_start(integer num_detected)
@@ -336,6 +357,8 @@ state another_state
336 [Test] 357 [Test]
337 public void TestComments() 358 public void TestComments()
338 { 359 {
360 TestHelpers.InMethod();
361
339 string input = @"// this test tests comments 362 string input = @"// this test tests comments
340default 363default
341{ 364{
@@ -358,6 +381,8 @@ default
358 [Test] 381 [Test]
359 public void TestStringsWithEscapedQuotesAndComments() 382 public void TestStringsWithEscapedQuotesAndComments()
360 { 383 {
384 TestHelpers.InMethod();
385
361 string input = @"// this test tests strings, with escaped quotes and comments in strings 386 string input = @"// this test tests strings, with escaped quotes and comments in strings
362default 387default
363{ 388{
@@ -397,6 +422,8 @@ default
397 [Test] 422 [Test]
398 public void TestCStyleComments() 423 public void TestCStyleComments()
399 { 424 {
425 TestHelpers.InMethod();
426
400 string input = @"/* this test tests comments 427 string input = @"/* this test tests comments
401 of the C variety 428 of the C variety
402*/ 429*/
@@ -426,6 +453,8 @@ default
426 [Test] 453 [Test]
427 public void TestGlobalDefinedFunctions() 454 public void TestGlobalDefinedFunctions()
428 { 455 {
456 TestHelpers.InMethod();
457
429 string input = @"// this test tests custom defined functions 458 string input = @"// this test tests custom defined functions
430 459
431string onefunc() 460string onefunc()
@@ -470,6 +499,8 @@ default
470 [Test] 499 [Test]
471 public void TestGlobalDeclaredVariables() 500 public void TestGlobalDeclaredVariables()
472 { 501 {
502 TestHelpers.InMethod();
503
473 string input = @"// this test tests custom defined functions and global variables 504 string input = @"// this test tests custom defined functions and global variables
474 505
475string globalString; 506string globalString;
@@ -525,6 +556,8 @@ default
525 [Test] 556 [Test]
526 public void TestMoreAssignments() 557 public void TestMoreAssignments()
527 { 558 {
559 TestHelpers.InMethod();
560
528 string input = @"// this test tests +=, -=, *=, /=, %= 561 string input = @"// this test tests +=, -=, *=, /=, %=
529 562
530string globalString; 563string globalString;
@@ -579,6 +612,8 @@ default
579 [Test] 612 [Test]
580 public void TestVectorConstantNotation() 613 public void TestVectorConstantNotation()
581 { 614 {
615 TestHelpers.InMethod();
616
582 string input = @"default 617 string input = @"default
583{ 618{
584 touch_start(integer num_detected) 619 touch_start(integer num_detected)
@@ -606,6 +641,8 @@ default
606 [Test] 641 [Test]
607 public void TestVectorMemberAccess() 642 public void TestVectorMemberAccess()
608 { 643 {
644 TestHelpers.InMethod();
645
609 string input = @"default 646 string input = @"default
610{ 647{
611 touch_start(integer num_detected) 648 touch_start(integer num_detected)
@@ -632,6 +669,8 @@ default
632 [Test] 669 [Test]
633 public void TestExpressionInParentheses() 670 public void TestExpressionInParentheses()
634 { 671 {
672 TestHelpers.InMethod();
673
635 string input = @"default 674 string input = @"default
636{ 675{
637 touch_start(integer num_detected) 676 touch_start(integer num_detected)
@@ -660,6 +699,8 @@ default
660 [Test] 699 [Test]
661 public void TestIncrementDecrementOperator() 700 public void TestIncrementDecrementOperator()
662 { 701 {
702 TestHelpers.InMethod();
703
663 string input = @"// here we'll test the ++ and -- operators 704 string input = @"// here we'll test the ++ and -- operators
664 705
665default 706default
@@ -690,6 +731,8 @@ default
690 [Test] 731 [Test]
691 public void TestLists() 732 public void TestLists()
692 { 733 {
734 TestHelpers.InMethod();
735
693 string input = @"// testing lists 736 string input = @"// testing lists
694 737
695default 738default
@@ -718,6 +761,8 @@ default
718 [Test] 761 [Test]
719 public void TestIfStatement() 762 public void TestIfStatement()
720 { 763 {
764 TestHelpers.InMethod();
765
721 string input = @"// let's test if statements 766 string input = @"// let's test if statements
722 767
723default 768default
@@ -822,6 +867,8 @@ default
822 [Test] 867 [Test]
823 public void TestIfElseStatement() 868 public void TestIfElseStatement()
824 { 869 {
870 TestHelpers.InMethod();
871
825 string input = @"// let's test complex logical expressions 872 string input = @"// let's test complex logical expressions
826 873
827default 874default
@@ -928,6 +975,8 @@ default
928 [Test] 975 [Test]
929 public void TestWhileLoop() 976 public void TestWhileLoop()
930 { 977 {
978 TestHelpers.InMethod();
979
931 string input = @"// let's test while loops 980 string input = @"// let's test while loops
932 981
933default 982default
@@ -968,6 +1017,8 @@ default
968 [Test] 1017 [Test]
969 public void TestDoWhileLoop() 1018 public void TestDoWhileLoop()
970 { 1019 {
1020 TestHelpers.InMethod();
1021
971 string input = @"// let's test do-while loops 1022 string input = @"// let's test do-while loops
972 1023
973default 1024default
@@ -1012,6 +1063,8 @@ default
1012 [Test] 1063 [Test]
1013 public void TestForLoop() 1064 public void TestForLoop()
1014 { 1065 {
1066 TestHelpers.InMethod();
1067
1015 string input = @"// let's test for loops 1068 string input = @"// let's test for loops
1016 1069
1017default 1070default
@@ -1056,6 +1109,8 @@ default
1056 [Test] 1109 [Test]
1057 public void TestFloatsWithTrailingDecimal() 1110 public void TestFloatsWithTrailingDecimal()
1058 { 1111 {
1112 TestHelpers.InMethod();
1113
1059 string input = @"// a curious feature of LSL that allows floats to be defined with a trailing dot 1114 string input = @"// a curious feature of LSL that allows floats to be defined with a trailing dot
1060 1115
1061default 1116default
@@ -1108,6 +1163,8 @@ default
1108 [Test] 1163 [Test]
1109 public void TestUnaryAndBinaryOperators() 1164 public void TestUnaryAndBinaryOperators()
1110 { 1165 {
1166 TestHelpers.InMethod();
1167
1111 string input = @"// let's test a few more operators 1168 string input = @"// let's test a few more operators
1112 1169
1113default 1170default
@@ -1144,6 +1201,8 @@ default
1144 [Test] 1201 [Test]
1145 public void TestTypecasts() 1202 public void TestTypecasts()
1146 { 1203 {
1204 TestHelpers.InMethod();
1205
1147 string input = @"// let's test typecasts 1206 string input = @"// let's test typecasts
1148 1207
1149default 1208default
@@ -1189,6 +1248,8 @@ default
1189 [Test] 1248 [Test]
1190 public void TestStates() 1249 public void TestStates()
1191 { 1250 {
1251 TestHelpers.InMethod();
1252
1192 string input = @"// let's test states 1253 string input = @"// let's test states
1193 1254
1194default 1255default
@@ -1229,6 +1290,8 @@ state statetwo
1229 [Test] 1290 [Test]
1230 public void TestHexIntegerConstants() 1291 public void TestHexIntegerConstants()
1231 { 1292 {
1293 TestHelpers.InMethod();
1294
1232 string input = @"// let's test hex integers 1295 string input = @"// let's test hex integers
1233 1296
1234default 1297default
@@ -1261,6 +1324,8 @@ default
1261 [Test] 1324 [Test]
1262 public void TestJumps() 1325 public void TestJumps()
1263 { 1326 {
1327 TestHelpers.InMethod();
1328
1264 string input = @"// let's test jumps 1329 string input = @"// let's test jumps
1265 1330
1266default 1331default
@@ -1291,6 +1356,8 @@ default
1291 [Test] 1356 [Test]
1292 public void TestImplicitVariableInitialization() 1357 public void TestImplicitVariableInitialization()
1293 { 1358 {
1359 TestHelpers.InMethod();
1360
1294 string input = @"// let's test implicitly initializing variables 1361 string input = @"// let's test implicitly initializing variables
1295 1362
1296default 1363default
@@ -1334,6 +1401,8 @@ default
1334 [Test] 1401 [Test]
1335 public void TestMultipleEqualsExpression() 1402 public void TestMultipleEqualsExpression()
1336 { 1403 {
1404 TestHelpers.InMethod();
1405
1337 string input = @"// let's test x = y = 5 type expressions 1406 string input = @"// let's test x = y = 5 type expressions
1338 1407
1339default 1408default
@@ -1366,6 +1435,8 @@ default
1366 [Test] 1435 [Test]
1367 public void TestUnaryExpressionLastInVectorConstant() 1436 public void TestUnaryExpressionLastInVectorConstant()
1368 { 1437 {
1438 TestHelpers.InMethod();
1439
1369 string input = @"// let's test unary expressions some more 1440 string input = @"// let's test unary expressions some more
1370 1441
1371default 1442default
@@ -1390,6 +1461,8 @@ default
1390 [Test] 1461 [Test]
1391 public void TestVectorMemberPlusEquals() 1462 public void TestVectorMemberPlusEquals()
1392 { 1463 {
1464 TestHelpers.InMethod();
1465
1393 string input = @"// let's test unary expressions some more 1466 string input = @"// let's test unary expressions some more
1394 1467
1395default 1468default
@@ -1424,6 +1497,8 @@ default
1424 [Test] 1497 [Test]
1425 public void TestWhileLoopWithNoBody() 1498 public void TestWhileLoopWithNoBody()
1426 { 1499 {
1500 TestHelpers.InMethod();
1501
1427 string input = @"default 1502 string input = @"default
1428{ 1503{
1429 state_entry() 1504 state_entry()
@@ -1447,6 +1522,8 @@ default
1447 [Test] 1522 [Test]
1448 public void TestDoWhileLoopWithNoBody() 1523 public void TestDoWhileLoopWithNoBody()
1449 { 1524 {
1525 TestHelpers.InMethod();
1526
1450 string input = @"default 1527 string input = @"default
1451{ 1528{
1452 state_entry() 1529 state_entry()
@@ -1472,6 +1549,8 @@ default
1472 [Test] 1549 [Test]
1473 public void TestIfWithNoBody() 1550 public void TestIfWithNoBody()
1474 { 1551 {
1552 TestHelpers.InMethod();
1553
1475 string input = @"default 1554 string input = @"default
1476{ 1555{
1477 state_entry() 1556 state_entry()
@@ -1495,6 +1574,8 @@ default
1495 [Test] 1574 [Test]
1496 public void TestIfElseWithNoBody() 1575 public void TestIfElseWithNoBody()
1497 { 1576 {
1577 TestHelpers.InMethod();
1578
1498 string input = @"default 1579 string input = @"default
1499{ 1580{
1500 state_entry() 1581 state_entry()
@@ -1521,6 +1602,8 @@ default
1521 [Test] 1602 [Test]
1522 public void TestForLoopWithNoBody() 1603 public void TestForLoopWithNoBody()
1523 { 1604 {
1605 TestHelpers.InMethod();
1606
1524 string input = @"default 1607 string input = @"default
1525{ 1608{
1526 state_entry() 1609 state_entry()
@@ -1544,6 +1627,8 @@ default
1544 [Test] 1627 [Test]
1545 public void TestForLoopWithNoAssignment() 1628 public void TestForLoopWithNoAssignment()
1546 { 1629 {
1630 TestHelpers.InMethod();
1631
1547 string input = @"default 1632 string input = @"default
1548{ 1633{
1549 state_entry() 1634 state_entry()
@@ -1569,6 +1654,8 @@ default
1569 [Test] 1654 [Test]
1570 public void TestForLoopWithOnlyIdentInAssignment() 1655 public void TestForLoopWithOnlyIdentInAssignment()
1571 { 1656 {
1657 TestHelpers.InMethod();
1658
1572 string input = @"default 1659 string input = @"default
1573{ 1660{
1574 state_entry() 1661 state_entry()
@@ -1594,6 +1681,8 @@ default
1594 [Test] 1681 [Test]
1595 public void TestAssignmentInIfWhileDoWhile() 1682 public void TestAssignmentInIfWhileDoWhile()
1596 { 1683 {
1684 TestHelpers.InMethod();
1685
1597 string input = @"default 1686 string input = @"default
1598{ 1687{
1599 state_entry() 1688 state_entry()
@@ -1631,6 +1720,8 @@ default
1631 [Test] 1720 [Test]
1632 public void TestLSLListHack() 1721 public void TestLSLListHack()
1633 { 1722 {
1723 TestHelpers.InMethod();
1724
1634 string input = @"default 1725 string input = @"default
1635{ 1726{
1636 state_entry() 1727 state_entry()
@@ -1653,9 +1744,12 @@ default
1653 } 1744 }
1654 1745
1655 [Test] 1746 [Test]
1656 [ExpectedException(typeof(System.Exception))]
1657 public void TestSyntaxError() 1747 public void TestSyntaxError()
1658 { 1748 {
1749 TestHelpers.InMethod();
1750
1751 bool gotException = false;
1752
1659 string input = @"default 1753 string input = @"default
1660{ 1754{
1661 state_entry() 1755 state_entry()
@@ -1671,17 +1765,22 @@ default
1671 } 1765 }
1672 catch (System.Exception e) 1766 catch (System.Exception e)
1673 { 1767 {
1674 // The syntax error is on line 6, char 5 (expected ';', found 1768 // The syntax error is on line 5, char 4 (expected ';', found
1675 // '}'). 1769 // '}').
1676 Assert.AreEqual("(4,4) syntax error", e.Message); 1770 Assert.AreEqual("(5,4) syntax error", e.Message);
1677 throw; 1771 gotException = true;
1678 } 1772 }
1773
1774 Assert.That(gotException, Is.True);
1679 } 1775 }
1680 1776
1681 [Test] 1777 [Test]
1682 [ExpectedException(typeof(System.Exception))]
1683 public void TestSyntaxErrorDeclaringVariableInForLoop() 1778 public void TestSyntaxErrorDeclaringVariableInForLoop()
1684 { 1779 {
1780 TestHelpers.InMethod();
1781
1782 bool gotException = false;
1783
1685 string input = @"default 1784 string input = @"default
1686{ 1785{
1687 state_entry() 1786 state_entry()
@@ -1697,11 +1796,13 @@ default
1697 } 1796 }
1698 catch (System.Exception e) 1797 catch (System.Exception e)
1699 { 1798 {
1700 // The syntax error is on line 5, char 14 (Syntax error) 1799 // The syntax error is on line 4, char 13 (Syntax error)
1701 Assert.AreEqual("(3,13) syntax error", e.Message); 1800 Assert.AreEqual("(4,13) syntax error", e.Message);
1702 1801
1703 throw; 1802 gotException = true;
1704 } 1803 }
1804
1805 Assert.That(gotException, Is.True);
1705 } 1806 }
1706 } 1807 }
1707} 1808}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs
index c5483c8..1fa6954 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using Microsoft.CSharp; 31using Microsoft.CSharp;
32using NUnit.Framework; 32using NUnit.Framework;
33using OpenSim.Region.ScriptEngine.Shared.CodeTools; 33using OpenSim.Region.ScriptEngine.Shared.CodeTools;
34using OpenSim.Tests.Common;
34 35
35namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests 36namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
36{ 37{
@@ -92,6 +93,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
92 //[Test] 93 //[Test]
93 public void TestUseUndeclaredVariable() 94 public void TestUseUndeclaredVariable()
94 { 95 {
96 TestHelpers.InMethod();
97
95 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll"); 98 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll");
96 99
97 string input = @"default 100 string input = @"default
@@ -124,6 +127,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
124 //[Test] 127 //[Test]
125 public void TestCastAndConcatString() 128 public void TestCastAndConcatString()
126 { 129 {
130 TestHelpers.InMethod();
131
127 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll"); 132 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll");
128 133
129 string input = @"string s = "" a string""; 134 string input = @"string s = "" a string"";
@@ -150,4 +155,4 @@ default
150 Assert.AreEqual(0, m_compilerResults.Errors.Count); 155 Assert.AreEqual(0, m_compilerResults.Errors.Count);
151 } 156 }
152 } 157 }
153} 158} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bc1902b..6e36742 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -56,36 +56,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 56 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 57 {
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
60 private IScriptEngine m_Engine; 60 /// <summary>
61 private IScriptWorkItem m_CurrentResult = null; 61 /// The current work item if an event for this script is running or waiting to run,
62 private Queue m_EventQueue = new Queue(32); 62 /// </summary>
63 private bool m_RunEvents = false; 63 /// <remarks>
64 private UUID m_ItemID; 64 /// Null if there is no running or waiting to run event. Must be changed only under an EventQueue lock.
65 private uint m_LocalID; 65 /// </remarks>
66 private UUID m_ObjectID; 66 private IScriptWorkItem m_CurrentWorkItem;
67 private UUID m_AssetID; 67
68 private IScript m_Script; 68 private IScript m_Script;
69 private UUID m_AppDomain;
70 private DetectParams[] m_DetectParams; 69 private DetectParams[] m_DetectParams;
71 private bool m_TimerQueued; 70 private bool m_TimerQueued;
72 private DateTime m_EventStart; 71 private DateTime m_EventStart;
73 private bool m_InEvent; 72 private bool m_InEvent;
74 private string m_PrimName;
75 private string m_ScriptName;
76 private string m_Assembly; 73 private string m_Assembly;
77 private int m_StartParam;
78 private string m_CurrentEvent = String.Empty; 74 private string m_CurrentEvent = String.Empty;
79 private bool m_InSelfDelete; 75 private bool m_InSelfDelete;
80 private int m_MaxScriptQueue; 76 private int m_MaxScriptQueue;
81 private bool m_SaveState = true; 77 private bool m_SaveState = true;
82 private bool m_ShuttingDown;
83 private int m_ControlEventsInQueue; 78 private int m_ControlEventsInQueue;
84 private int m_LastControlLevel; 79 private int m_LastControlLevel;
85 private bool m_CollisionInQueue; 80 private bool m_CollisionInQueue;
86 private TaskInventoryItem m_thisScriptTask; 81
87 // The following is for setting a minimum delay between events 82 // The following is for setting a minimum delay between events
88 private double m_minEventDelay; 83 private double m_minEventDelay;
84
89 private long m_eventDelayTicks; 85 private long m_eventDelayTicks;
90 private long m_nextEventTimeTicks; 86 private long m_nextEventTimeTicks;
91 private bool m_startOnInit = true; 87 private bool m_startOnInit = true;
@@ -96,21 +92,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
96 private UUID m_CurrentStateHash; 92 private UUID m_CurrentStateHash;
97 private UUID m_RegionID; 93 private UUID m_RegionID;
98 94
99 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 95 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> LineMap { get; set; }
100 m_LineMap;
101
102 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
103 LineMap
104 {
105 get { return m_LineMap; }
106 set { m_LineMap = value; }
107 }
108 96
109 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 97 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
110 98
111 // Script state
112 private string m_State = "default";
113
114 public Object[] PluginData = new Object[0]; 99 public Object[] PluginData = new Object[0];
115 100
116 /// <summary> 101 /// <summary>
@@ -133,11 +118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
133 } 118 }
134 } 119 }
135 120
136 public bool Running 121 public bool Running { get; set; }
137 {
138 get { return m_RunEvents; }
139 set { m_RunEvents = value; }
140 }
141 122
142 public bool Suspended 123 public bool Suspended
143 { 124 {
@@ -153,11 +134,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
153 134
154 if (wasSuspended && !m_Suspended) 135 if (wasSuspended && !m_Suspended)
155 { 136 {
156 lock (m_EventQueue) 137 lock (EventQueue)
157 { 138 {
158 // Need to place ourselves back in a work item if there are events to process 139 // Need to place ourselves back in a work item if there are events to process
159 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 140 if (EventQueue.Count > 0 && Running && !ShuttingDown)
160 m_CurrentResult = m_Engine.QueueEventHandler(this); 141 m_CurrentWorkItem = Engine.QueueEventHandler(this);
161 } 142 }
162 } 143 }
163 } 144 }
@@ -165,79 +146,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 } 146 }
166 private bool m_Suspended; 147 private bool m_Suspended;
167 148
168 public bool ShuttingDown 149 public bool ShuttingDown { get; set; }
169 {
170 get { return m_ShuttingDown; }
171 set { m_ShuttingDown = value; }
172 }
173 150
174 public string State 151 public string State { get; set; }
175 {
176 get { return m_State; }
177 set { m_State = value; }
178 }
179 152
180 public IScriptEngine Engine 153 public IScriptEngine Engine { get; private set; }
181 {
182 get { return m_Engine; }
183 }
184 154
185 public UUID AppDomain 155 public UUID AppDomain { get; set; }
186 {
187 get { return m_AppDomain; }
188 set { m_AppDomain = value; }
189 }
190 156
191 public string PrimName 157 public string PrimName { get; private set; }
192 {
193 get { return m_PrimName; }
194 }
195 158
196 public string ScriptName 159 public string ScriptName { get; private set; }
197 {
198 get { return m_ScriptName; }
199 }
200 160
201 public UUID ItemID 161 public UUID ItemID { get; private set; }
202 {
203 get { return m_ItemID; }
204 }
205 162
206 public UUID ObjectID 163 public UUID ObjectID { get; private set; }
207 {
208 get { return m_ObjectID; }
209 }
210 164
211 public uint LocalID 165 public uint LocalID { get; private set; }
212 {
213 get { return m_LocalID; }
214 }
215 166
216 public UUID AssetID 167 public UUID RootObjectID { get; private set; }
217 {
218 get { return m_AssetID; }
219 }
220 168
221 public Queue EventQueue 169 public uint RootLocalID { get; private set; }
222 {
223 get { return m_EventQueue; }
224 }
225 170
226 public void ClearQueue() 171 public UUID AssetID { get; private set; }
227 {
228 m_TimerQueued = false;
229 m_EventQueue.Clear();
230 }
231 172
232 public int StartParam 173 public Queue EventQueue { get; private set; }
233 { 174
234 get { return m_StartParam; } 175 public int StartParam { get; set; }
235 set { m_StartParam = value; } 176
236 } 177 public TaskInventoryItem ScriptTask { get; private set; }
178
179 public DateTime TimeStarted { get; private set; }
180
181 public long MeasurementPeriodTickStart { get; private set; }
237 182
238 public TaskInventoryItem ScriptTask 183 public long MeasurementPeriodExecutionTime { get; private set; }
184
185 public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
186
187 public void ClearQueue()
239 { 188 {
240 get { return m_thisScriptTask; } 189 m_TimerQueued = false;
190 EventQueue.Clear();
241 } 191 }
242 192
243 public ScriptInstance(IScriptEngine engine, SceneObjectPart part, 193 public ScriptInstance(IScriptEngine engine, SceneObjectPart part,
@@ -246,16 +196,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
246 int startParam, bool postOnRez, StateSource stateSource, 196 int startParam, bool postOnRez, StateSource stateSource,
247 int maxScriptQueue) 197 int maxScriptQueue)
248 { 198 {
249 m_Engine = engine; 199 State = "default";
250 200 EventQueue = new Queue(32);
251 m_LocalID = part.LocalId; 201
252 m_ObjectID = part.UUID; 202 Engine = engine;
253 m_ItemID = itemID; 203 LocalID = part.LocalId;
254 m_AssetID = assetID; 204 ObjectID = part.UUID;
255 m_PrimName = primName; 205 RootLocalID = part.ParentGroup.LocalId;
256 m_ScriptName = scriptName; 206 RootObjectID = part.ParentGroup.UUID;
207 ItemID = itemID;
208 AssetID = assetID;
209 PrimName = primName;
210 ScriptName = scriptName;
257 m_Assembly = assembly; 211 m_Assembly = assembly;
258 m_StartParam = startParam; 212 StartParam = startParam;
259 m_MaxScriptQueue = maxScriptQueue; 213 m_MaxScriptQueue = maxScriptQueue;
260 m_stateSource = stateSource; 214 m_stateSource = stateSource;
261 m_postOnRez = postOnRez; 215 m_postOnRez = postOnRez;
@@ -266,9 +220,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
266 { 220 {
267 lock (part.TaskInventory) 221 lock (part.TaskInventory)
268 { 222 {
269 if (part.TaskInventory.ContainsKey(m_ItemID)) 223 if (part.TaskInventory.ContainsKey(ItemID))
270 { 224 {
271 m_thisScriptTask = part.TaskInventory[m_ItemID]; 225 ScriptTask = part.TaskInventory[ItemID];
272 } 226 }
273 } 227 }
274 } 228 }
@@ -278,20 +232,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
278 foreach (string api in am.GetApis()) 232 foreach (string api in am.GetApis())
279 { 233 {
280 m_Apis[api] = am.CreateApi(api); 234 m_Apis[api] = am.CreateApi(api);
281 m_Apis[api].Initialize(engine, part, m_LocalID, itemID); 235 m_Apis[api].Initialize(engine, part, LocalID, itemID);
282 } 236 }
283 237
284 try 238 try
285 { 239 {
286 if (dom != System.AppDomain.CurrentDomain) 240 if (dom != System.AppDomain.CurrentDomain)
287 m_Script = (IScript)dom.CreateInstanceAndUnwrap( 241 m_Script = (IScript)dom.CreateInstanceAndUnwrap(
288 Path.GetFileNameWithoutExtension(assembly), 242 Path.GetFileNameWithoutExtension(assembly),
289 "SecondLife.Script"); 243 "SecondLife.Script");
290 else 244 else
291 m_Script = (IScript)Assembly.Load( 245 m_Script = (IScript)Assembly.Load(
292 Path.GetFileNameWithoutExtension(assembly)).CreateInstance( 246 Path.GetFileNameWithoutExtension(assembly)).CreateInstance(
293 "SecondLife.Script"); 247 "SecondLife.Script");
294
295 248
296 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 249 //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 250 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
@@ -313,7 +266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
313 266
314// // m_log.Debug("[Script] Script instance created"); 267// // m_log.Debug("[Script] Script instance created");
315 268
316 part.SetScriptEvents(m_ItemID, 269 part.SetScriptEvents(ItemID,
317 (int)m_Script.GetStateEventFlags(State)); 270 (int)m_Script.GetStateEventFlags(State));
318 } 271 }
319 catch (Exception e) 272 catch (Exception e)
@@ -328,7 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
328 m_SaveState = true; 281 m_SaveState = true;
329 282
330 string savedState = Path.Combine(Path.GetDirectoryName(assembly), 283 string savedState = Path.Combine(Path.GetDirectoryName(assembly),
331 m_ItemID.ToString() + ".state"); 284 ItemID.ToString() + ".state");
332 if (File.Exists(savedState)) 285 if (File.Exists(savedState))
333 { 286 {
334 string xml = String.Empty; 287 string xml = String.Empty;
@@ -352,24 +305,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
352 305
353 ScriptSerializer.Deserialize(xml, this); 306 ScriptSerializer.Deserialize(xml, this);
354 307
355 AsyncCommandManager.CreateFromData(m_Engine, 308 AsyncCommandManager.CreateFromData(Engine,
356 m_LocalID, m_ItemID, m_ObjectID, 309 LocalID, ItemID, ObjectID,
357 PluginData); 310 PluginData);
358 311
359// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName); 312// m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName);
360 313
361 part.SetScriptEvents(m_ItemID, 314 part.SetScriptEvents(ItemID,
362 (int)m_Script.GetStateEventFlags(State)); 315 (int)m_Script.GetStateEventFlags(State));
363 316
364 if (m_RunEvents && (!m_ShuttingDown)) 317 Running = false;
365 { 318
366 m_RunEvents = false; 319 if (ShuttingDown)
367 }
368 else
369 {
370 m_RunEvents = false;
371 m_startOnInit = false; 320 m_startOnInit = false;
372 }
373 321
374 // we get new rez events on sim restart, too 322 // we get new rez events on sim restart, too
375 // but if there is state, then we fire the change 323 // but if there is state, then we fire the change
@@ -378,7 +326,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
378 // We loaded state, don't force a re-save 326 // We loaded state, don't force a re-save
379 m_SaveState = false; 327 m_SaveState = false;
380 m_startedFromSavedState = true; 328 m_startedFromSavedState = true;
381
382 } 329 }
383 } 330 }
384 else 331 else
@@ -397,7 +344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
397 } 344 }
398// else 345// else
399// { 346// {
400// ScenePresence presence = m_Engine.World.GetScenePresence(part.OwnerID); 347// ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID);
401 348
402// if (presence != null && (!postOnRez)) 349// if (presence != null && (!postOnRez))
403// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); 350// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
@@ -415,7 +362,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
415 if (m_postOnRez) 362 if (m_postOnRez)
416 { 363 {
417 PostEvent(new EventParams("on_rez", 364 PostEvent(new EventParams("on_rez",
418 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0])); 365 new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
419 } 366 }
420 367
421 if (m_stateSource == StateSource.AttachedRez) 368 if (m_stateSource == StateSource.AttachedRez)
@@ -449,7 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
449 if (m_postOnRez) 396 if (m_postOnRez)
450 { 397 {
451 PostEvent(new EventParams("on_rez", 398 PostEvent(new EventParams("on_rez",
452 new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0])); 399 new Object[] {new LSL_Types.LSLInteger(StartParam)}, new DetectParams[0]));
453 } 400 }
454 401
455 if (m_stateSource == StateSource.AttachedRez) 402 if (m_stateSource == StateSource.AttachedRez)
@@ -463,7 +410,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
463 410
464 private void ReleaseControls() 411 private void ReleaseControls()
465 { 412 {
466 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(m_LocalID); 413 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
467 414
468 if (part != null) 415 if (part != null)
469 { 416 {
@@ -471,18 +418,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
471 UUID permsGranter; 418 UUID permsGranter;
472 lock (part.TaskInventory) 419 lock (part.TaskInventory)
473 { 420 {
474 if (!part.TaskInventory.ContainsKey(m_ItemID)) 421 if (!part.TaskInventory.ContainsKey(ItemID))
475 return; 422 return;
476 423
477 permsGranter = part.TaskInventory[m_ItemID].PermsGranter; 424 permsGranter = part.TaskInventory[ItemID].PermsGranter;
478 permsMask = part.TaskInventory[m_ItemID].PermsMask; 425 permsMask = part.TaskInventory[ItemID].PermsMask;
479 } 426 }
480 427
481 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 428 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
482 { 429 {
483 ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter); 430 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
484 if (presence != null) 431 if (presence != null)
485 presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID); 432 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
486 } 433 }
487 } 434 }
488 } 435 }
@@ -490,13 +437,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
490 public void DestroyScriptInstance() 437 public void DestroyScriptInstance()
491 { 438 {
492 ReleaseControls(); 439 ReleaseControls();
493 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 440 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
494 } 441 }
495 442
496 public void RemoveState() 443 public void RemoveState()
497 { 444 {
498 string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), 445 string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly),
499 m_ItemID.ToString() + ".state"); 446 ItemID.ToString() + ".state");
500 447
501 try 448 try
502 { 449 {
@@ -509,7 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
509 456
510 public void VarDump(Dictionary<string, object> vars) 457 public void VarDump(Dictionary<string, object> vars)
511 { 458 {
512 // m_log.Info("Variable dump for script "+ m_ItemID.ToString()); 459 // m_log.Info("Variable dump for script "+ ItemID.ToString());
513 // foreach (KeyValuePair<string, object> v in vars) 460 // foreach (KeyValuePair<string, object> v in vars)
514 // { 461 // {
515 // m_log.Info("Variable: "+v.Key+" = "+v.Value.ToString()); 462 // m_log.Info("Variable: "+v.Key+" = "+v.Value.ToString());
@@ -518,17 +465,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
518 465
519 public void Start() 466 public void Start()
520 { 467 {
521 lock (m_EventQueue) 468 lock (EventQueue)
522 { 469 {
523 if (Running) 470 if (Running)
524 return; 471 return;
525 472
526 m_RunEvents = true; 473 Running = true;
474
475 TimeStarted = DateTime.Now;
476 MeasurementPeriodTickStart = Util.EnvironmentTickCount();
477 MeasurementPeriodExecutionTime = 0;
527 478
528 if (m_EventQueue.Count > 0) 479 if (EventQueue.Count > 0)
529 { 480 {
530 if (m_CurrentResult == null) 481 if (m_CurrentWorkItem == null)
531 m_CurrentResult = m_Engine.QueueEventHandler(this); 482 m_CurrentWorkItem = Engine.QueueEventHandler(this);
532 // else 483 // else
533 // m_log.Error("[Script] Tried to start a script that was already queued"); 484 // m_log.Error("[Script] Tried to start a script that was already queued");
534 } 485 }
@@ -538,51 +489,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
538 public bool Stop(int timeout) 489 public bool Stop(int timeout)
539 { 490 {
540// m_log.DebugFormat( 491// m_log.DebugFormat(
541// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); 492// "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}",
493// ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks);
542 494
543 IScriptWorkItem result; 495 IScriptWorkItem workItem;
544 496
545 lock (m_EventQueue) 497 lock (EventQueue)
546 { 498 {
547 if (!Running) 499 if (!Running)
548 return true; 500 return true;
549 501
550 if (m_CurrentResult == null) 502 // If we're not running or waiting to run an event then we can safely stop.
503 if (m_CurrentWorkItem == null)
551 { 504 {
552 m_RunEvents = false; 505 Running = false;
553 return true; 506 return true;
554 } 507 }
555 508
556 if (m_CurrentResult.Cancel()) 509 // If we are waiting to run an event then we can try to cancel it.
510 if (m_CurrentWorkItem.Cancel())
557 { 511 {
558 m_CurrentResult = null; 512 m_CurrentWorkItem = null;
559 m_RunEvents = false; 513 Running = false;
560 return true; 514 return true;
561 } 515 }
562 516
563 result = m_CurrentResult; 517 workItem = m_CurrentWorkItem;
564 m_RunEvents = false; 518 Running = false;
565 } 519 }
566 520
567 if (result.Wait(new TimeSpan((long)timeout * 100000))) 521 // Wait for the current event to complete.
522 if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000)))
568 { 523 {
569 return true; 524 return true;
570 } 525 }
571 526
572 lock (m_EventQueue) 527 lock (EventQueue)
573 { 528 {
574 result = m_CurrentResult; 529 workItem = m_CurrentWorkItem;
575 } 530 }
576 531
577 if (result == null) 532 if (workItem == null)
578 return true; 533 return true;
579 534
535 // If the event still hasn't stopped and we the stop isn't the result of script or object removal, then
536 // forcibly abort the work item (this aborts the underlying thread).
580 if (!m_InSelfDelete) 537 if (!m_InSelfDelete)
581 result.Abort(); 538 {
539// m_log.ErrorFormat(
540// "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}",
541// ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks);
542
543 workItem.Abort();
544 }
582 545
583 lock (m_EventQueue) 546 lock (EventQueue)
584 { 547 {
585 m_CurrentResult = null; 548 m_CurrentWorkItem = null;
586 } 549 }
587 550
588 return true; 551 return true;
@@ -603,10 +566,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
603 throw new EventAbortException(); 566 throw new EventAbortException();
604 } 567 }
605 568
569 /// <summary>
570 /// Post an event to this script instance.
571 /// </summary>
572 /// <remarks>
573 /// The request to run the event is sent
574 /// </remarks>
575 /// <param name="data"></param>
606 public void PostEvent(EventParams data) 576 public void PostEvent(EventParams data)
607 { 577 {
608// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}", 578// m_log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}",
609// m_PrimName, m_ScriptName, data.EventName, m_State); 579// PrimName, ScriptName, data.EventName, State);
610 580
611 if (!Running) 581 if (!Running)
612 return; 582 return;
@@ -621,9 +591,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
621 m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks; 591 m_nextEventTimeTicks = DateTime.Now.Ticks + m_eventDelayTicks;
622 } 592 }
623 593
624 lock (m_EventQueue) 594 lock (EventQueue)
625 { 595 {
626 if (m_EventQueue.Count >= m_MaxScriptQueue) 596 if (EventQueue.Count >= m_MaxScriptQueue)
627 return; 597 return;
628 598
629 if (data.EventName == "timer") 599 if (data.EventName == "timer")
@@ -667,11 +637,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
667 m_CollisionInQueue = true; 637 m_CollisionInQueue = true;
668 } 638 }
669 639
670 m_EventQueue.Enqueue(data); 640 EventQueue.Enqueue(data);
671 641
672 if (m_CurrentResult == null) 642 if (m_CurrentWorkItem == null)
673 { 643 {
674 m_CurrentResult = m_Engine.QueueEventHandler(this); 644 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 } 645 }
676 } 646 }
677 } 647 }
@@ -682,6 +652,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
682 /// <returns></returns> 652 /// <returns></returns>
683 public object EventProcessor() 653 public object EventProcessor()
684 { 654 {
655 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
656 if (!Running)
657 return 0;
658
685 lock (m_Script) 659 lock (m_Script)
686 { 660 {
687// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 661// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
@@ -691,18 +665,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
691 665
692 EventParams data = null; 666 EventParams data = null;
693 667
694 lock (m_EventQueue) 668 lock (EventQueue)
695 { 669 {
696 data = (EventParams) m_EventQueue.Dequeue(); 670 data = (EventParams)EventQueue.Dequeue();
697 if (data == null) // Shouldn't happen 671 if (data == null) // Shouldn't happen
698 { 672 {
699 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
700 { 674 {
701 m_CurrentResult = m_Engine.QueueEventHandler(this); 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
702 } 676 }
703 else 677 else
704 { 678 {
705 m_CurrentResult = null; 679 m_CurrentWorkItem = null;
706 } 680 }
707 return 0; 681 return 0;
708 } 682 }
@@ -725,28 +699,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
725 if (data.EventName == "state") // Hardcoded state change 699 if (data.EventName == "state") // Hardcoded state change
726 { 700 {
727 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", 701 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
728 // m_PrimName, m_ScriptName, data.Params[0].ToString()); 702 // PrimName, ScriptName, data.Params[0].ToString());
729 m_State = data.Params[0].ToString(); 703 State = data.Params[0].ToString();
730 AsyncCommandManager.RemoveScript(m_Engine, 704 AsyncCommandManager.RemoveScript(Engine,
731 m_LocalID, m_ItemID); 705 LocalID, ItemID);
732 706
733 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 707 SceneObjectPart part = Engine.World.GetSceneObjectPart(
734 m_LocalID); 708 LocalID);
735 if (part != null) 709 if (part != null)
736 { 710 {
737 part.SetScriptEvents(m_ItemID, 711 part.SetScriptEvents(ItemID,
738 (int)m_Script.GetStateEventFlags(State)); 712 (int)m_Script.GetStateEventFlags(State));
739 } 713 }
740 } 714 }
741 else 715 else
742 { 716 {
743 if (m_Engine.World.PipeEventsForScript(m_LocalID) || 717 if (Engine.World.PipeEventsForScript(LocalID) ||
744 data.EventName == "control") // Don't freeze avies! 718 data.EventName == "control") // Don't freeze avies!
745 { 719 {
746 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 720 SceneObjectPart part = Engine.World.GetSceneObjectPart(
747 m_LocalID); 721 LocalID);
748 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", 722 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
749 // m_PrimName, m_ScriptName, data.EventName, m_State); 723 // PrimName, ScriptName, data.EventName, State);
750 724
751 try 725 try
752 { 726 {
@@ -754,8 +728,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
754 m_EventStart = DateTime.Now; 728 m_EventStart = DateTime.Now;
755 m_InEvent = true; 729 m_InEvent = true;
756 730
731 int start = Util.EnvironmentTickCount();
732
733 // Reset the measurement period when we reach the end of the current one.
734 if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod)
735 MeasurementPeriodTickStart = start;
736
757 m_Script.ExecuteEvent(State, data.EventName, data.Params); 737 m_Script.ExecuteEvent(State, data.EventName, data.Params);
758 738
739 MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start;
740
759 m_InEvent = false; 741 m_InEvent = false;
760 m_CurrentEvent = String.Empty; 742 m_CurrentEvent = String.Empty;
761 743
@@ -764,7 +746,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
764 // This will be the very first event we deliver 746 // This will be the very first event we deliver
765 // (state_entry) in default state 747 // (state_entry) in default state
766 // 748 //
767
768 SaveState(m_Assembly); 749 SaveState(m_Assembly);
769 750
770 m_SaveState = false; 751 m_SaveState = false;
@@ -788,7 +769,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
788 769
789 if (text.Length > 1000) 770 if (text.Length > 1000)
790 text = text.Substring(0, 1000); 771 text = text.Substring(0, 1000);
791 m_Engine.World.SimChat(Utils.StringToBytes(text), 772 Engine.World.SimChat(Utils.StringToBytes(text),
792 ChatTypeEnum.DebugChannel, 2147483647, 773 ChatTypeEnum.DebugChannel, 2147483647,
793 part.AbsolutePosition, 774 part.AbsolutePosition,
794 part.Name, part.UUID, false); 775 part.Name, part.UUID, false);
@@ -810,27 +791,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
810 { 791 {
811 m_InSelfDelete = true; 792 m_InSelfDelete = true;
812 if (part != null) 793 if (part != null)
813 m_Engine.World.DeleteSceneObject(part.ParentGroup, false); 794 Engine.World.DeleteSceneObject(part.ParentGroup, false);
814 } 795 }
815 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 796 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
816 { 797 {
817 m_InSelfDelete = true; 798 m_InSelfDelete = true;
818 if (part != null) 799 if (part != null)
819 part.Inventory.RemoveInventoryItem(m_ItemID); 800 part.Inventory.RemoveInventoryItem(ItemID);
820 } 801 }
821 } 802 }
822 } 803 }
823 } 804 }
824 805
825 lock (m_EventQueue) 806 // If there are more events and we are currently running and not shutting down, then ask the
807 // script engine to run the next event.
808 lock (EventQueue)
826 { 809 {
827 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 810 if (EventQueue.Count > 0 && Running && !ShuttingDown)
828 { 811 {
829 m_CurrentResult = m_Engine.QueueEventHandler(this); 812 m_CurrentWorkItem = Engine.QueueEventHandler(this);
830 } 813 }
831 else 814 else
832 { 815 {
833 m_CurrentResult = null; 816 m_CurrentWorkItem = null;
834 } 817 }
835 } 818 }
836 819
@@ -859,15 +842,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
859 ReleaseControls(); 842 ReleaseControls();
860 843
861 Stop(0); 844 Stop(0);
862 SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); 845 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
863 part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; 846 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
864 part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; 847 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
865 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 848 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
866 m_EventQueue.Clear(); 849 EventQueue.Clear();
867 m_Script.ResetVars(); 850 m_Script.ResetVars();
868 m_State = "default"; 851 State = "default";
869 852
870 part.SetScriptEvents(m_ItemID, 853 part.SetScriptEvents(ItemID,
871 (int)m_Script.GetStateEventFlags(State)); 854 (int)m_Script.GetStateEventFlags(State));
872 if (running) 855 if (running)
873 Start(); 856 Start();
@@ -884,16 +867,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
884 ReleaseControls(); 867 ReleaseControls();
885 868
886 m_Script.ResetVars(); 869 m_Script.ResetVars();
887 SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); 870 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
888 part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; 871 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
889 part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; 872 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
890 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 873 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
891 874
892 m_EventQueue.Clear(); 875 EventQueue.Clear();
893 m_Script.ResetVars(); 876 m_Script.ResetVars();
894 m_State = "default"; 877 State = "default";
895 878
896 part.SetScriptEvents(m_ItemID, 879 part.SetScriptEvents(ItemID,
897 (int)m_Script.GetStateEventFlags(State)); 880 (int)m_Script.GetStateEventFlags(State));
898 881
899 if (m_CurrentEvent != "state_entry") 882 if (m_CurrentEvent != "state_entry")
@@ -940,8 +923,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
940 923
941 public void SaveState(string assembly) 924 public void SaveState(string assembly)
942 { 925 {
943
944
945 // If we're currently in an event, just tell it to save upon return 926 // If we're currently in an event, just tell it to save upon return
946 // 927 //
947 if (m_InEvent) 928 if (m_InEvent)
@@ -950,7 +931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
950 return; 931 return;
951 } 932 }
952 933
953 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 934 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
954 935
955 string xml = ScriptSerializer.Serialize(this); 936 string xml = ScriptSerializer.Serialize(this);
956 937
@@ -962,7 +943,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
962 { 943 {
963 try 944 try
964 { 945 {
965 FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")); 946 FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state"));
966 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding(); 947 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
967 Byte[] buf = enc.GetBytes(xml); 948 Byte[] buf = enc.GetBytes(xml);
968 fs.Write(buf, 0, buf.Length); 949 fs.Write(buf, 0, buf.Length);
@@ -972,7 +953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
972 { 953 {
973 // m_log.Error("Unable to save xml\n"+e.ToString()); 954 // m_log.Error("Unable to save xml\n"+e.ToString());
974 } 955 }
975 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"))) 956 //if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state")))
976 //{ 957 //{
977 // throw new Exception("Completed persistence save, but no file was created"); 958 // throw new Exception("Completed persistence save, but no file was created");
978 //} 959 //}
@@ -989,7 +970,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
989 970
990 public override string ToString() 971 public override string ToString()
991 { 972 {
992 return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName); 973 return String.Format("{0} {1} on {2}", ScriptName, ItemID, PrimName);
993 } 974 }
994 975
995 string FormatException(Exception e) 976 string FormatException(Exception e)
@@ -1057,7 +1038,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1057 1038
1058 // Force an update of the in-memory plugin data 1039 // Force an update of the in-memory plugin data
1059 // 1040 //
1060 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 1041 PluginData = AsyncCommandManager.GetSerializationData(Engine, ItemID);
1061 1042
1062 return ScriptSerializer.Serialize(this); 1043 return ScriptSerializer.Serialize(this);
1063 } 1044 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
new file mode 100644
index 0000000..e2d0db2
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiInventoryTests.cs
@@ -0,0 +1,168 @@
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.Services.Interfaces;
45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47
48namespace OpenSim.Region.ScriptEngine.Shared.Tests
49{
50 /// <summary>
51 /// Tests for inventory functions in LSL
52 /// </summary>
53 [TestFixture]
54 public class LSL_ApiInventoryTests
55 {
56 protected Scene m_scene;
57 protected XEngine.XEngine m_engine;
58
59 [SetUp]
60 public void SetUp()
61 {
62 IConfigSource initConfigSource = new IniConfigSource();
63 IConfig config = initConfigSource.AddConfig("XEngine");
64 config.Set("Enabled", "true");
65
66 m_scene = SceneHelpers.SetupScene();
67 SceneHelpers.SetupSceneModules(m_scene, initConfigSource);
68
69 m_engine = new XEngine.XEngine();
70 m_engine.Initialise(initConfigSource);
71 m_engine.AddRegion(m_scene);
72 }
73
74 /// <summary>
75 /// Test giving inventory from an object to an object where both are owned by the same user.
76 /// </summary>
77 [Test]
78 public void TestLlGiveInventoryO2OSameOwner()
79 {
80 TestHelpers.InMethod();
81// log4net.Config.XmlConfigurator.Configure();
82
83 UUID userId = TestHelpers.ParseTail(0x1);
84 string inventoryItemName = "item1";
85
86 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, userId, "so1", 0x10);
87 m_scene.AddSceneObject(so1);
88
89 // Create an object embedded inside the first
90 UUID itemId = TestHelpers.ParseTail(0x20);
91 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, userId);
92
93 LSL_Api api = new LSL_Api();
94 api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID);
95
96 // Create a second object
97 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, userId, "so2", 0x100);
98 m_scene.AddSceneObject(so2);
99
100 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName);
101
102 // Item has copy permissions so original should stay intact.
103 List<TaskInventoryItem> originalItems = so1.RootPart.Inventory.GetInventoryItems();
104 Assert.That(originalItems.Count, Is.EqualTo(1));
105
106 List<TaskInventoryItem> copiedItems = so2.RootPart.Inventory.GetInventoryItems(inventoryItemName);
107 Assert.That(copiedItems.Count, Is.EqualTo(1));
108 Assert.That(copiedItems[0].Name, Is.EqualTo(inventoryItemName));
109 }
110
111 /// <summary>
112 /// Test giving inventory from an object to an object where they have different owners
113 /// </summary>
114 [Test]
115 public void TestLlGiveInventoryO2ODifferentOwners()
116 {
117 TestHelpers.InMethod();
118// log4net.Config.XmlConfigurator.Configure();
119
120 UUID user1Id = TestHelpers.ParseTail(0x1);
121 UUID user2Id = TestHelpers.ParseTail(0x2);
122 string inventoryItemName = "item1";
123
124 SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(1, user1Id, "so1", 0x10);
125 m_scene.AddSceneObject(so1);
126 LSL_Api api = new LSL_Api();
127 api.Initialize(m_engine, so1.RootPart, so1.RootPart.LocalId, so1.RootPart.UUID);
128
129 // Create an object embedded inside the first
130 UUID itemId = TestHelpers.ParseTail(0x20);
131 TaskInventoryHelpers.AddSceneObject(m_scene, so1.RootPart, inventoryItemName, itemId, user1Id);
132
133 // Create a second object
134 SceneObjectGroup so2 = SceneHelpers.CreateSceneObject(1, user2Id, "so2", 0x100);
135 m_scene.AddSceneObject(so2);
136 LSL_Api api2 = new LSL_Api();
137 api2.Initialize(m_engine, so2.RootPart, so2.RootPart.LocalId, so2.RootPart.UUID);
138
139 // *** Firstly, we test where llAllowInventoryDrop() has not been called. ***
140 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName);
141
142 {
143 // Item has copy permissions so original should stay intact.
144 List<TaskInventoryItem> originalItems = so1.RootPart.Inventory.GetInventoryItems();
145 Assert.That(originalItems.Count, Is.EqualTo(1));
146
147 // Should have not copied
148 List<TaskInventoryItem> copiedItems = so2.RootPart.Inventory.GetInventoryItems(inventoryItemName);
149 Assert.That(copiedItems.Count, Is.EqualTo(0));
150 }
151
152 // *** Secondly, we turn on allow inventory drop in the target and retest. ***
153 api2.llAllowInventoryDrop(1);
154 api.llGiveInventory(so2.UUID.ToString(), inventoryItemName);
155
156 {
157 // Item has copy permissions so original should stay intact.
158 List<TaskInventoryItem> originalItems = so1.RootPart.Inventory.GetInventoryItems();
159 Assert.That(originalItems.Count, Is.EqualTo(1));
160
161 // Should now have copied.
162 List<TaskInventoryItem> copiedItems = so2.RootPart.Inventory.GetInventoryItems(inventoryItemName);
163 Assert.That(copiedItems.Count, Is.EqualTo(1));
164 Assert.That(copiedItems[0].Name, Is.EqualTo(inventoryItemName));
165 }
166 }
167 }
168} \ 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 3baa723..9cf9258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -46,7 +46,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
46 [TestFixture, LongRunning] 46 [TestFixture, LongRunning]
47 public class LSL_ApiTest 47 public class LSL_ApiTest
48 { 48 {
49
50 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; 49 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
51 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; 50 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
52 private const float FLOAT_ACCURACY = 0.00005f; 51 private const float FLOAT_ACCURACY = 0.00005f;
@@ -55,7 +54,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
55 [SetUp] 54 [SetUp]
56 public void SetUp() 55 public void SetUp()
57 { 56 {
58
59 IConfigSource initConfigSource = new IniConfigSource(); 57 IConfigSource initConfigSource = new IniConfigSource();
60 IConfig config = initConfigSource.AddConfig("XEngine"); 58 IConfig config = initConfigSource.AddConfig("XEngine");
61 config.Set("Enabled", "true"); 59 config.Set("Enabled", "true");
@@ -75,6 +73,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
75 [Test] 73 [Test]
76 public void TestllAngleBetween() 74 public void TestllAngleBetween()
77 { 75 {
76 TestHelpers.InMethod();
77
78 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1, 1); 78 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1, 1);
79 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 1, 1); 79 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 1, 1);
80 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 1, 1); 80 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 1, 1);
@@ -158,6 +158,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
158 // llRot2Euler test. 158 // llRot2Euler test.
159 public void TestllRot2Euler() 159 public void TestllRot2Euler()
160 { 160 {
161 TestHelpers.InMethod();
162
161 // 180, 90 and zero degree rotations. 163 // 180, 90 and zero degree rotations.
162 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f)); 164 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f));
163 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, 0.707107f)); 165 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, 0.707107f));
@@ -256,6 +258,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
256 // llSetPrimitiveParams and llGetPrimitiveParams test. 258 // llSetPrimitiveParams and llGetPrimitiveParams test.
257 public void TestllSetPrimitiveParams() 259 public void TestllSetPrimitiveParams()
258 { 260 {
261 TestHelpers.InMethod();
262
259 // Create Prim1. 263 // Create Prim1.
260 Scene scene = SceneHelpers.SetupScene(); 264 Scene scene = SceneHelpers.SetupScene();
261 string obj1Name = "Prim1"; 265 string obj1Name = "Prim1";
@@ -486,9 +490,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
486 } 490 }
487 491
488 [Test] 492 [Test]
489 // llVecNorm test.
490 public void TestllVecNorm() 493 public void TestllVecNorm()
491 { 494 {
495 TestHelpers.InMethod();
496
492 // Check special case for normalizing zero vector. 497 // Check special case for normalizing zero vector.
493 CheckllVecNorm(new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), new LSL_Types.Vector3(0.0d, 0.0d, 0.0d)); 498 CheckllVecNorm(new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), new LSL_Types.Vector3(0.0d, 0.0d, 0.0d));
494 // Check various vectors. 499 // Check various vectors.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs
index 10b52cf..3ed2562 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLFloat.cs
@@ -213,6 +213,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
213 [Test] 213 [Test]
214 public void TestConstructFromInt() 214 public void TestConstructFromInt()
215 { 215 {
216 TestHelpers.InMethod();
217
216 LSL_Types.LSLFloat testFloat; 218 LSL_Types.LSLFloat testFloat;
217 219
218 foreach (KeyValuePair<int, double> number in m_intDoubleSet) 220 foreach (KeyValuePair<int, double> number in m_intDoubleSet)
@@ -228,6 +230,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
228 [Test] 230 [Test]
229 public void TestConstructFromDouble() 231 public void TestConstructFromDouble()
230 { 232 {
233 TestHelpers.InMethod();
234
231 LSL_Types.LSLFloat testFloat; 235 LSL_Types.LSLFloat testFloat;
232 236
233 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet) 237 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet)
@@ -243,6 +247,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
243 [Test] 247 [Test]
244 public void TestExplicitCastLSLFloatToInt() 248 public void TestExplicitCastLSLFloatToInt()
245 { 249 {
250 TestHelpers.InMethod();
251
246 int testNumber; 252 int testNumber;
247 253
248 foreach (KeyValuePair<double, int> number in m_doubleIntSet) 254 foreach (KeyValuePair<double, int> number in m_doubleIntSet)
@@ -258,6 +264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
258 [Test] 264 [Test]
259 public void TestExplicitCastLSLFloatToUint() 265 public void TestExplicitCastLSLFloatToUint()
260 { 266 {
267 TestHelpers.InMethod();
268
261 uint testNumber; 269 uint testNumber;
262 270
263 foreach (KeyValuePair<double, int> number in m_doubleUintSet) 271 foreach (KeyValuePair<double, int> number in m_doubleUintSet)
@@ -273,6 +281,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
273 [Test] 281 [Test]
274 public void TestImplicitCastLSLFloatToBooleanTrue() 282 public void TestImplicitCastLSLFloatToBooleanTrue()
275 { 283 {
284 TestHelpers.InMethod();
285
276 LSL_Types.LSLFloat testFloat; 286 LSL_Types.LSLFloat testFloat;
277 bool testBool; 287 bool testBool;
278 288
@@ -291,6 +301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
291 [Test] 301 [Test]
292 public void TestImplicitCastLSLFloatToBooleanFalse() 302 public void TestImplicitCastLSLFloatToBooleanFalse()
293 { 303 {
304 TestHelpers.InMethod();
305
294 LSL_Types.LSLFloat testFloat = new LSL_Types.LSLFloat(0.0); 306 LSL_Types.LSLFloat testFloat = new LSL_Types.LSLFloat(0.0);
295 bool testBool = testFloat; 307 bool testBool = testFloat;
296 308
@@ -303,6 +315,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
303 [Test] 315 [Test]
304 public void TestImplicitCastIntToLSLFloat() 316 public void TestImplicitCastIntToLSLFloat()
305 { 317 {
318 TestHelpers.InMethod();
319
306 LSL_Types.LSLFloat testFloat; 320 LSL_Types.LSLFloat testFloat;
307 321
308 foreach (int number in m_intList) 322 foreach (int number in m_intList)
@@ -318,6 +332,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
318 [Test] 332 [Test]
319 public void TestImplicitCastLSLIntegerToLSLFloat() 333 public void TestImplicitCastLSLIntegerToLSLFloat()
320 { 334 {
335 TestHelpers.InMethod();
336
321 LSL_Types.LSLFloat testFloat; 337 LSL_Types.LSLFloat testFloat;
322 338
323 foreach (int number in m_intList) 339 foreach (int number in m_intList)
@@ -333,6 +349,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
333 [Test] 349 [Test]
334 public void TestExplicitCastLSLIntegerToLSLFloat() 350 public void TestExplicitCastLSLIntegerToLSLFloat()
335 { 351 {
352 TestHelpers.InMethod();
353
336 LSL_Types.LSLFloat testFloat; 354 LSL_Types.LSLFloat testFloat;
337 355
338 foreach (int number in m_intList) 356 foreach (int number in m_intList)
@@ -348,6 +366,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
348 [Test] 366 [Test]
349 public void TestExplicitCastStringToLSLFloat() 367 public void TestExplicitCastStringToLSLFloat()
350 { 368 {
369 TestHelpers.InMethod();
370
351 LSL_Types.LSLFloat testFloat; 371 LSL_Types.LSLFloat testFloat;
352 372
353 foreach (KeyValuePair<string, double> number in m_stringDoubleSet) 373 foreach (KeyValuePair<string, double> number in m_stringDoubleSet)
@@ -363,6 +383,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
363 [Test] 383 [Test]
364 public void TestExplicitCastLSLStringToLSLFloat() 384 public void TestExplicitCastLSLStringToLSLFloat()
365 { 385 {
386 TestHelpers.InMethod();
387
366 LSL_Types.LSLFloat testFloat; 388 LSL_Types.LSLFloat testFloat;
367 389
368 foreach (KeyValuePair<string, double> number in m_stringDoubleSet) 390 foreach (KeyValuePair<string, double> number in m_stringDoubleSet)
@@ -378,6 +400,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
378 [Test] 400 [Test]
379 public void TestImplicitCastDoubleToLSLFloat() 401 public void TestImplicitCastDoubleToLSLFloat()
380 { 402 {
403 TestHelpers.InMethod();
404
381 LSL_Types.LSLFloat testFloat; 405 LSL_Types.LSLFloat testFloat;
382 406
383 foreach (double number in m_doubleList) 407 foreach (double number in m_doubleList)
@@ -393,6 +417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
393 [Test] 417 [Test]
394 public void TestImplicitCastLSLFloatToDouble() 418 public void TestImplicitCastLSLFloatToDouble()
395 { 419 {
420 TestHelpers.InMethod();
421
396 double testNumber; 422 double testNumber;
397 LSL_Types.LSLFloat testFloat; 423 LSL_Types.LSLFloat testFloat;
398 424
@@ -411,19 +437,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
411 [Test] 437 [Test]
412 public void TestExplicitCastLSLFloatToFloat() 438 public void TestExplicitCastLSLFloatToFloat()
413 { 439 {
414 float testFloat; 440 TestHelpers.InMethod();
415 float numberAsFloat; 441
416 LSL_Types.LSLFloat testLSLFloat; 442 float testFloat;
417 foreach (double number in m_doubleList) 443 float numberAsFloat;
418 { 444 LSL_Types.LSLFloat testLSLFloat;
419 testLSLFloat = new LSL_Types.LSLFloat(number);
420 numberAsFloat = (float)number;
421 testFloat = (float)testLSLFloat;
422
423 Assert.That((double)testFloat, new DoubleToleranceConstraint((double)numberAsFloat, _lowPrecisionTolerance));
424 }
425 }
426 445
446 foreach (double number in m_doubleList)
447 {
448 testLSLFloat = new LSL_Types.LSLFloat(number);
449 numberAsFloat = (float)number;
450 testFloat = (float)testLSLFloat;
451
452 Assert.That((double)testFloat, new DoubleToleranceConstraint((double)numberAsFloat, _lowPrecisionTolerance));
453 }
454 }
427 455
428 /// <summary> 456 /// <summary>
429 /// Tests the equality (==) operator. 457 /// Tests the equality (==) operator.
@@ -431,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
431 [Test] 459 [Test]
432 public void TestEqualsOperator() 460 public void TestEqualsOperator()
433 { 461 {
462 TestHelpers.InMethod();
463
434 LSL_Types.LSLFloat testFloatA, testFloatB; 464 LSL_Types.LSLFloat testFloatA, testFloatB;
435 465
436 foreach (double number in m_doubleList) 466 foreach (double number in m_doubleList)
@@ -450,6 +480,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
450 [Test] 480 [Test]
451 public void TestNotEqualOperator() 481 public void TestNotEqualOperator()
452 { 482 {
483 TestHelpers.InMethod();
484
453 LSL_Types.LSLFloat testFloatA, testFloatB; 485 LSL_Types.LSLFloat testFloatA, testFloatB;
454 486
455 foreach (double number in m_doubleList) 487 foreach (double number in m_doubleList)
@@ -469,6 +501,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
469 [Test] 501 [Test]
470 public void TestIncrementOperator() 502 public void TestIncrementOperator()
471 { 503 {
504 TestHelpers.InMethod();
505
472 LSL_Types.LSLFloat testFloat; 506 LSL_Types.LSLFloat testFloat;
473 double testNumber; 507 double testNumber;
474 508
@@ -493,6 +527,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
493 [Test] 527 [Test]
494 public void TestDecrementOperator() 528 public void TestDecrementOperator()
495 { 529 {
530 TestHelpers.InMethod();
531
496 LSL_Types.LSLFloat testFloat; 532 LSL_Types.LSLFloat testFloat;
497 double testNumber; 533 double testNumber;
498 534
@@ -517,6 +553,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
517 [Test] 553 [Test]
518 public void TestToString() 554 public void TestToString()
519 { 555 {
556 TestHelpers.InMethod();
557
520 LSL_Types.LSLFloat testFloat; 558 LSL_Types.LSLFloat testFloat;
521 559
522 foreach (KeyValuePair<double, string> number in m_doubleStringSet) 560 foreach (KeyValuePair<double, string> number in m_doubleStringSet)
@@ -532,6 +570,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
532 [Test] 570 [Test]
533 public void TestAddTwoLSLFloats() 571 public void TestAddTwoLSLFloats()
534 { 572 {
573 TestHelpers.InMethod();
574
535 LSL_Types.LSLFloat testResult; 575 LSL_Types.LSLFloat testResult;
536 576
537 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet) 577 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet)
@@ -547,6 +587,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
547 [Test] 587 [Test]
548 public void TestSubtractTwoLSLFloats() 588 public void TestSubtractTwoLSLFloats()
549 { 589 {
590 TestHelpers.InMethod();
591
550 LSL_Types.LSLFloat testResult; 592 LSL_Types.LSLFloat testResult;
551 593
552 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet) 594 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet)
@@ -562,6 +604,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
562 [Test] 604 [Test]
563 public void TestMultiplyTwoLSLFloats() 605 public void TestMultiplyTwoLSLFloats()
564 { 606 {
607 TestHelpers.InMethod();
608
565 LSL_Types.LSLFloat testResult; 609 LSL_Types.LSLFloat testResult;
566 610
567 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet) 611 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet)
@@ -577,6 +621,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
577 [Test] 621 [Test]
578 public void TestDivideTwoLSLFloats() 622 public void TestDivideTwoLSLFloats()
579 { 623 {
624 TestHelpers.InMethod();
625
580 LSL_Types.LSLFloat testResult; 626 LSL_Types.LSLFloat testResult;
581 627
582 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet) 628 foreach (KeyValuePair<double, double> number in m_doubleDoubleSet)
@@ -595,6 +641,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
595 [Test] 641 [Test]
596 public void TestImplicitCastBooleanToLSLFloat() 642 public void TestImplicitCastBooleanToLSLFloat()
597 { 643 {
644 TestHelpers.InMethod();
645
598 LSL_Types.LSLFloat testFloat; 646 LSL_Types.LSLFloat testFloat;
599 647
600 testFloat = (1 == 0); 648 testFloat = (1 == 0);
@@ -610,4 +658,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
610 Assert.That(testFloat.value, new DoubleToleranceConstraint(1.0, _lowPrecisionTolerance)); 658 Assert.That(testFloat.value, new DoubleToleranceConstraint(1.0, _lowPrecisionTolerance));
611 } 659 }
612 } 660 }
613} 661} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs
index 3ad673b..8d1169a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLInteger.cs
@@ -79,6 +79,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
79 [Test] 79 [Test]
80 public void TestExplicitCastLSLFloatToLSLInteger() 80 public void TestExplicitCastLSLFloatToLSLInteger()
81 { 81 {
82 TestHelpers.InMethod();
83
82 LSL_Types.LSLInteger testInteger; 84 LSL_Types.LSLInteger testInteger;
83 85
84 foreach (KeyValuePair<double, int> number in m_doubleIntSet) 86 foreach (KeyValuePair<double, int> number in m_doubleIntSet)
@@ -94,6 +96,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
94 [Test] 96 [Test]
95 public void TestExplicitCastStringToLSLInteger() 97 public void TestExplicitCastStringToLSLInteger()
96 { 98 {
99 TestHelpers.InMethod();
100
97 LSL_Types.LSLInteger testInteger; 101 LSL_Types.LSLInteger testInteger;
98 102
99 foreach (KeyValuePair<string, int> number in m_stringIntSet) 103 foreach (KeyValuePair<string, int> number in m_stringIntSet)
@@ -109,6 +113,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
109 [Test] 113 [Test]
110 public void TestExplicitCastLSLStringToLSLInteger() 114 public void TestExplicitCastLSLStringToLSLInteger()
111 { 115 {
116 TestHelpers.InMethod();
117
112 LSL_Types.LSLInteger testInteger; 118 LSL_Types.LSLInteger testInteger;
113 119
114 foreach (KeyValuePair<string, int> number in m_stringIntSet) 120 foreach (KeyValuePair<string, int> number in m_stringIntSet)
@@ -124,6 +130,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
124 [Test] 130 [Test]
125 public void TestImplicitCastBooleanToLSLInteger() 131 public void TestImplicitCastBooleanToLSLInteger()
126 { 132 {
133 TestHelpers.InMethod();
134
127 LSL_Types.LSLInteger testInteger; 135 LSL_Types.LSLInteger testInteger;
128 136
129 testInteger = (1 == 0); 137 testInteger = (1 == 0);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs
index fa976ed..c4ca1a8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestLSLString.cs
@@ -71,6 +71,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
71 [Test] 71 [Test]
72 public void TestConstructFromLSLFloat() 72 public void TestConstructFromLSLFloat()
73 { 73 {
74 TestHelpers.InMethod();
75
74 LSL_Types.LSLString testString; 76 LSL_Types.LSLString testString;
75 77
76 foreach (KeyValuePair<double, string> number in m_doubleStringSet) 78 foreach (KeyValuePair<double, string> number in m_doubleStringSet)
@@ -86,6 +88,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
86 [Test] 88 [Test]
87 public void TestExplicitCastLSLFloatToLSLString() 89 public void TestExplicitCastLSLFloatToLSLString()
88 { 90 {
91 TestHelpers.InMethod();
92
89 LSL_Types.LSLString testString; 93 LSL_Types.LSLString testString;
90 94
91 foreach (KeyValuePair<double, string> number in m_doubleStringSet) 95 foreach (KeyValuePair<double, string> number in m_doubleStringSet)
@@ -101,6 +105,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
101 [Test] 105 [Test]
102 public void TestExplicitCastLSLStringToQuaternion() 106 public void TestExplicitCastLSLStringToQuaternion()
103 { 107 {
108 TestHelpers.InMethod();
109
104 string quaternionString = "<0.00000, 0.70711, 0.00000, 0.70711>"; 110 string quaternionString = "<0.00000, 0.70711, 0.00000, 0.70711>";
105 LSL_Types.LSLString quaternionLSLString = new LSL_Types.LSLString(quaternionString); 111 LSL_Types.LSLString quaternionLSLString = new LSL_Types.LSLString(quaternionString);
106 112
@@ -118,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
118 [Test] 124 [Test]
119 public void TestImplicitCastBooleanToLSLFloat() 125 public void TestImplicitCastBooleanToLSLFloat()
120 { 126 {
127 TestHelpers.InMethod();
128
121 LSL_Types.LSLString testString; 129 LSL_Types.LSLString testString;
122 130
123 testString = (LSL_Types.LSLString) (1 == 0); 131 testString = (LSL_Types.LSLString) (1 == 0);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs
index 66a7329..b81225f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestList.cs
@@ -44,6 +44,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
44 [Test] 44 [Test]
45 public void TestConcatenateString() 45 public void TestConcatenateString()
46 { 46 {
47 TestHelpers.InMethod();
48
47 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test")); 49 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test"));
48 testList += new LSL_Types.LSLString("addition"); 50 testList += new LSL_Types.LSLString("addition");
49 51
@@ -64,6 +66,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
64 [Test] 66 [Test]
65 public void TestConcatenateInteger() 67 public void TestConcatenateInteger()
66 { 68 {
69 TestHelpers.InMethod();
70
67 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test")); 71 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test"));
68 testList += new LSL_Types.LSLInteger(20); 72 testList += new LSL_Types.LSLInteger(20);
69 73
@@ -84,6 +88,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
84 [Test] 88 [Test]
85 public void TestConcatenateDouble() 89 public void TestConcatenateDouble()
86 { 90 {
91 TestHelpers.InMethod();
92
87 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test")); 93 LSL_Types.list testList = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger('a'), new LSL_Types.LSLString("test"));
88 testList += new LSL_Types.LSLFloat(2.0f); 94 testList += new LSL_Types.LSLFloat(2.0f);
89 95
@@ -104,6 +110,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
104 [Test] 110 [Test]
105 public void TestCastLSLIntegerItemToLSLInteger() 111 public void TestCastLSLIntegerItemToLSLInteger()
106 { 112 {
113 TestHelpers.InMethod();
114
107 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(123); 115 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(123);
108 LSL_Types.list testList = new LSL_Types.list(testValue); 116 LSL_Types.list testList = new LSL_Types.list(testValue);
109 117
@@ -116,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
116 [Test] 124 [Test]
117 public void TestCastLSLFloatItemToLSLFloat() 125 public void TestCastLSLFloatItemToLSLFloat()
118 { 126 {
127 TestHelpers.InMethod();
128
119 LSL_Types.LSLFloat testValue = new LSL_Types.LSLFloat(123.45678987); 129 LSL_Types.LSLFloat testValue = new LSL_Types.LSLFloat(123.45678987);
120 LSL_Types.list testList = new LSL_Types.list(testValue); 130 LSL_Types.list testList = new LSL_Types.list(testValue);
121 131
@@ -128,6 +138,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
128 [Test] 138 [Test]
129 public void TestCastLSLStringItemToLSLString() 139 public void TestCastLSLStringItemToLSLString()
130 { 140 {
141 TestHelpers.InMethod();
142
131 LSL_Types.LSLString testValue = new LSL_Types.LSLString("hello there"); 143 LSL_Types.LSLString testValue = new LSL_Types.LSLString("hello there");
132 LSL_Types.list testList = new LSL_Types.list(testValue); 144 LSL_Types.list testList = new LSL_Types.list(testValue);
133 145
@@ -140,6 +152,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
140 [Test] 152 [Test]
141 public void TestCastVector3ItemToVector3() 153 public void TestCastVector3ItemToVector3()
142 { 154 {
155 TestHelpers.InMethod();
156
143 LSL_Types.Vector3 testValue = new LSL_Types.Vector3(12.34, 56.987654, 0.00987); 157 LSL_Types.Vector3 testValue = new LSL_Types.Vector3(12.34, 56.987654, 0.00987);
144 LSL_Types.list testList = new LSL_Types.list(testValue); 158 LSL_Types.list testList = new LSL_Types.list(testValue);
145 159
@@ -151,6 +165,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
151 [Test] 165 [Test]
152 public void TestCastQuaternionItemToQuaternion() 166 public void TestCastQuaternionItemToQuaternion()
153 { 167 {
168 TestHelpers.InMethod();
169
154 LSL_Types.Quaternion testValue = new LSL_Types.Quaternion(12.34, 56.44323, 765.983421, 0.00987); 170 LSL_Types.Quaternion testValue = new LSL_Types.Quaternion(12.34, 56.44323, 765.983421, 0.00987);
155 LSL_Types.list testList = new LSL_Types.list(testValue); 171 LSL_Types.list testList = new LSL_Types.list(testValue);
156 172
@@ -165,6 +181,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
165 [Test] 181 [Test]
166 public void TestGetLSLIntegerItemForLSLIntegerItem() 182 public void TestGetLSLIntegerItemForLSLIntegerItem()
167 { 183 {
184 TestHelpers.InMethod();
185
168 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(999911); 186 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(999911);
169 LSL_Types.list testList = new LSL_Types.list(testValue); 187 LSL_Types.list testList = new LSL_Types.list(testValue);
170 188
@@ -177,6 +195,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
177 [Test] 195 [Test]
178 public void TestGetLSLFloatItemForLSLFloatItem() 196 public void TestGetLSLFloatItemForLSLFloatItem()
179 { 197 {
198 TestHelpers.InMethod();
199
180 LSL_Types.LSLFloat testValue = new LSL_Types.LSLFloat(321.45687876); 200 LSL_Types.LSLFloat testValue = new LSL_Types.LSLFloat(321.45687876);
181 LSL_Types.list testList = new LSL_Types.list(testValue); 201 LSL_Types.list testList = new LSL_Types.list(testValue);
182 202
@@ -189,11 +209,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
189 [Test] 209 [Test]
190 public void TestGetLSLFloatItemForLSLIntegerItem() 210 public void TestGetLSLFloatItemForLSLIntegerItem()
191 { 211 {
192 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(3060987); 212 TestHelpers.InMethod();
193 LSL_Types.LSLFloat testFloatValue = new LSL_Types.LSLFloat(testValue); 213
194 LSL_Types.list testList = new LSL_Types.list(testValue); 214 LSL_Types.LSLInteger testValue = new LSL_Types.LSLInteger(3060987);
215 LSL_Types.LSLFloat testFloatValue = new LSL_Types.LSLFloat(testValue);
216 LSL_Types.list testList = new LSL_Types.list(testValue);
195 217
196 Assert.AreEqual(testFloatValue, testList.GetLSLFloatItem(0)); 218 Assert.AreEqual(testFloatValue, testList.GetLSLFloatItem(0));
197 } 219 }
198 220
199 /// <summary> 221 /// <summary>
@@ -202,6 +224,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
202 [Test] 224 [Test]
203 public void TestGetLSLStringItemForLSLStringItem() 225 public void TestGetLSLStringItemForLSLStringItem()
204 { 226 {
227 TestHelpers.InMethod();
228
205 LSL_Types.LSLString testValue = new LSL_Types.LSLString("hello all"); 229 LSL_Types.LSLString testValue = new LSL_Types.LSLString("hello all");
206 LSL_Types.list testList = new LSL_Types.list(testValue); 230 LSL_Types.list testList = new LSL_Types.list(testValue);
207 231
@@ -214,6 +238,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
214 [Test] 238 [Test]
215 public void TestGetLSLStringItemForKeyItem() 239 public void TestGetLSLStringItemForKeyItem()
216 { 240 {
241 TestHelpers.InMethod();
242
217 LSL_Types.key testValue 243 LSL_Types.key testValue
218 = new LSL_Types.key("98000000-0000-2222-3333-100000001000"); 244 = new LSL_Types.key("98000000-0000-2222-3333-100000001000");
219 LSL_Types.LSLString testStringValue = new LSL_Types.LSLString(testValue); 245 LSL_Types.LSLString testStringValue = new LSL_Types.LSLString(testValue);
@@ -228,6 +254,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
228 [Test] 254 [Test]
229 public void TestGetVector3ItemForVector3Item() 255 public void TestGetVector3ItemForVector3Item()
230 { 256 {
257 TestHelpers.InMethod();
258
231 LSL_Types.Vector3 testValue = new LSL_Types.Vector3(92.34, 58.98754, -0.10987); 259 LSL_Types.Vector3 testValue = new LSL_Types.Vector3(92.34, 58.98754, -0.10987);
232 LSL_Types.list testList = new LSL_Types.list(testValue); 260 LSL_Types.list testList = new LSL_Types.list(testValue);
233 261
@@ -239,6 +267,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
239 [Test] 267 [Test]
240 public void TestGetQuaternionItemForQuaternionItem() 268 public void TestGetQuaternionItemForQuaternionItem()
241 { 269 {
270 TestHelpers.InMethod();
271
242 LSL_Types.Quaternion testValue = new LSL_Types.Quaternion(12.64, 59.43723, 765.3421, 4.00987); 272 LSL_Types.Quaternion testValue = new LSL_Types.Quaternion(12.64, 59.43723, 765.3421, 4.00987);
243 LSL_Types.list testList = new LSL_Types.list(testValue); 273 LSL_Types.list testList = new LSL_Types.list(testValue);
244 274
@@ -251,6 +281,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
251 [Test] 281 [Test]
252 public void TestGetKeyItemForKeyItem() 282 public void TestGetKeyItemForKeyItem()
253 { 283 {
284 TestHelpers.InMethod();
285
254 LSL_Types.key testValue 286 LSL_Types.key testValue
255 = new LSL_Types.key("00000000-0000-2222-3333-100000001012"); 287 = new LSL_Types.key("00000000-0000-2222-3333-100000001012");
256 LSL_Types.list testList = new LSL_Types.list(testValue); 288 LSL_Types.list testList = new LSL_Types.list(testValue);
@@ -258,4 +290,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
258 Assert.AreEqual(testValue, testList.GetKeyItem(0)); 290 Assert.AreEqual(testValue, testList.GetKeyItem(0));
259 } 291 }
260 } 292 }
261} 293} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs
index 195af7f..ebf8001 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_TypesTestVector3.cs
@@ -32,16 +32,17 @@ using OpenSim.Region.ScriptEngine.Shared;
32 32
33namespace OpenSim.Region.ScriptEngine.Shared.Tests 33namespace OpenSim.Region.ScriptEngine.Shared.Tests
34{ 34{
35 /// <summary>
36 /// Tests for Vector3
37 /// </summary>
35 [TestFixture] 38 [TestFixture]
36 public class LSL_TypesTestVector3 39 public class LSL_TypesTestVector3
37 { 40 {
38 /// <summary>
39 /// Tests for Vector3
40 /// </summary>
41 [Test] 41 [Test]
42
43 public void TestDotProduct() 42 public void TestDotProduct()
44 { 43 {
44 TestHelpers.InMethod();
45
45 // The numbers we test for. 46 // The numbers we test for.
46 Dictionary<string, double> expectsSet = new Dictionary<string, double>(); 47 Dictionary<string, double> expectsSet = new Dictionary<string, double>();
47 expectsSet.Add("<1, 2, 3> * <2, 3, 4>", 20.0); 48 expectsSet.Add("<1, 2, 3> * <2, 3, 4>", 20.0);
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c68f03f..7712076 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -49,7 +49,10 @@ using OpenSim.Region.ScriptEngine.Shared;
49using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 49using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
50using OpenSim.Region.ScriptEngine.Shared.CodeTools; 50using OpenSim.Region.ScriptEngine.Shared.CodeTools;
51using OpenSim.Region.ScriptEngine.Shared.Instance; 51using OpenSim.Region.ScriptEngine.Shared.Instance;
52using OpenSim.Region.ScriptEngine.Shared.Api;
53using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
52using OpenSim.Region.ScriptEngine.Interfaces; 54using OpenSim.Region.ScriptEngine.Interfaces;
55using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
53 56
54using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 57using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
55 58
@@ -173,12 +176,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
173 get { return m_ConfigSource; } 176 get { return m_ConfigSource; }
174 } 177 }
175 178
179 /// <summary>
180 /// Event fired after the script engine has finished removing a script.
181 /// </summary>
176 public event ScriptRemoved OnScriptRemoved; 182 public event ScriptRemoved OnScriptRemoved;
183
184 /// <summary>
185 /// Event fired after the script engine has finished removing a script from an object.
186 /// </summary>
177 public event ObjectRemoved OnObjectRemoved; 187 public event ObjectRemoved OnObjectRemoved;
178 188
179 //
180 // IRegionModule functions
181 //
182 public void Initialise(IConfigSource configSource) 189 public void Initialise(IConfigSource configSource)
183 { 190 {
184 if (configSource.Configs["XEngine"] == null) 191 if (configSource.Configs["XEngine"] == null)
@@ -274,22 +281,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine
274 } 281 }
275 282
276 MainConsole.Instance.Commands.AddCommand( 283 MainConsole.Instance.Commands.AddCommand(
277 "scripts", false, "xengine status", "xengine status", "Show status information", 284 "Scripts", false, "xengine status", "xengine status", "Show status information",
278 "Show status information on the script engine.", 285 "Show status information on the script engine.",
279 HandleShowStatus); 286 HandleShowStatus);
280 287
281 MainConsole.Instance.Commands.AddCommand( 288 MainConsole.Instance.Commands.AddCommand(
282 "scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", 289 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information",
283 "Show information on all scripts known to the script engine." 290 "Show information on all scripts known to the script engine."
284 + "If a <script-item-uuid> is given then only information on that script will be shown.", 291 + "If a <script-item-uuid> is given then only information on that script will be shown.",
285 HandleShowScripts); 292 HandleShowScripts);
286 293
287 MainConsole.Instance.Commands.AddCommand( 294 MainConsole.Instance.Commands.AddCommand(
288 "scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", 295 "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information",
289 "Synonym for scripts show command", HandleShowScripts); 296 "Synonym for scripts show command", HandleShowScripts);
290 297
291 MainConsole.Instance.Commands.AddCommand( 298 MainConsole.Instance.Commands.AddCommand(
292 "scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", 299 "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts",
293 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" 300 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a"
294 + " script that is currently processing an event.\n" 301 + " script that is currently processing an event.\n"
295 + "Suspended scripts will continue to accumulate events but won't process them.\n" 302 + "Suspended scripts will continue to accumulate events but won't process them.\n"
@@ -297,20 +304,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
297 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); 304 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript));
298 305
299 MainConsole.Instance.Commands.AddCommand( 306 MainConsole.Instance.Commands.AddCommand(
300 "scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", 307 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts",
301 "Resumes all currently suspended scripts.\n" 308 "Resumes all currently suspended scripts.\n"
302 + "Resumed scripts will process all events accumulated whilst suspended." 309 + "Resumed scripts will process all events accumulated whilst suspended."
303 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", 310 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
304 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); 311 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
305 312
306 MainConsole.Instance.Commands.AddCommand( 313 MainConsole.Instance.Commands.AddCommand(
307 "scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", 314 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts",
308 "Stops all running scripts." 315 "Stops all running scripts."
309 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", 316 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
310 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); 317 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
311 318
312 MainConsole.Instance.Commands.AddCommand( 319 MainConsole.Instance.Commands.AddCommand(
313 "scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", 320 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts",
314 "Starts all stopped scripts." 321 "Starts all stopped scripts."
315 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", 322 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.",
316 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); 323 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
@@ -373,6 +380,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
373 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) 380 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
374 return; 381 return;
375 382
383 MainConsole.Instance.OutputFormat(GetStatusReport());
384 }
385
386 public string GetStatusReport()
387 {
376 StringBuilder sb = new StringBuilder(); 388 StringBuilder sb = new StringBuilder();
377 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); 389 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName);
378 390
@@ -381,12 +393,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine
381 393
382 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); 394 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
383 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); 395 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
396 sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads);
397 sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads);
384 sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads); 398 sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads);
385 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); 399 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads);
386 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); 400 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks);
387// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); 401// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
388 402
389 MainConsole.Instance.OutputFormat(sb.ToString()); 403 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this);
404 sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0);
405
406 Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this);
407 sb.AppendFormat("Dataserver requests : {0}\n", ds != null ? ds.DataserverRequestsCount : 0);
408
409 Timer t = AsyncCommandManager.GetTimerPlugin(this);
410 sb.AppendFormat("Timers : {0}\n", t != null ? t.TimersCount : 0);
411
412 Listener l = AsyncCommandManager.GetListenerPlugin(this);
413 sb.AppendFormat("Listeners : {0}\n", l != null ? l.ListenerCount : 0);
414
415 return sb.ToString();
390 } 416 }
391 417
392 public void HandleShowScripts(string module, string[] cmdparams) 418 public void HandleShowScripts(string module, string[] cmdparams)
@@ -973,7 +999,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
973 lock (m_Scripts) 999 lock (m_Scripts)
974 { 1000 {
975 // Create the object record 1001 // Create the object record
976
977 if ((!m_Scripts.ContainsKey(itemID)) || 1002 if ((!m_Scripts.ContainsKey(itemID)) ||
978 (m_Scripts[itemID].AssetID != assetID)) 1003 (m_Scripts[itemID].AssetID != assetID))
979 { 1004 {
@@ -1063,7 +1088,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1063 1088
1064 if (!m_PrimObjects[localID].Contains(itemID)) 1089 if (!m_PrimObjects[localID].Contains(itemID))
1065 m_PrimObjects[localID].Add(itemID); 1090 m_PrimObjects[localID].Add(itemID);
1066
1067 } 1091 }
1068 1092
1069 if (!m_Assemblies.ContainsKey(assetID)) 1093 if (!m_Assemblies.ContainsKey(assetID))
@@ -1102,7 +1126,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1102 } 1126 }
1103 1127
1104 instance.ClearQueue(); 1128 instance.ClearQueue();
1105 instance.Stop(0); 1129
1130 // Give the script some time to finish processing its last event. Simply aborting the script thread can
1131 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1132 instance.Stop(1000);
1133
1106// bool objectRemoved = false; 1134// bool objectRemoved = false;
1107 1135
1108 lock (m_PrimObjects) 1136 lock (m_PrimObjects)
@@ -1133,14 +1161,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 UnloadAppDomain(instance.AppDomain); 1161 UnloadAppDomain(instance.AppDomain);
1134 } 1162 }
1135 1163
1136 instance = null;
1137
1138 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1164 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1139 if (handlerObjectRemoved != null) 1165 if (handlerObjectRemoved != null)
1140 { 1166 handlerObjectRemoved(instance.ObjectID);
1141 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1142 handlerObjectRemoved(part.UUID);
1143 }
1144 1167
1145 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1168 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1146 if (handlerScriptRemoved != null) 1169 if (handlerScriptRemoved != null)
@@ -1872,6 +1895,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1872 } 1895 }
1873 } 1896 }
1874 1897
1898 public Dictionary<uint, float> GetObjectScriptsExecutionTimes()
1899 {
1900 long tickNow = Util.EnvironmentTickCount();
1901 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1902
1903 lock (m_Scripts)
1904 {
1905 foreach (IScriptInstance si in m_Scripts.Values)
1906 {
1907 if (!topScripts.ContainsKey(si.LocalID))
1908 topScripts[si.RootLocalID] = 0;
1909
1910// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1911// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond);
1912
1913 // Execution time of the script adjusted by it's measurement period to make scripts started at
1914 // different times comparable.
1915// float adjustedExecutionTime
1916// = (float)si.MeasurementPeriodExecutionTime
1917// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
1918// / TimeSpan.TicksPerMillisecond;
1919
1920 long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1921
1922 // Avoid divide by zerp
1923 if (ticksElapsed == 0)
1924 ticksElapsed = 1;
1925
1926 // Scale execution time to the ideal 55 fps frame time for these reasons.
1927 //
1928 // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
1929 // 'script execution time per frame', which is the original purpose of this value.
1930 //
1931 // 2) Giving the raw execution times is misleading since scripts start at different times, making
1932 // it impossible to compare scripts.
1933 //
1934 // 3) Scaling the raw execution time to the time that the script has been running is better but
1935 // is still misleading since a script that has just been rezzed may appear to have been running
1936 // for much longer.
1937 //
1938 // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
1939 // since the figure does not represent actual execution time and very hard running scripts will
1940 // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
1941 float adjustedExecutionTime
1942 = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
1943
1944 topScripts[si.RootLocalID] += adjustedExecutionTime;
1945 }
1946 }
1947
1948 return topScripts;
1949 }
1950
1875 public void SuspendScript(UUID itemID) 1951 public void SuspendScript(UUID itemID)
1876 { 1952 {
1877// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); 1953// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID);