From 9b66108081a8c8cf79faaa6c541554091c40850e Mon Sep 17 00:00:00 2001
From: Dr Scofield
Date: Fri, 6 Feb 2009 16:55:34 +0000
Subject: This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part.
This first changeset refactors OpenSim.Region.Environment.Scenes,
OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into
OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in
OpenSim.Region.Environment.
The next step will be to move region modules up from
OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and
then sort out which modules are really core modules and which should
move out to forge.
I've been very careful to NOT BREAK anything. i hope i've
succeeded. as this is the work of a whole week i hope i managed to
keep track with the applied patches of the last week --- could any of
you that did check in stuff have a look at whether it survived? thx!
---
.../Interfaces/IAgentAssetTransactions.cs | 49 +
.../Region/Framework/Interfaces/IAvatarFactory.cs | 39 +
.../Framework/Interfaces/ICapabilitiesModule.cs | 74 +
OpenSim/Region/Framework/Interfaces/ICommand.cs | 50 +
.../Framework/Interfaces/ICommandableModule.cs | 37 +
OpenSim/Region/Framework/Interfaces/ICommander.cs | 47 +
.../Region/Framework/Interfaces/IDialogModule.cs | 136 +
.../Framework/Interfaces/IDynamicTextureManager.cs | 58 +
.../Region/Framework/Interfaces/IEmailModule.cs | 48 +
.../Region/Framework/Interfaces/IEntityCreator.cs | 56 +
.../Framework/Interfaces/IEntityInventory.cs | 207 +
.../Framework/Interfaces/IEstateDataStore.cs | 41 +
.../Region/Framework/Interfaces/IEstateModule.cs | 44 +
OpenSim/Region/Framework/Interfaces/IEventQueue.cs | 64 +
.../Region/Framework/Interfaces/IFriendsModule.cs | 49 +
.../Region/Framework/Interfaces/IGroupsModule.cs | 68 +
.../Region/Framework/Interfaces/IHttpRequests.cs | 51 +
.../Framework/Interfaces/IInterregionComms.cs | 81 +
.../Interfaces/IInventoryTransferModule.cs | 42 +
OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs | 41 +
.../Region/Framework/Interfaces/ILandChannel.cs | 49 +
OpenSim/Region/Framework/Interfaces/ILandObject.cs | 83 +
.../Framework/Interfaces/IMessageTransferModule.cs | 40 +
.../Region/Framework/Interfaces/IPresenceModule.cs | 56 +
.../Framework/Interfaces/IRegionArchiverModule.cs | 75 +
.../Framework/Interfaces/IRegionDataStore.cs | 109 +
.../Region/Framework/Interfaces/IRegionModule.cs | 41 +
.../Interfaces/IRegionSerialiserModule.cs | 122 +
.../Region/Framework/Interfaces/IScriptModule.cs | 41 +
.../Region/Framework/Interfaces/IServiceRequest.cs | 45 +
.../Region/Framework/Interfaces/ISoundModule.cs | 41 +
OpenSim/Region/Framework/Interfaces/ITerrain.cs | 78 +
.../Region/Framework/Interfaces/ITerrainChannel.cs | 48 +
.../Region/Framework/Interfaces/ITextureSender.cs | 58 +
.../Framework/Interfaces/IVegetationModule.cs | 49 +
OpenSim/Region/Framework/Interfaces/IWindModule.cs | 41 +
OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 64 +
OpenSim/Region/Framework/Interfaces/IXMLRPC.cs | 66 +
OpenSim/Region/Framework/Interfaces/IXfer.cs | 34 +
OpenSim/Region/Framework/ModuleLoader.cs | 255 ++
OpenSim/Region/Framework/Scenes/Animation.cs | 59 +
OpenSim/Region/Framework/Scenes/AnimationSet.cs | 155 +
.../Scenes/AsyncSceneObjectGroupDeleter.cs | 165 +
.../Region/Framework/Scenes/AvatarAnimations.cs | 63 +
OpenSim/Region/Framework/Scenes/EntityBase.cs | 253 ++
OpenSim/Region/Framework/Scenes/EntityManager.cs | 279 ++
OpenSim/Region/Framework/Scenes/EventManager.cs | 981 +++++
.../Framework/Scenes/Hypergrid/HGAssetMapper.cs | 376 ++
.../Scenes/Hypergrid/HGScene.Inventory.cs | 152 +
.../Region/Framework/Scenes/Hypergrid/HGScene.cs | 84 +
.../Hypergrid/HGSceneCommunicationService.cs | 360 ++
.../Region/Framework/Scenes/IScenePresenceBody.cs | 37 +
OpenSim/Region/Framework/Scenes/ReturnInfo.cs | 39 +
OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2665 ++++++++++++
.../Framework/Scenes/Scene.PacketHandlers.cs | 632 +++
.../Region/Framework/Scenes/Scene.Permissions.cs | 1334 ++++++
OpenSim/Region/Framework/Scenes/Scene.cs | 4239 ++++++++++++++++++++
OpenSim/Region/Framework/Scenes/SceneBase.cs | 419 ++
.../Framework/Scenes/SceneCommunicationService.cs | 1095 +++++
OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1814 +++++++++
OpenSim/Region/Framework/Scenes/SceneManager.cs | 669 +++
.../Framework/Scenes/SceneObjectGroup.Inventory.cs | 401 ++
.../Region/Framework/Scenes/SceneObjectGroup.cs | 3012 ++++++++++++++
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3826 ++++++++++++++++++
.../Framework/Scenes/SceneObjectPartInventory.cs | 891 ++++
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3649 +++++++++++++++++
OpenSim/Region/Framework/Scenes/SceneXmlLoader.cs | 289 ++
.../Framework/Scenes/Scripting/IScriptHost.cs | 46 +
.../Framework/Scenes/Scripting/NullScriptHost.cs | 86 +
.../Scenes/Scripting/ScriptEngineInterface.cs | 38 +
.../Scenes/Scripting/ScriptEngineLoader.cs | 119 +
.../Region/Framework/Scenes/SimStatsReporter.cs | 450 +++
OpenSim/Region/Framework/Scenes/TerrainChannel.cs | 242 ++
OpenSim/Region/Framework/Scenes/TerrainUtil.cs | 132 +
.../Framework/Scenes/Tests/EntityManagerTests.cs | 176 +
.../Scenes/Tests/SceneObjectBasicTests.cs | 139 +
.../Scenes/Tests/SceneObjectLinkingTests.cs | 249 ++
.../Framework/Scenes/Tests/ScenePresenceTests.cs | 292 ++
.../Scenes/Tests/StandaloneTeleportTests.cs | 105 +
.../Framework/Scenes/Types/BasicQuadTreeNode.cs | 269 ++
.../Region/Framework/Scenes/Types/UpdateQueue.cs | 134 +
OpenSim/Region/Framework/Scenes/UndoState.cs | 116 +
OpenSim/Region/Framework/StorageManager.cs | 96 +
83 files changed, 33304 insertions(+)
create mode 100644 OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ICommand.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ICommandableModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ICommander.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IDialogModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEmailModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEntityCreator.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEstateModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IEventQueue.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IInventoryTransferModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ILandChannel.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ILandObject.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IMessageTransferModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IPresenceModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IScriptModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IServiceRequest.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ISoundModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ITerrain.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/ITextureSender.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IVegetationModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IWindModule.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IWorldComm.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IXMLRPC.cs
create mode 100644 OpenSim/Region/Framework/Interfaces/IXfer.cs
create mode 100644 OpenSim/Region/Framework/ModuleLoader.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Animation.cs
create mode 100644 OpenSim/Region/Framework/Scenes/AnimationSet.cs
create mode 100644 OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
create mode 100644 OpenSim/Region/Framework/Scenes/AvatarAnimations.cs
create mode 100644 OpenSim/Region/Framework/Scenes/EntityBase.cs
create mode 100644 OpenSim/Region/Framework/Scenes/EntityManager.cs
create mode 100644 OpenSim/Region/Framework/Scenes/EventManager.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
create mode 100644 OpenSim/Region/Framework/Scenes/IScenePresenceBody.cs
create mode 100644 OpenSim/Region/Framework/Scenes/ReturnInfo.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scene.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneBase.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneGraph.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneManager.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
create mode 100644 OpenSim/Region/Framework/Scenes/ScenePresence.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SceneXmlLoader.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineInterface.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Scripting/ScriptEngineLoader.cs
create mode 100644 OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
create mode 100644 OpenSim/Region/Framework/Scenes/TerrainChannel.cs
create mode 100644 OpenSim/Region/Framework/Scenes/TerrainUtil.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Tests/StandaloneTeleportTests.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Types/BasicQuadTreeNode.cs
create mode 100644 OpenSim/Region/Framework/Scenes/Types/UpdateQueue.cs
create mode 100644 OpenSim/Region/Framework/Scenes/UndoState.cs
create mode 100644 OpenSim/Region/Framework/StorageManager.cs
(limited to 'OpenSim/Region/Framework')
diff --git a/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs b/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs
new file mode 100644
index 0000000..49a5dd0
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IAgentAssetTransactions
+ {
+ void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID,
+ InventoryItemBase item);
+
+ void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
+ uint callbackID, string description, string name, sbyte invType,
+ sbyte type, byte wearableType, uint nextOwnerMask);
+
+ void HandleTaskItemUpdateFromTransaction(
+ IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item);
+
+ void RemoveAgentAssetTransactions(UUID userID);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
new file mode 100644
index 0000000..b533206
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IAvatarFactory
+ {
+ bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance);
+ void UpdateDatabase(UUID userID, AvatarAppearance avatAppearance);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs
new file mode 100644
index 0000000..bac0b2e
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ICapabilitiesModule.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ICapabilitiesModule
+ {
+ void NewUserConnection(AgentCircuitData agent);
+
+ ///
+ /// Add a caps handler for the given agent. If the CAPS handler already exists for this agent,
+ /// then it is replaced by a new CAPS handler.
+ ///
+ /// FIXME: On login this is called twice, once for the login and once when the connection is made.
+ /// This is somewhat innefficient and should be fixed. The initial login creation is necessary
+ /// since the client asks for capabilities immediately after being informed of the seed.
+ ///
+ ///
+ ///
+ void AddCapsHandler(UUID agentId);
+
+ ///
+ /// Remove the caps handler for a given agent.
+ ///
+ ///
+ void RemoveCapsHandler(UUID agentId);
+
+ ///
+ /// Will return null if the agent doesn't have a caps handler registered
+ ///
+ ///
+ Caps GetCapsHandlerForUser(UUID agentId);
+
+ Dictionary GetChildrenSeeds(UUID agentID);
+
+ string GetChildSeed(UUID agentID, ulong handle);
+
+ void SetChildrenSeed(UUID agentID, Dictionary seeds);
+
+ void DropChildSeed(UUID agentID, ulong handle);
+
+ string GetCapsPath(UUID agentId);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ICommand.cs b/OpenSim/Region/Framework/Interfaces/ICommand.cs
new file mode 100644
index 0000000..1551b58
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ICommand.cs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public enum CommandIntentions
+ {
+ COMMAND_STATISTICAL,
+ COMMAND_NON_HAZARDOUS,
+ COMMAND_HAZARDOUS
+ };
+
+ public interface ICommand
+ {
+ void AddArgument(string name, string helptext, string type);
+ Dictionary Arguments { get; }
+ string Help { get; }
+ string Name { get; }
+ CommandIntentions Intentions { get; }
+
+ void Run(object[] args);
+ void ShowConsoleHelp();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ICommandableModule.cs b/OpenSim/Region/Framework/Interfaces/ICommandableModule.cs
new file mode 100644
index 0000000..5d6660d
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ICommandableModule.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ICommandableModule
+ {
+ ICommander CommandInterface
+ {
+ get;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ICommander.cs b/OpenSim/Region/Framework/Interfaces/ICommander.cs
new file mode 100644
index 0000000..17a2e4a
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ICommander.cs
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ICommander
+ {
+ ///
+ /// The name of this commander
+ ///
+ string Name { get; }
+
+ ///
+ /// Provide general help information about this commander.
+ ///
+ string Help { get; }
+
+ void ProcessConsoleCommand(string function, string[] args);
+ void RegisterCommand(string commandName, ICommand command);
+ void Run(string function, object[] args);
+ string GenerateRuntimeAPI();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IDialogModule.cs b/OpenSim/Region/Framework/Interfaces/IDialogModule.cs
new file mode 100644
index 0000000..7247d52
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IDialogModule.cs
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IDialogModule
+ {
+ ///
+ /// Send a non-modal alert message to a particular user. This can disappear from the user's view after a
+ /// small interval.
+ ///
+ ///
+ ///
+ void SendAlertToUser(IClientAPI client, string message);
+
+ ///
+ /// Send an alert message to a particular user.
+ ///
+ ///
+ ///
+ ///
+ void SendAlertToUser(IClientAPI client, string message, bool modal);
+
+ ///
+ /// Send a non-modal alert message to a particular user.
+ ///
+ ///
+ ///
+ void SendAlertToUser(UUID agentID, string message);
+
+ ///
+ /// Send an alert message to a particular user.
+ ///
+ ///
+ ///
+ ///
+ void SendAlertToUser(UUID agentID, string message, bool modal);
+
+ ///
+ /// Send an alert message to a particular user.
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SendAlertToUser(string firstName, string lastName, string message, bool modal);
+
+ ///
+ /// Send an alert message to all users in the scene.
+ ///
+ ///
+ void SendGeneralAlert(string message);
+
+ ///
+ /// Send a dialog box to a particular user.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SendDialogToUser(
+ UUID avatarID, string objectName, UUID objectID, UUID ownerID,
+ string message, UUID textureID, int ch, string[] buttonlabels);
+
+ ///
+ /// Send a url to a particular user.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SendUrlToUser(
+ UUID avatarID, string objectName, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
+
+ ///
+ /// Send a notification to all users in the scene. This notification should remain around until the
+ /// user explicitly dismisses it.
+ ///
+ ///
+ /// On the Linden Labs Second Client (as of 1.21), this is a big blue box message on the upper right of the
+ /// screen.
+ ///
+ /// The user sending the message
+ /// The name of the user doing the sending
+ /// The message being sent to the user
+ void SendNotificationToUsersInRegion(UUID fromAvatarID, string fromAvatarName, string message);
+
+ ///
+ /// Send a notification to all users in the estate. This notification should remain around until the
+ /// user explicitly dismisses it.
+ ///
+ ///
+ /// On the Linden Labs Second Client (as of 1.21), this is a big blue box message on the upper right of the
+ /// screen.
+ ///
+ /// The user sending the message
+ /// The name of the user doing the sending
+ /// The message being sent to the user
+ void SendNotificationToUsersInEstate(UUID fromAvatarID, string fromAvatarName, string message);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
new file mode 100644
index 0000000..e119bc3
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IDynamicTextureManager
+ {
+ void RegisterRender(string handleType, IDynamicTextureRender render);
+ void ReturnData(UUID id, byte[] data);
+
+ UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
+ int updateTimer);
+ UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
+ int updateTimer, bool SetBlending, byte AlphaValue);
+ UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
+ int updateTimer);
+ UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams,
+ int updateTimer, bool SetBlending, byte AlphaValue);
+ }
+
+ public interface IDynamicTextureRender
+ {
+ string GetName();
+ string GetContentType();
+ bool SupportsAsynchronous();
+ byte[] ConvertUrl(string url, string extraParams);
+ byte[] ConvertStream(Stream data, string extraParams);
+ bool AsyncConvertUrl(UUID id, string url, string extraParams);
+ bool AsyncConvertData(UUID id, string bodyData, string extraParams);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs
new file mode 100644
index 0000000..b5f885a
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public class Email
+ {
+ public string time;
+ public string sender;
+ public string subject;
+ public string message;
+ public int numLeft;
+ }
+
+ public interface IEmailModule : IRegionModule
+ {
+ void SendEmail(UUID objectID, string address, string subject, string body);
+ Email GetNextEmail(UUID objectID, string sender, string subject);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityCreator.cs b/OpenSim/Region/Framework/Interfaces/IEntityCreator.cs
new file mode 100644
index 0000000..1a6e626
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEntityCreator.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// Interface to a class that is capable of creating entities
+ ///
+ public interface IEntityCreator
+ {
+ ///
+ /// The entities that this class is capable of creating. These match the PCode format.
+ ///
+ ///
+ PCode[] CreationCapabilities { get; }
+
+ ///
+ /// Create an entity
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The entity created, or null if the creation failed
+ SceneObjectGroup CreateEntity(UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
new file mode 100644
index 0000000..20fe090
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using OpenMetaverse;
+using log4net;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes.Scripting;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// Interface to an entity's (SceneObjectPart's) inventory
+ ///
+ ///
+ /// This is not a finished 1.0 candidate interface
+ public interface IEntityInventory
+ {
+ ///
+ /// Force the task inventory of this prim to persist at the next update sweep
+ ///
+ void ForceInventoryPersistence();
+
+ ///
+ /// Reset UUIDs for all the items in the prim's inventory.
+ ///
+ ///
+ /// This involves either generating
+ /// new ones or setting existing UUIDs to the correct parent UUIDs.
+ ///
+ /// If this method is called and there are inventory items, then we regard the inventory as having changed.
+ ///
+ /// Link number for the part
+ void ResetInventoryIDs();
+
+ ///
+ /// Change every item in this inventory to a new owner.
+ ///
+ ///
+ void ChangeInventoryOwner(UUID ownerId);
+
+ ///
+ /// Change every item in this inventory to a new group.
+ ///
+ ///
+ void ChangeInventoryGroup(UUID groupID);
+
+ ///
+ /// Start all the scripts contained in this entity's inventory
+ ///
+ void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
+
+ ///
+ /// Stop all the scripts in this entity.
+ ///
+ void RemoveScriptInstances();
+
+ ///
+ /// Start a script which is in this entity's inventory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ void CreateScriptInstance(
+ TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource);
+
+ ///
+ /// Start a script which is in this entity's inventory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
+
+ ///
+ /// Stop a script which is in this prim's inventory.
+ ///
+ ///
+ void RemoveScriptInstance(UUID itemId);
+
+ ///
+ /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
+ /// name is chosen.
+ ///
+ ///
+ void AddInventoryItem(TaskInventoryItem item, bool allowedDrop);
+
+ ///
+ /// Add an item to this entity's inventory. If an item with the same name already exists, it is replaced.
+ ///
+ ///
+ void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop);
+
+ ///
+ /// Restore a whole collection of items to the entity's inventory at once.
+ /// We assume that the items already have all their fields correctly filled out.
+ /// The items are not flagged for persistence to the database, since they are being restored
+ /// from persistence rather than being newly added.
+ ///
+ ///
+ void RestoreInventoryItems(ICollection items);
+
+ ///
+ /// Returns an existing inventory item. Returns the original, so any changes will be live.
+ ///
+ ///
+ /// null if the item does not exist
+ TaskInventoryItem GetInventoryItem(UUID itemId);
+
+ ///
+ /// Update an existing inventory item.
+ ///
+ /// The updated item. An item with the same id must already exist
+ /// in this prim's inventory.
+ /// false if the item did not exist, true if the update occurred successfully
+ bool UpdateInventoryItem(TaskInventoryItem item);
+
+ ///
+ /// Remove an item from this entity's inventory
+ ///
+ ///
+ /// Numeric asset type of the item removed. Returns -1 if the item did not exist
+ /// in this prim's inventory.
+ int RemoveInventoryItem(UUID itemID);
+
+ ///
+ /// Return the name with which a client can request a xfer of this prim's inventory metadata
+ ///
+ string GetInventoryFileName();
+
+ bool GetInventoryFileName(IClientAPI client, uint localID);
+
+ ///
+ /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
+ ///
+ ///
+ void RequestInventoryFile(IClientAPI client, IXfer xferManager);
+
+ ///
+ /// Backup the inventory to the given data store
+ ///
+ ///
+ void ProcessInventoryBackup(IRegionDataStore datastore);
+
+ uint MaskEffectivePermissions();
+
+ void ApplyNextOwnerPermissions();
+
+ void ApplyGodPermissions(uint perms);
+
+ ///
+ /// Returns true if this inventory contains any scripts
+ ///
+ bool ContainsScripts();
+
+ ///
+ /// Get the uuids of all items in this inventory
+ ///
+ ///
+ List GetInventoryList();
+
+ ///
+ /// Get the names of the assemblies associated with scripts in this inventory.
+ ///
+ ///
+ string[] GetScriptAssemblies();
+
+ ///
+ /// Get the xml representing the saved states of scripts in this inventory.
+ ///
+ ///
+ /// A
+ ///
+ Dictionary GetScriptStates();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs b/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
new file mode 100644
index 0000000..4da115e
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEstateDataStore.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IEstateDataStore
+ {
+ void Initialise(string connectstring);
+
+ EstateSettings LoadEstateSettings(UUID regionID);
+ void StoreEstateSettings(EstateSettings es);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
new file mode 100644
index 0000000..f169f61
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IEstateModule : IRegionModule
+ {
+ uint GetRegionFlags();
+ bool IsManager(UUID avatarID);
+
+ ///
+ /// Tell all clients about the current state of the region (terrain textures, water height, etc.).
+ ///
+ void sendRegionHandshakeToAll();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
new file mode 100644
index 0000000..cf609ae
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Net;
+using OpenSim.Framework;
+using OpenMetaverse;
+using OpenMetaverse.Packets;
+using OpenMetaverse.StructuredData;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IEventQueue
+ {
+ bool Enqueue(OSD o, UUID avatarID);
+
+ // These are required to decouple Scenes from EventQueueHelper
+ void DisableSimulator(ulong handle, UUID avatarID);
+ void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID);
+ void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint,
+ string capsPath);
+ void TeleportFinishEvent(ulong regionHandle, byte simAccess,
+ IPEndPoint regionExternalEndPoint,
+ uint locationID, uint flags, string capsURL,
+ UUID agentID);
+ void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
+ IPEndPoint newRegionExternalEndPoint,
+ string capsURL, UUID avatarID, UUID sessionID);
+ void ChatterboxInvitation(UUID sessionID, string sessionName,
+ UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
+ uint timeStamp, bool offline, int parentEstateID, Vector3 position,
+ uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
+ void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat,
+ bool isModerator, bool textMute);
+ void ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket, UUID avatarID);
+ void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
new file mode 100644
index 0000000..0bdfb8f
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IFriendsModule
+ {
+ ///
+ /// Offer a friendship to a user from the server end rather than by direct initiation from a client.
+ ///
+ ///
+ /// A user with this id must existing in the user data store, but need not be logged on.
+ ///
+ ///
+ /// An actually logged in client to which the offer is being made.
+ /// FIXME: This is somewhat too tightly coupled - it should arguably be possible to offer friendships even if the
+ /// receiving user is not currently online.
+ ///
+ ///
+ void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
new file mode 100644
index 0000000..16527d1
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public delegate void NewGroupNotice(UUID groupID, UUID noticeID);
+
+ public interface IGroupsModule
+ {
+ event NewGroupNotice OnNewGroupNotice;
+
+ void ActivateGroup(IClientAPI remoteClient, UUID groupID);
+ List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID);
+ List GroupMembersRequest(IClientAPI remoteClient, UUID groupID);
+ List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID);
+ List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID);
+ GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID);
+ GroupMembershipData[] GetMembershipData(UUID UserID);
+
+ void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish);
+
+ void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile);
+
+ void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID);
+ UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish);
+
+ GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID);
+ string GetGroupTitle(UUID avatarID);
+ void GroupRoleUpdate(IClientAPI remoteClient, UUID GroupID, UUID RoleID, string name, string description, string title, ulong powers, byte updateType);
+ void GroupRoleChanges(IClientAPI remoteClient, UUID GroupID, UUID RoleID, UUID MemberID, uint changes);
+ void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID);
+ void SendGroupNoticeToClient(IClientAPI remoteClient, UUID groupNoticeID, byte dialog);
+ void SendAgentGroupDataUpdate(IClientAPI remoteClient);
+ void JoinGroupRequest(IClientAPI remoteClient, UUID GroupID);
+ void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID);
+ void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID);
+ void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
new file mode 100644
index 0000000..fd49757
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public enum HttpRequestConstants
+ {
+ HTTP_METHOD = 0,
+ HTTP_MIMETYPE = 1,
+ HTTP_BODY_MAXLENGTH = 2,
+ HTTP_VERIFY_CERT = 3,
+ }
+
+ public interface IHttpRequestModule
+ {
+ UUID MakeHttpRequest(string url, string parameters, string body);
+ UUID StartHttpRequest(uint localID, UUID itemID, string url, List parameters, Dictionary headers, string body);
+ void StopHttpRequest(uint m_localID, UUID m_itemID);
+ IServiceRequest GetNextCompletedRequest();
+ void RemoveCompletedRequest(UUID id);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
new file mode 100644
index 0000000..783b3f9
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public delegate bool ChildAgentUpdateReceived(AgentData data);
+
+ public interface IInterregionCommsOut
+ {
+ bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit);
+
+ ///
+ /// Full child agent update.
+ ///
+ ///
+ ///
+ ///
+ bool SendChildAgentUpdate(ulong regionHandle, AgentData data);
+
+ ///
+ /// Short child agent update, mostly for position.
+ ///
+ ///
+ ///
+ ///
+ bool SendChildAgentUpdate(ulong regionHandle, AgentPosition data);
+
+ ///
+ /// Message from receiving region to departing region, telling it got contacted by the client.
+ /// When sent over REST, it invokes the opaque uri.
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool SendReleaseAgent(ulong regionHandle, UUID id, string uri);
+
+ ///
+ /// Close agent.
+ ///
+ ///
+ ///
+ ///
+ bool SendCloseAgent(ulong regionHandle, UUID id);
+ }
+
+ // This may not be needed, but having it here for now.
+ public interface IInterregionCommsIn
+ {
+ event ChildAgentUpdateReceived OnChildAgentUpdate;
+ }
+
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryTransferModule.cs
new file mode 100644
index 0000000..4314271
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IInventoryTransferModule.cs
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// An interface for a module that manages inter-agent inventory offers and transfers.
+ ///
+ public interface IInventoryTransferModule
+ {
+ void SetRootAgentScene(UUID agentID, Scene scene);
+ bool NeedSceneCacheClear(UUID agentID, Scene scene);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
new file mode 100644
index 0000000..1d10896
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenMetaverse.Imaging;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+
+ public delegate void DecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers);
+
+ public interface IJ2KDecoder
+ {
+ void decode(UUID AssetId, byte[] assetData, DecodedCallback decodedReturn);
+ void syncdecode(UUID AssetId, byte[] j2kdata);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ILandChannel.cs b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs
new file mode 100644
index 0000000..35c2fc1
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ILandChannel
+ {
+ List ParcelsNearPoint(Vector3 position);
+ List AllParcels();
+ ILandObject GetLandObject(int x, int y);
+ ILandObject GetLandObject(float x, float y);
+ bool IsLandPrimCountTainted();
+ bool IsForcefulBansAllowed();
+ void UpdateLandObject(int localID, LandData data);
+ void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient);
+ void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
+ void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
+ void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ILandObject.cs b/OpenSim/Region/Framework/Interfaces/ILandObject.cs
new file mode 100644
index 0000000..52cc6cf
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ILandObject.cs
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public delegate int overrideParcelMaxPrimCountDelegate(ILandObject obj);
+ public delegate int overrideSimulatorMaxPrimCountDelegate(ILandObject obj);
+
+ public interface ILandObject
+ {
+ int getParcelMaxPrimCount(ILandObject thisObject);
+ int getSimulatorMaxPrimCount(ILandObject thisObject);
+
+ LandData landData { get; set; }
+ bool[,] landBitmap { get; set; }
+ UUID regionUUID { get; }
+ bool containsPoint(int x, int y);
+ ILandObject Copy();
+
+ void sendLandUpdateToAvatarsOverMe();
+
+ void sendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client);
+ void updateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
+ bool isEitherBannedOrRestricted(UUID avatar);
+ bool isBannedFromLand(UUID avatar);
+ bool isRestrictedFromLand(UUID avatar);
+ void sendLandUpdateToClient(IClientAPI remote_client);
+ List createAccessListArrayByFlag(AccessList flag);
+ void sendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client);
+ void updateAccessList(uint flags, List entries, IClientAPI remote_client);
+ void updateLandBitmapByteArray();
+ void setLandBitmapFromByteArray();
+ bool[,] getLandBitmap();
+ void forceUpdateLandInfo();
+ void setLandBitmap(bool[,] bitmap);
+
+
+ bool[,] basicFullRegionLandBitmap();
+ bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y);
+ bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value);
+ bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add);
+ void sendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client);
+ void sendLandObjectOwners(IClientAPI remote_client);
+ void returnObject(SceneObjectGroup obj);
+ void returnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client);
+ void resetLandPrimCounts();
+ void addPrimToCount(SceneObjectGroup obj);
+ void removePrimFromCount(SceneObjectGroup obj);
+ void updateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area);
+
+ void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
+ void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IMessageTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IMessageTransferModule.cs
new file mode 100644
index 0000000..f0a5473
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IMessageTransferModule.cs
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public delegate void MessageResultNotification(bool success);
+
+ public interface IMessageTransferModule
+ {
+ void SendInstantMessage(GridInstantMessage im, MessageResultNotification result);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs b/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs
new file mode 100644
index 0000000..011f8bb
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IPresenceModule.cs
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public struct PresenceInfo
+ {
+ public UUID userID;
+ public UUID regionID;
+
+ public PresenceInfo(UUID userID, UUID regionID)
+ {
+ this.userID = userID;
+ this.regionID = regionID;
+ }
+ }
+
+ public delegate void PresenceChange(PresenceInfo info);
+ public delegate void BulkPresenceData(PresenceInfo[] info);
+
+ public interface IPresenceModule
+ {
+ void RequestBulkPresenceData(UUID[] users);
+
+ event PresenceChange OnPresenceChange;
+ event BulkPresenceData OnBulkPresenceData;
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
new file mode 100644
index 0000000..97afe8d
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// Interface to region archive functionality
+ ///
+ public interface IRegionArchiverModule
+ {
+ ///
+ /// Archive the region to the given path
+ ///
+ ///
+ /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
+ /// the EventManager.OnOarFileSaved event.
+ ///
+ ///
+ void ArchiveRegion(string savePath);
+
+ ///
+ /// Archive the region to a stream.
+ ///
+ ///
+ /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
+ /// the EventManager.OnOarFileSaved event.
+ ///
+ ///
+ void ArchiveRegion(Stream saveStream);
+
+ ///
+ /// Dearchive the given region archive into the scene
+ ///
+ ///
+ /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
+ ///
+ ///
+ void DearchiveRegion(string loadPath);
+
+ ///
+ /// Dearchive a region from a stream.
+ ///
+ ///
+ /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
+ ///
+ ///
+ void DearchiveRegion(Stream loadStream);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
new file mode 100644
index 0000000..46d81ce
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IRegionDataStore
+ {
+ ///
+ /// Initialises the data storage engine
+ ///
+ /// The file to save the database to (may not be applicable). Alternatively,
+ /// a connection string for the database
+ void Initialise(string filename);
+
+ ///
+ /// Dispose the database
+ ///
+ void Dispose();
+
+ ///
+ /// Stores all object's details apart from inventory
+ ///
+ ///
+ ///
+ void StoreObject(SceneObjectGroup obj, UUID regionUUID);
+
+ ///
+ /// Entirely removes the object, including inventory
+ ///
+ ///
+ ///
+ ///
+ void RemoveObject(UUID uuid, UUID regionUUID);
+
+ ///
+ /// Store a prim's inventory
+ ///
+ ///
+ void StorePrimInventory(UUID primID, ICollection items);
+
+ ///
+ /// Load persisted objects from region storage.
+ ///
+ /// the Region UUID
+ /// List of loaded groups
+ List LoadObjects(UUID regionUUID);
+
+ ///
+ /// Store a terrain revision in region storage
+ ///
+ /// HeightField data
+ /// region UUID
+ void StoreTerrain(double[,] terrain, UUID regionID);
+
+ ///
+ /// Load the latest terrain revision from region storage
+ ///
+ /// the region UUID
+ /// Heightfield data
+ double[,] LoadTerrain(UUID regionID);
+
+ void StoreLandObject(ILandObject Parcel);
+
+ ///
+ ///
+ /// - delete from land where UUID=globalID
+ /// - delete from landaccesslist where LandUUID=globalID
+ ///
+ ///
+ ///
+ void RemoveLandObject(UUID globalID);
+
+ List LoadLandObjects(UUID regionUUID);
+
+ void StoreRegionSettings(RegionSettings rs);
+ RegionSettings LoadRegionSettings(UUID regionUUID);
+
+ void Shutdown();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs
new file mode 100644
index 0000000..6a45017
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using Nini.Config;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IRegionModule
+ {
+ void Initialise(Scene scene, IConfigSource source);
+ void PostInitialise();
+ void Close();
+ string Name { get; }
+ bool IsSharedModule { get; }
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
new file mode 100644
index 0000000..40e4c99
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionSerialiserModule.cs
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using System.Collections.Generic;
+using System.IO;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IRegionSerialiserModule
+ {
+ List SerialiseRegion(Scene scene, string saveDir);
+
+ ///
+ /// Load prims from the xml format
+ ///
+ ///
+ ///
+ ///
+ ///
+ void LoadPrimsFromXml(Scene scene, string fileName, bool newIDS, Vector3 loadOffset);
+
+ ///
+ /// Save prims in the xml format
+ ///
+ ///
+ ///
+ void SavePrimsToXml(Scene scene, string fileName);
+
+ ///
+ /// Load prims from the xml2 format
+ ///
+ ///
+ ///
+ void LoadPrimsFromXml2(Scene scene, string fileName);
+
+ ///
+ /// Load prims from the xml2 format
+ ///
+ ///
+ ///
+ ///
+ void LoadPrimsFromXml2(Scene scene, TextReader reader, bool startScripts);
+
+ ///
+ /// Save prims in the xml2 format
+ ///
+ ///
+ ///
+ void SavePrimsToXml2(Scene scene, string fileName);
+
+ ///
+ /// Save prims in the xml2 format, optionally specifying a bounding box for which
+ /// prims should be saved. If both min and max vectors are Vector3.Zero, then all prims
+ /// are exported.
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SavePrimsToXml2(Scene scene, TextWriter stream, Vector3 min, Vector3 max);
+
+ ///
+ /// Save a set of prims in the xml2 format
+ ///
+ ///
+ ///
+ void SavePrimListToXml2(List entityList, string fileName);
+
+ ///
+ /// Save a set of prims in the xml2 format, optionally specifying a bounding box for which
+ /// prims should be saved. If both min and max vectors are Vector3.Zero, then all prims
+ /// are exported.
+ ///
+ ///
+ ///
+ ///
+ ///
+ void SavePrimListToXml2(List entityList, TextWriter stream, Vector3 min, Vector3 max);
+
+ void SaveNamedPrimsToXml2(Scene scene, string primName, string fileName);
+
+ ///
+ /// Deserializes a scene object from its xml2 representation. This does not load the object into the scene.
+ ///
+ ///
+ /// The scene object created. null if the scene object already existed
+ SceneObjectGroup DeserializeGroupFromXml2(string xmlString);
+
+ ///
+ /// Serialize an individual scene object into the xml2 format
+ ///
+ ///
+ ///
+ string SaveGroupToXml2(SceneObjectGroup grp);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
new file mode 100644
index 0000000..65620d3
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IScriptModule
+ {
+ string ScriptEngineName { get; }
+
+ string GetAssemblyName(UUID itemID);
+ string GetXMLState(UUID itemID);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IServiceRequest.cs b/OpenSim/Region/Framework/Interfaces/IServiceRequest.cs
new file mode 100644
index 0000000..f3283c4
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IServiceRequest.cs
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IServiceRequest
+ {
+ // Status
+ bool Finished { get; }
+
+ // Request info
+ UUID ItemID { get; set; }
+ uint LocalID { get; set; }
+ UUID ReqID { get; set; }
+
+ void Process();
+ void SendRequest();
+ void Stop();
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs
new file mode 100644
index 0000000..91c80e3
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using Nini.Config;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ISoundModule
+ {
+ void PlayAttachedSound(UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags);
+
+ void TriggerSound(
+ UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle);
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrain.cs b/OpenSim/Region/Framework/Interfaces/ITerrain.cs
new file mode 100644
index 0000000..6e9c98d
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ITerrain.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ITerrain
+ {
+ bool Tainted();
+ bool Tainted(int x, int y);
+ void ResetTaint();
+
+ void ModifyTerrain(float height, float seconds, byte brushsize, byte action, float north, float west,
+ IClientAPI remoteUser);
+
+ void CheckHeightValues();
+ float[] GetHeights1D();
+ float[,] GetHeights2D();
+ double[,] GetHeights2DD();
+ void GetHeights1D(float[] heights);
+ void SetHeights2D(float[,] heights);
+ void SetHeights2D(double[,] heights);
+ void SwapRevertMaps();
+ void SaveRevertMap();
+ bool RunTerrainCmd(string[] args, ref string resultText, string simName);
+ void SetRange(float min, float max);
+ void LoadFromFileF64(string filename);
+ void LoadFromFileF32(string filename);
+ void LoadFromFileF32(string filename, int dimensionX, int dimensionY, int lowerboundX, int lowerboundY);
+ void LoadFromFileIMG(string filename, int dimensionX, int dimensionY, int lowerboundX, int lowerboundY);
+ void LoadFromFileSLRAW(string filename);
+ void WriteToFileF64(string filename);
+ void WriteToFileF32(string filename);
+ void WriteToFileRAW(string filename);
+ void WriteToFileHiRAW(string filename);
+ void SetSeed(int val);
+ void RaiseTerrain(double rx, double ry, double size, double amount);
+ void LowerTerrain(double rx, double ry, double size, double amount);
+ void FlattenTerrain(double rx, double ry, double size, double amount);
+ void NoiseTerrain(double rx, double ry, double size, double amount);
+ void RevertTerrain(double rx, double ry, double size, double amount);
+ void SmoothTerrain(double rx, double ry, double size, double amount);
+ void HillsGenerator();
+ double GetHeight(int x, int y);
+ void ExportImage(string filename, string gradientmap);
+ byte[] ExportJpegImage(string gradientmap);
+ }
+
+ public interface IMapImageGenerator
+ {
+ byte[] WriteJpeg2000Image(string gradientmap);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
new file mode 100644
index 0000000..fc4ced2
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainChannel.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface ITerrainChannel
+ {
+ int Height { get; }
+ double this[int x, int y] { get; set; }
+ int Width { get; }
+
+ ///
+ /// Squash the entire heightmap into a single dimensioned array
+ ///
+ ///
+ float[] GetFloatsSerialised();
+
+ double[,] GetDoubles();
+ bool Tainted(int x, int y);
+ ITerrainChannel MakeCopy();
+ string SaveToXmlString();
+ void LoadFromXmlString(string data);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/ITextureSender.cs b/OpenSim/Region/Framework/Interfaces/ITextureSender.cs
new file mode 100644
index 0000000..aab3d26
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ITextureSender.cs
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ ///
+ /// Interface for an object which can send texture information to a client
+ ///
+ public interface ITextureSender
+ {
+ ///
+ /// Are we in the process of sending the texture?
+ ///
+ bool Sending { get; set; }
+
+ ///
+ /// Has the texture send been cancelled?
+ ///
+ bool Cancel { get; set; }
+
+ ///
+ /// Update the non data properties of a texture request
+ ///
+ ///
+ ///
+ void UpdateRequest(int discardLevel, uint packetNumber);
+
+ ///
+ /// Send a texture packet to the client.
+ ///
+ /// True if the last packet has been sent, false otherwise.
+ bool SendTexturePacket();
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IVegetationModule.cs b/OpenSim/Region/Framework/Interfaces/IVegetationModule.cs
new file mode 100644
index 0000000..537a8dc
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IVegetationModule.cs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IVegetationModule : IEntityCreator
+ {
+ ///
+ /// Add a new tree to the scene. Used by other modules.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ SceneObjectGroup AddTree(
+ UUID uuid, UUID groupID, Vector3 scale, Quaternion rotation, Vector3 position, Tree treeType, bool newTree);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IWindModule.cs b/OpenSim/Region/Framework/Interfaces/IWindModule.cs
new file mode 100644
index 0000000..96b303f
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IWindModule.cs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IWindModule : IRegionModule
+ {
+ Vector2[] WindSpeeds
+ {
+ get;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
new file mode 100644
index 0000000..24865db
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenMetaverse;
+using OpenSim.Framework;
+// using OpenSim.Region.Environment.Modules.Scripting.WorldComm;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IWorldCommListenerInfo
+ {
+ Object[] GetSerializationData();
+ UUID GetItemID();
+ UUID GetHostID();
+ int GetChannel();
+ uint GetLocalID();
+ int GetHandle();
+ string GetMessage();
+ string GetName();
+ bool IsActive();
+ void Deactivate();
+ void Activate();
+ UUID GetID();
+ }
+
+ public interface IWorldComm
+ {
+ int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
+ void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
+ bool HasMessages();
+ IWorldCommListenerInfo GetNextMessage();
+ void ListenControl(UUID itemID, int handle, int active);
+ void ListenRemove(UUID itemID, int handle);
+ void DeleteListener(UUID itemID);
+ Object[] GetSerializationData(UUID itemID);
+ void CreateFromData(uint localID, UUID itemID, UUID hostID,
+ Object[] data);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IXMLRPC.cs b/OpenSim/Region/Framework/Interfaces/IXMLRPC.cs
new file mode 100644
index 0000000..6570b0a
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IXMLRPC.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using Nwc.XmlRpc;
+
+// using OpenSim.Region.Environment.Modules.Scripting.XMLRPC;
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IXmlRpcRequestInfo
+ {
+ bool IsProcessed();
+ UUID GetChannelKey();
+ void SetProcessed(bool processed);
+ void SetStrRetval(string resp);
+ string GetStrRetval();
+ void SetIntRetval(int resp);
+ int GetIntRetval();
+ uint GetLocalID();
+ UUID GetItemID();
+ string GetStrVal();
+ int GetIntValue();
+ UUID GetMessageID();
+ }
+
+ public interface IXMLRPC
+ {
+ UUID OpenXMLRPCChannel(uint localID, UUID itemID, UUID channelID);
+ void CloseXMLRPCChannel(UUID channelKey);
+ bool hasRequests();
+ void RemoteDataReply(string channel, string message_id, string sdata, int idata);
+ bool IsEnabled();
+ IXmlRpcRequestInfo GetNextCompletedRequest();
+ void RemoveCompletedRequest(UUID id);
+ void DeleteChannels(UUID itemID);
+ UUID SendRemoteData(uint localID, UUID itemID, string channel, string dest, int idata, string sdata);
+ IServiceRequest GetNextCompletedSRDRequest();
+ void RemoveCompletedSRDRequest(UUID id);
+ void CancelSRDRequests(UUID itemID);
+ }
+}
diff --git a/OpenSim/Region/Framework/Interfaces/IXfer.cs b/OpenSim/Region/Framework/Interfaces/IXfer.cs
new file mode 100644
index 0000000..a83f166
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IXfer.cs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace OpenSim.Region.Framework.Interfaces
+{
+ public interface IXfer
+ {
+ bool AddNewFile(string fileName, byte[] data);
+ }
+}
diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs
new file mode 100644
index 0000000..d393919
--- /dev/null
+++ b/OpenSim/Region/Framework/ModuleLoader.cs
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using log4net;
+using Nini.Config;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework
+{
+ public class ModuleLoader
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public Dictionary LoadedAssemblys = new Dictionary();
+
+ private readonly List m_loadedModules = new List();
+ private readonly Dictionary m_loadedSharedModules = new Dictionary();
+ private readonly IConfigSource m_config;
+
+ public ModuleLoader(IConfigSource config)
+ {
+ m_config = config;
+ }
+
+ public IRegionModule[] GetLoadedSharedModules
+ {
+ get
+ {
+ IRegionModule[] regionModules = new IRegionModule[m_loadedSharedModules.Count];
+ m_loadedSharedModules.Values.CopyTo(regionModules, 0);
+ return regionModules;
+ }
+ }
+
+ public List PickupModules(Scene scene, string moduleDir)
+ {
+ DirectoryInfo dir = new DirectoryInfo(moduleDir);
+ List modules = new List();
+
+ foreach (FileInfo fileInfo in dir.GetFiles("*.dll"))
+ {
+ modules.AddRange(LoadRegionModules(fileInfo.FullName, scene));
+ }
+ return modules;
+ }
+
+ public void LoadDefaultSharedModule(IRegionModule module)
+ {
+ if (m_loadedSharedModules.ContainsKey(module.Name))
+ {
+ m_log.ErrorFormat("[MODULES]: Module name \"{0}\" already exists in module list. Module not added!", module.Name);
+ }
+ else
+ {
+ m_loadedSharedModules.Add(module.Name, module);
+ }
+ }
+
+
+ public void InitialiseSharedModules(Scene scene)
+ {
+ foreach (IRegionModule module in m_loadedSharedModules.Values)
+ {
+ module.Initialise(scene, m_config);
+ scene.AddModule(module.Name, module); //should be doing this?
+ }
+ }
+
+ public void InitializeModule(IRegionModule module, Scene scene)
+ {
+ module.Initialise(scene, m_config);
+ scene.AddModule(module.Name, module);
+ m_loadedModules.Add(module);
+ }
+
+ ///
+ /// Loads/initialises a Module instance that can be used by multiple Regions
+ ///
+ ///
+ ///
+ public void LoadSharedModule(string dllName, string moduleName)
+ {
+ IRegionModule module = LoadModule(dllName, moduleName);
+
+ if (module != null)
+ LoadSharedModule(module);
+ }
+
+ ///
+ /// Loads/initialises a Module instance that can be used by multiple Regions
+ ///
+ ///
+ public void LoadSharedModule(IRegionModule module)
+ {
+ if (!m_loadedSharedModules.ContainsKey(module.Name))
+ {
+ m_loadedSharedModules.Add(module.Name, module);
+ }
+ }
+
+ public List LoadRegionModules(string dllName, Scene scene)
+ {
+ IRegionModule[] modules = LoadModules(dllName);
+ List initializedModules = new List();
+
+ if (modules.Length > 0)
+ {
+ m_log.InfoFormat("[MODULES]: Found Module Library [{0}]", dllName);
+ foreach (IRegionModule module in modules)
+ {
+ if (!module.IsSharedModule)
+ {
+ m_log.InfoFormat("[MODULES]: [{0}]: Initializing.", module.Name);
+ InitializeModule(module, scene);
+ initializedModules.Add(module);
+ }
+ else
+ {
+ m_log.InfoFormat("[MODULES]: [{0}]: Loading Shared Module.", module.Name);
+ LoadSharedModule(module);
+ }
+ }
+ }
+ return initializedModules;
+ }
+
+ public void LoadRegionModule(string dllName, string moduleName, Scene scene)
+ {
+ IRegionModule module = LoadModule(dllName, moduleName);
+ if (module != null)
+ {
+ InitializeModule(module, scene);
+ }
+ }
+
+ ///
+ /// Loads a external Module (if not already loaded) and creates a new instance of it.
+ ///
+ ///
+ ///
+ public IRegionModule LoadModule(string dllName, string moduleName)
+ {
+ IRegionModule[] modules = LoadModules(dllName);
+
+ foreach (IRegionModule module in modules)
+ {
+ if ((module != null) && (module.Name == moduleName))
+ {
+ return module;
+ }
+ }
+
+ return null;
+ }
+
+ public IRegionModule[] LoadModules(string dllName)
+ {
+ List modules = new List();
+
+ Assembly pluginAssembly;
+ if (!LoadedAssemblys.TryGetValue(dllName, out pluginAssembly))
+ {
+ try
+ {
+ pluginAssembly = Assembly.LoadFrom(dllName);
+ LoadedAssemblys.Add(dllName, pluginAssembly);
+ }
+ catch (BadImageFormatException)
+ {
+ //m_log.InfoFormat("[MODULES]: The file [{0}] is not a module assembly.", e.FileName);
+ }
+ }
+
+ if (pluginAssembly != null)
+ {
+ try
+ {
+ foreach (Type pluginType in pluginAssembly.GetTypes())
+ {
+ if (pluginType.IsPublic)
+ {
+ if (!pluginType.IsAbstract)
+ {
+ if (pluginType.GetInterface("IRegionModule") != null)
+ {
+ modules.Add((IRegionModule)Activator.CreateInstance(pluginType));
+ }
+ }
+ }
+ }
+ }
+ catch (ReflectionTypeLoadException)
+ {
+ m_log.InfoFormat("[MODULES]: Could not load types for [{0}].", pluginAssembly.FullName);
+ }
+ }
+
+ return modules.ToArray();
+ }
+
+ public void PostInitialise()
+ {
+ foreach (IRegionModule module in m_loadedSharedModules.Values)
+ {
+ module.PostInitialise();
+ }
+
+ foreach (IRegionModule module in m_loadedModules)
+ {
+ module.PostInitialise();
+ }
+ }
+
+ public void ClearCache()
+ {
+ LoadedAssemblys.Clear();
+ }
+
+ public void UnloadModule(IRegionModule rm)
+ {
+ rm.Close();
+
+ m_loadedModules.Remove(rm);
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Animation.cs b/OpenSim/Region/Framework/Scenes/Animation.cs
new file mode 100644
index 0000000..3504717
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation.cs
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public class Animation
+ {
+ private UUID animID;
+ public UUID AnimID
+ {
+ get { return animID; }
+ set { animID = value; }
+ }
+
+ private int sequenceNum;
+ public int SequenceNum
+ {
+ get { return sequenceNum; }
+ set { sequenceNum = value; }
+ }
+
+ public Animation()
+ {
+ }
+
+ public Animation(UUID animID, int sequenceNum)
+ {
+ this.animID = animID;
+ this.sequenceNum = sequenceNum;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
new file mode 100644
index 0000000..f53bb78
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/AnimationSet.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public class AnimationSet
+ {
+ public static AvatarAnimations Animations = new AvatarAnimations();
+
+ private Animation m_defaultAnimation = new Animation();
+ private List m_animations = new List();
+
+ public Animation DefaultAnimation
+ {
+ get { return m_defaultAnimation; }
+ }
+ public AnimationSet()
+ {
+ ResetDefaultAnimation();
+ }
+
+ public bool HasAnimation(UUID animID)
+ {
+ if (m_defaultAnimation.AnimID == animID)
+ return true;
+
+ for (int i = 0; i < m_animations.Count; ++i)
+ {
+ if (m_animations[i].AnimID == animID)
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool Add(UUID animID, int sequenceNum)
+ {
+ lock (m_animations)
+ {
+ if (!HasAnimation(animID))
+ {
+ m_animations.Add(new Animation(animID, sequenceNum));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public bool Remove(UUID animID)
+ {
+ lock (m_animations)
+ {
+ if (m_defaultAnimation.AnimID == animID)
+ {
+ ResetDefaultAnimation();
+ }
+ else if (HasAnimation(animID))
+ {
+ for (int i = 0; i < m_animations.Count; i++)
+ {
+ if (m_animations[i].AnimID == animID)
+ {
+ m_animations.RemoveAt(i);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public void Clear()
+ {
+ ResetDefaultAnimation();
+ m_animations.Clear();
+ }
+
+ ///
+ /// The default animation is reserved for "main" animations
+ /// that are mutually exclusive, e.g. flying and sitting.
+ ///
+ public bool SetDefaultAnimation(UUID animID, int sequenceNum)
+ {
+ if (m_defaultAnimation.AnimID != animID)
+ {
+ m_defaultAnimation = new Animation(animID, sequenceNum);
+ return true;
+ }
+ return false;
+ }
+
+ protected bool ResetDefaultAnimation()
+ {
+ return TrySetDefaultAnimation("STAND", 1);
+ }
+
+ ///
+ /// Set the animation as the default animation if it's known
+ ///
+ public bool TrySetDefaultAnimation(string anim, int sequenceNum)
+ {
+ if (Animations.AnimsUUID.ContainsKey(anim))
+ {
+ return SetDefaultAnimation(Animations.AnimsUUID[anim], sequenceNum);
+ }
+ return false;
+ }
+
+ public void GetArrays(out UUID[] animIDs, out int[] sequenceNums)
+ {
+ lock (m_animations)
+ {
+ animIDs = new UUID[m_animations.Count + 1];
+ sequenceNums = new int[m_animations.Count + 1];
+
+ animIDs[0] = m_defaultAnimation.AnimID;
+ sequenceNums[0] = m_defaultAnimation.SequenceNum;
+
+ for (int i = 0; i < m_animations.Count; ++i)
+ {
+ animIDs[i + 1] = m_animations[i].AnimID;
+ sequenceNums[i + 1] = m_animations[i].SequenceNum;
+ }
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
new file mode 100644
index 0000000..178f1f7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Timers;
+using log4net;
+using OpenMetaverse;
+using OpenMetaverse.Packets;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ class DeleteToInventoryHolder
+ {
+ public DeRezAction action;
+ public IClientAPI remoteClient;
+ public SceneObjectGroup objectGroup;
+ public UUID folderID;
+ public bool permissionToDelete;
+ }
+
+ ///
+ /// Asynchronously derez objects. This is used to derez large number of objects to inventory without holding
+ /// up the main client thread.
+ ///
+ public class AsyncSceneObjectGroupDeleter
+ {
+ private static readonly ILog m_log
+ = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Is the deleter currently enabled?
+ ///
+ public bool Enabled;
+
+ private Timer m_inventoryTicker = new Timer(2000);
+ private readonly Queue m_inventoryDeletes = new Queue();
+ private Scene m_scene;
+
+ public AsyncSceneObjectGroupDeleter(Scene scene)
+ {
+ m_scene = scene;
+
+ m_inventoryTicker.AutoReset = false;
+ m_inventoryTicker.Elapsed += InventoryRunDeleteTimer;
+ }
+
+ ///
+ /// Delete the given object from the scene
+ ///
+ public void DeleteToInventory(DeRezAction action, UUID folderID,
+ SceneObjectGroup objectGroup, IClientAPI remoteClient,
+ bool permissionToDelete)
+ {
+ if (Enabled)
+ m_inventoryTicker.Stop();
+
+ lock (m_inventoryDeletes)
+ {
+ DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
+ dtis.action = action;
+ dtis.folderID = folderID;
+ dtis.objectGroup = objectGroup;
+ dtis.remoteClient = remoteClient;
+ dtis.permissionToDelete = permissionToDelete;
+
+ m_inventoryDeletes.Enqueue(dtis);
+ }
+
+ if (Enabled)
+ m_inventoryTicker.Start();
+
+ // Visually remove it, even if it isnt really gone yet. This means that if we crash before the object
+ // has gone to inventory, it will reappear in the region again on restart instead of being lost.
+ // This is not ideal since the object will still be available for manipulation when it should be, but it's
+ // better than losing the object for now.
+ if (permissionToDelete)
+ objectGroup.DeleteGroup(false);
+ }
+
+ private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
+ {
+ m_log.Debug("[SCENE]: Starting send to inventory loop");
+
+ while (InventoryDeQueueAndDelete())
+ {
+ m_log.Debug("[SCENE]: Sent item successfully to inventory, continuing...");
+ }
+ }
+
+ ///
+ /// Move the next object in the queue to inventory. Then delete it properly from the scene.
+ ///
+ ///
+ public bool InventoryDeQueueAndDelete()
+ {
+ DeleteToInventoryHolder x = null;
+
+ try
+ {
+ lock (m_inventoryDeletes)
+ {
+ int left = m_inventoryDeletes.Count;
+ if (left > 0)
+ {
+ m_log.DebugFormat(
+ "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left);
+
+ x = m_inventoryDeletes.Dequeue();
+
+ try
+ {
+ m_scene.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient);
+ if (x.permissionToDelete)
+ m_scene.DeleteSceneObject(x.objectGroup, false);
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("Exception background sending object: " + e);
+ }
+
+ return true;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // We can't put the object group details in here since the root part may have disappeared (which is where these sit).
+ // FIXME: This needs to be fixed.
+ m_log.ErrorFormat(
+ "[SCENE]: Queued sending of scene object to agent {0} {1} failed: {2}",
+ (x != null ? x.remoteClient.Name : "unavailable"), (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), e.ToString());
+ }
+
+ m_log.Debug("[SCENE]: No objects left in inventory send queue.");
+ return false;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/AvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/AvatarAnimations.cs
new file mode 100644
index 0000000..562fcf9
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/AvatarAnimations.cs
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using System.Xml;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public class AvatarAnimations
+ {
+ public Dictionary AnimsUUID = new Dictionary();
+ public Dictionary AnimsNames = new Dictionary();
+ public Dictionary AnimStateNames = new Dictionary();
+
+ public AvatarAnimations()
+ {
+ using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load(reader);
+ foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
+ {
+ if (nod.Attributes["name"] != null)
+ {
+ string name = (string)nod.Attributes["name"].Value;
+ UUID id = (UUID)nod.InnerText;
+ string animState = (string)nod.Attributes["state"].Value;
+
+ AnimsUUID.Add(name, id);
+ AnimsNames.Add(id, name);
+ if (animState != "")
+ AnimStateNames.Add(id, animState);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
new file mode 100644
index 0000000..5055e44
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ [Serializable]
+ public abstract class EntityBase : ISerializable
+ {
+ ///
+ /// The scene to which this entity belongs
+ ///
+ public Scene Scene
+ {
+ get { return m_scene; }
+ }
+ protected Scene m_scene;
+
+ protected UUID m_uuid;
+
+ public virtual UUID UUID
+ {
+ get { return m_uuid; }
+ set { m_uuid = value; }
+ }
+
+ protected string m_name;
+
+ ///
+ /// The name of this entity
+ ///
+ public virtual string Name
+ {
+ get { return m_name; }
+ set { m_name = value; }
+ }
+
+ ///
+ /// Signals whether this entity was in a scene but has since been removed from it.
+ ///
+ public bool IsDeleted
+ {
+ get { return m_isDeleted; }
+ }
+ protected bool m_isDeleted;
+
+ protected Vector3 m_pos;
+
+ ///
+ ///
+ ///
+ public virtual Vector3 AbsolutePosition
+ {
+ get { return m_pos; }
+ set { m_pos = value; }
+ }
+
+ protected Vector3 m_velocity;
+ protected Vector3 m_rotationalvelocity;
+
+ ///
+ /// Current velocity of the entity.
+ ///
+ public virtual Vector3 Velocity
+ {
+ get { return m_velocity; }
+ set { m_velocity = value; }
+ }
+
+ protected Quaternion m_rotation = new Quaternion(0f, 0f, 1f, 0f);
+
+ public virtual Quaternion Rotation
+ {
+ get { return m_rotation; }
+ set { m_rotation = value; }
+ }
+
+ protected uint m_localId;
+
+ public virtual uint LocalId
+ {
+ get { return m_localId; }
+ set { m_localId = value; }
+ }
+
+ ///
+ /// Creates a new Entity (should not occur on it's own)
+ ///
+ public EntityBase()
+ {
+ m_uuid = UUID.Zero;
+
+ m_pos = Vector3.Zero;
+ m_velocity = Vector3.Zero;
+ Rotation = Quaternion.Identity;
+ m_name = "(basic entity)";
+ m_rotationalvelocity = Vector3.Zero;
+ }
+
+ ///
+ ///
+ ///
+ public abstract void UpdateMovement();
+
+ ///
+ /// Performs any updates that need to be done at each frame, as opposed to immediately.
+ /// These included scheduled updates and updates that occur due to physics processing.
+ ///
+ public abstract void Update();
+
+ ///
+ /// Copies the entity
+ ///
+ ///
+ public virtual EntityBase Copy()
+ {
+ return (EntityBase) MemberwiseClone();
+ }
+
+
+ public abstract void SetText(string text, Vector3 color, double alpha);
+
+ protected EntityBase(SerializationInfo info, StreamingContext context)
+ {
+ //System.Console.WriteLine("EntityBase Deserialize BGN");
+
+ if (info == null)
+ {
+ throw new ArgumentNullException("info");
+ }
+
+ m_uuid = new UUID((Guid)info.GetValue("m_uuid", typeof(Guid)));
+ m_name = (string)info.GetValue("m_name", typeof(string));
+
+ m_pos
+ = new Vector3(
+ (float)info.GetValue("m_pos.X", typeof(float)),
+ (float)info.GetValue("m_pos.Y", typeof(float)),
+ (float)info.GetValue("m_pos.Z", typeof(float)));
+
+ m_velocity
+ = new Vector3(
+ (float)info.GetValue("m_velocity.X", typeof(float)),
+ (float)info.GetValue("m_velocity.Y", typeof(float)),
+ (float)info.GetValue("m_velocity.Z", typeof(float)));
+
+ m_rotationalvelocity
+ = new Vector3(
+ (float)info.GetValue("m_rotationalvelocity.X", typeof(float)),
+ (float)info.GetValue("m_rotationalvelocity.Y", typeof(float)),
+ (float)info.GetValue("m_rotationalvelocity.Z", typeof(float)));
+
+ m_rotation
+ = new Quaternion(
+ (float)info.GetValue("m_rotation.X", typeof(float)),
+ (float)info.GetValue("m_rotation.Y", typeof(float)),
+ (float)info.GetValue("m_rotation.Z", typeof(float)),
+ (float)info.GetValue("m_rotation.W", typeof(float)));
+
+ m_localId = (uint)info.GetValue("m_localId", typeof(uint));
+
+ //System.Console.WriteLine("EntityBase Deserialize END");
+ }
+
+ [SecurityPermission(SecurityAction.LinkDemand,
+ Flags = SecurityPermissionFlag.SerializationFormatter)]
+ public virtual void GetObjectData(
+ SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException("info");
+ }
+
+ info.AddValue("m_uuid", m_uuid.Guid);
+ info.AddValue("m_name", m_name);
+
+ // Vector3
+ info.AddValue("m_pos.X", m_pos.X);
+ info.AddValue("m_pos.Y", m_pos.Y);
+ info.AddValue("m_pos.Z", m_pos.Z);
+
+ // Vector3
+ info.AddValue("m_velocity.X", m_velocity.X);
+ info.AddValue("m_velocity.Y", m_velocity.Y);
+ info.AddValue("m_velocity.Z", m_velocity.Z);
+
+ // Vector3
+ info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X);
+ info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y);
+ info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z);
+
+ // Quaternion
+ info.AddValue("m_rotation.X", m_rotation.X);
+ info.AddValue("m_rotation.Y", m_rotation.Y);
+ info.AddValue("m_rotation.Z", m_rotation.Z);
+ info.AddValue("m_rotation.W", m_rotation.W);
+
+ info.AddValue("m_localId", m_localId);
+ }
+ }
+
+ //Nested Classes
+ public class EntityIntersection
+ {
+ public Vector3 ipoint = new Vector3(0, 0, 0);
+ public Vector3 normal = new Vector3(0, 0, 0);
+ public Vector3 AAfaceNormal = new Vector3(0, 0, 0);
+ public int face = -1;
+ public bool HitTF = false;
+ public SceneObjectPart obj;
+ public float distance = 0;
+
+ public EntityIntersection()
+ {
+ }
+
+ public EntityIntersection(Vector3 _ipoint, Vector3 _normal, bool _HitTF)
+ {
+ ipoint = _ipoint;
+ normal = _normal;
+ HitTF = _HitTF;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
new file mode 100644
index 0000000..a322766
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using log4net;
+using OpenMetaverse;
+
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public class EntityManager : IEnumerable
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private readonly Dictionary m_eb_uuid = new Dictionary();
+ private readonly Dictionary m_eb_localID = new Dictionary();
+ //private readonly Dictionary m_pres_uuid = new Dictionary();
+ private readonly Object m_lock = new Object();
+
+ [Obsolete("Use Add() instead.")]
+ public void Add(UUID id, EntityBase eb)
+ {
+ Add(eb);
+ }
+
+ public void Add(EntityBase entity)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ m_eb_uuid.Add(entity.UUID, entity);
+ m_eb_localID.Add(entity.LocalId, entity);
+ }
+ catch(Exception e)
+ {
+ m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
+ }
+ }
+ }
+
+ public void InsertOrReplace(EntityBase entity)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ m_eb_uuid[entity.UUID] = entity;
+ m_eb_localID[entity.LocalId] = entity;
+ }
+ catch(Exception e)
+ {
+ m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
+ }
+ }
+ }
+
+ public void Clear()
+ {
+ lock (m_lock)
+ {
+ m_eb_uuid.Clear();
+ m_eb_localID.Clear();
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ lock (m_lock)
+ {
+ return m_eb_uuid.Count;
+ }
+ }
+ }
+
+ public bool ContainsKey(UUID id)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ return m_eb_uuid.ContainsKey(id);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public bool ContainsKey(uint localID)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ return m_eb_localID.ContainsKey(localID);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ }
+
+ public bool Remove(uint localID)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID);
+ bool b = m_eb_localID.Remove(localID);
+ return a && b;
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("Remove Entity failed for {0}", localID, e);
+ return false;
+ }
+ }
+ }
+
+ public bool Remove(UUID id)
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId);
+ bool b = m_eb_uuid.Remove(id);
+ return a && b;
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("Remove Entity failed for {0}", id, e);
+ return false;
+ }
+ }
+ }
+
+ public List GetAllByType()
+ {
+ List tmp = new List();
+
+ lock (m_lock)
+ {
+ try
+ {
+ foreach (KeyValuePair pair in m_eb_uuid)
+ {
+ if (pair.Value is T)
+ {
+ tmp.Add(pair.Value);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("GetAllByType failed for {0}", e);
+ tmp = null;
+ }
+ }
+
+ return tmp;
+ }
+
+ public List GetEntities()
+ {
+ lock (m_lock)
+ {
+ return new List(m_eb_uuid.Values);
+ }
+ }
+
+ public EntityBase this[UUID id]
+ {
+ get
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ return m_eb_uuid[id];
+ }
+ catch
+ {
+ return null;
+ }
+ }
+ }
+ set
+ {
+ InsertOrReplace(value);
+ }
+ }
+
+ public EntityBase this[uint localID]
+ {
+ get
+ {
+ lock (m_lock)
+ {
+ try
+ {
+ return m_eb_localID[localID];
+ }
+ catch
+ {
+ return null;
+ }
+ }
+ }
+ set
+ {
+ InsertOrReplace(value);
+ }
+ }
+
+ public bool TryGetValue(UUID key, out EntityBase obj)
+ {
+ lock (m_lock)
+ {
+ return m_eb_uuid.TryGetValue(key, out obj);
+ }
+ }
+
+ public bool TryGetValue(uint key, out EntityBase obj)
+ {
+ lock (m_lock)
+ {
+ return m_eb_localID.TryGetValue(key, out obj);
+ }
+ }
+
+ ///
+ /// This could be optimised to work on the list 'live' rather than making a safe copy and iterating that.
+ ///
+ ///
+ public IEnumerator GetEnumerator()
+ {
+ return GetEntities().GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
new file mode 100644
index 0000000..23e1278
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Framework.Client;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
+using System.Collections.Generic;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ ///
+ /// A class for triggering remote scene events.
+ ///
+ public class EventManager
+ {
+ public delegate void OnFrameDelegate();
+
+ public event OnFrameDelegate OnFrame;
+
+ public delegate void ClientMovement(ScenePresence client);
+
+ public event ClientMovement OnClientMovement;
+
+ public delegate void OnTerrainTickDelegate();
+
+ public event OnTerrainTickDelegate OnTerrainTick;
+
+ public delegate void OnBackupDelegate(IRegionDataStore datastore, bool forceBackup);
+
+ public event OnBackupDelegate OnBackup;
+
+ public delegate void OnClientConnectCoreDelegate(IClientCore client);
+
+ public event OnClientConnectCoreDelegate OnClientConnect;
+
+ public delegate void OnNewClientDelegate(IClientAPI client);
+
+ ///
+ /// Depreciated in favour of OnClientConnect.
+ /// Will be marked Obsolete after IClientCore has 100% of IClientAPI interfaces.
+ ///
+ public event OnNewClientDelegate OnNewClient;
+
+ public delegate void OnNewPresenceDelegate(ScenePresence presence);
+
+ public event OnNewPresenceDelegate OnNewPresence;
+
+ public delegate void OnRemovePresenceDelegate(UUID agentId);
+
+ public event OnRemovePresenceDelegate OnRemovePresence;
+
+ public delegate void OnParcelPrimCountUpdateDelegate();
+
+ public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate;
+
+ public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj);
+
+ public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd;
+
+ public delegate void OnPluginConsoleDelegate(string[] args);
+
+ public event OnPluginConsoleDelegate OnPluginConsole;
+
+ public delegate void OnShutdownDelegate();
+
+ public event OnShutdownDelegate OnShutdown;
+
+ public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
+ public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient);
+ public delegate void ScriptResetDelegate(uint localID, UUID itemID);
+
+ public delegate void OnPermissionErrorDelegate(UUID user, string reason);
+
+ public delegate void OnSetRootAgentSceneDelegate(UUID agentID, Scene scene);
+
+ public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
+
+ public event ObjectGrabDelegate OnObjectGrab;
+ public event ObjectDeGrabDelegate OnObjectDeGrab;
+ public event ScriptResetDelegate OnScriptReset;
+
+ public event OnPermissionErrorDelegate OnPermissionError;
+
+ public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
+
+ public event NewRezScript OnRezScript;
+
+ public delegate void RemoveScript(uint localID, UUID itemID);
+
+ public event RemoveScript OnRemoveScript;
+
+ public delegate void StartScript(uint localID, UUID itemID);
+
+ public event StartScript OnStartScript;
+
+ public delegate void StopScript(uint localID, UUID itemID);
+
+ public event StopScript OnStopScript;
+
+ public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta);
+
+ public event SceneGroupMoved OnSceneGroupMove;
+
+ public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID);
+
+ public event SceneGroupGrabed OnSceneGroupGrab;
+
+ public delegate void LandObjectAdded(ILandObject newParcel);
+
+ public event LandObjectAdded OnLandObjectAdded;
+
+ public delegate void LandObjectRemoved(UUID globalID);
+
+ public event LandObjectRemoved OnLandObjectRemoved;
+
+ public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
+
+ public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
+
+ public delegate void SignificantClientMovement(IClientAPI remote_client);
+
+ public event SignificantClientMovement OnSignificantClientMovement;
+
+ public delegate void IncomingInstantMessage(GridInstantMessage message);
+
+ public event IncomingInstantMessage OnIncomingInstantMessage;
+
+ public event IncomingInstantMessage OnUnhandledInstantMessage;
+
+ public delegate void ClientClosed(UUID clientID);
+
+ public event ClientClosed OnClientClosed;
+
+ public delegate void ScriptChangedEvent(uint localID, uint change);
+
+ public event ScriptChangedEvent OnScriptChangedEvent;
+
+ public delegate void ScriptControlEvent(uint localID, UUID item, UUID avatarID, uint held, uint changed);
+
+ public event ScriptControlEvent OnScriptControlEvent;
+
+ public delegate void ScriptAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 atpos);
+
+ public event ScriptAtTargetEvent OnScriptAtTargetEvent;
+
+ public delegate void ScriptNotAtTargetEvent(uint localID);
+
+ public event ScriptNotAtTargetEvent OnScriptNotAtTargetEvent;
+
+ public delegate void ScriptColliding(uint localID, ColliderArgs colliders);
+
+ public event ScriptColliding OnScriptColliderStart;
+ public event ScriptColliding OnScriptColliding;
+ public event ScriptColliding OnScriptCollidingEnd;
+
+ public delegate void OnMakeChildAgentDelegate(ScenePresence presence);
+ public event OnMakeChildAgentDelegate OnMakeChildAgent;
+
+ public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
+ public event OnMakeRootAgentDelegate OnMakeRootAgent;
+
+ public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
+
+ public event NewInventoryItemUploadComplete OnNewInventoryItemUploadComplete;
+
+ public delegate void RequestChangeWaterHeight(float height);
+
+ public event RequestChangeWaterHeight OnRequestChangeWaterHeight;
+
+ public delegate void AvatarKillData(uint KillerLocalID, ScenePresence avatar);
+
+ public event AvatarKillData OnAvatarKilled;
+
+ public delegate void ScriptTimerEvent(uint localID, double timerinterval);
+
+ public event ScriptTimerEvent OnScriptTimerEvent;
+
+ public delegate void EstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool EstateSun, float LindenHour);
+ public delegate void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID);
+
+ public event EstateToolsTimeUpdate OnEstateToolsTimeUpdate;
+
+ public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
+ public event ObjectBeingRemovedFromScene OnObjectBeingRemovedFromScene;
+
+ public delegate void NoticeNoLandDataFromStorage();
+ public event NoticeNoLandDataFromStorage OnNoticeNoLandDataFromStorage;
+
+ public delegate void IncomingLandDataFromStorage(List data);
+ public event IncomingLandDataFromStorage OnIncomingLandDataFromStorage;
+
+ public delegate void SetAllowForcefulBan(bool allow);
+ public event SetAllowForcefulBan OnSetAllowForcefulBan;
+
+ public delegate void RequestParcelPrimCountUpdate();
+ public event RequestParcelPrimCountUpdate OnRequestParcelPrimCountUpdate;
+
+ public delegate void ParcelPrimCountTainted();
+ public event ParcelPrimCountTainted OnParcelPrimCountTainted;
+ public event GetScriptRunning OnGetScriptRunning;
+
+ ///
+ /// RegisterCapsEvent is called by Scene after the Caps object
+ /// has been instantiated and before it is return to the
+ /// client and provides region modules to add their caps.
+ ///
+ public delegate void RegisterCapsEvent(UUID agentID, Caps caps);
+ public event RegisterCapsEvent OnRegisterCaps;
+
+ ///
+ /// DeregisterCapsEvent is called by Scene when the caps
+ /// handler for an agent are removed.
+ ///
+ public delegate void DeregisterCapsEvent(UUID agentID, Caps caps);
+ public event DeregisterCapsEvent OnDeregisterCaps;
+
+ ///
+ /// ChatFromWorldEvent is called via Scene when a chat message
+ /// from world comes in.
+ ///
+ public delegate void ChatFromWorldEvent(Object sender, OSChatMessage chat);
+ public event ChatFromWorldEvent OnChatFromWorld;
+
+ ///
+ /// ChatFromClientEvent is triggered via ChatModule (or
+ /// substitutes thereof) when a chat message
+ /// from the client comes in.
+ ///
+ public delegate void ChatFromClientEvent(Object sender, OSChatMessage chat);
+ public event ChatFromClientEvent OnChatFromClient;
+
+ ///
+ /// ChatBroadcastEvent is called via Scene when a broadcast chat message
+ /// from world comes in
+ ///
+ public delegate void ChatBroadcastEvent(Object sender, OSChatMessage chat);
+ public event ChatBroadcastEvent OnChatBroadcast;
+
+ public delegate float SunLindenHour();
+ public event SunLindenHour OnGetSunLindenHour;
+
+ ///
+ /// Called when oar file has finished loading, although
+ /// the scripts may not have started yet
+ /// Message is non empty string if there were problems loading the oar file
+ ///
+ public delegate void OarFileLoaded(string message);
+ public event OarFileLoaded OnOarFileLoaded;
+
+ ///
+ /// Called when an oar file has finished saving
+ /// Message is non empty string if there were problems saving the oar file
+ ///
+ public delegate void OarFileSaved(string message);
+ public event OarFileSaved OnOarFileSaved;
+
+ ///
+ /// Called when the script compile queue becomes empty
+ /// Returns the number of scripts which failed to start
+ ///
+ public delegate void EmptyScriptCompileQueue(int numScriptsFailed, string message);
+ public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue;
+
+ public class MoneyTransferArgs : EventArgs
+ {
+ public UUID sender;
+ public UUID receiver;
+
+ // Always false. The SL protocol sucks.
+ public bool authenticated = false;
+
+ public int amount;
+ public int transactiontype;
+ public string description;
+
+ public MoneyTransferArgs(UUID asender, UUID areceiver, int aamount, int atransactiontype, string adescription)
+ {
+ sender = asender;
+ receiver = areceiver;
+ amount = aamount;
+ transactiontype = atransactiontype;
+ description = adescription;
+ }
+ }
+
+ public class LandBuyArgs : EventArgs
+ {
+ public UUID agentId = UUID.Zero;
+
+ public UUID groupId = UUID.Zero;
+
+ public UUID parcelOwnerID = UUID.Zero;
+
+ public bool final = false;
+ public bool groupOwned = false;
+ public bool removeContribution = false;
+ public int parcelLocalID = 0;
+ public int parcelArea = 0;
+ public int parcelPrice = 0;
+ public bool authenticated = false;
+ public bool landValidated = false;
+ public bool economyValidated = false;
+ public int transactionID = 0;
+ public int amountDebited = 0;
+
+ public LandBuyArgs(UUID pagentId, UUID pgroupId, bool pfinal, bool pgroupOwned,
+ bool premoveContribution, int pparcelLocalID, int pparcelArea, int pparcelPrice,
+ bool pauthenticated)
+ {
+ agentId = pagentId;
+ groupId = pgroupId;
+ final = pfinal;
+ groupOwned = pgroupOwned;
+ removeContribution = premoveContribution;
+ parcelLocalID = pparcelLocalID;
+ parcelArea = pparcelArea;
+ parcelPrice = pparcelPrice;
+ authenticated = pauthenticated;
+ }
+ }
+
+ public delegate void MoneyTransferEvent(Object sender, MoneyTransferArgs e);
+
+ public delegate void LandBuy(Object sender, LandBuyArgs e);
+
+ public event MoneyTransferEvent OnMoneyTransfer;
+ public event LandBuy OnLandBuy;
+ public event LandBuy OnValidateLandBuy;
+
+ /* Designated Event Deletage Instances */
+
+ private ScriptChangedEvent handlerScriptChangedEvent = null; //OnScriptChangedEvent;
+ private ScriptAtTargetEvent handlerScriptAtTargetEvent = null;
+ private ScriptNotAtTargetEvent handlerScriptNotAtTargetEvent = null;
+ private ClientMovement handlerClientMovement = null; //OnClientMovement;
+ private OnPermissionErrorDelegate handlerPermissionError = null; //OnPermissionError;
+ private OnPluginConsoleDelegate handlerPluginConsole = null; //OnPluginConsole;
+ private OnFrameDelegate handlerFrame = null; //OnFrame;
+ private OnNewClientDelegate handlerNewClient = null; //OnNewClient;
+ private OnClientConnectCoreDelegate handlerClientConnect = null; //OnClientConnect
+ private OnNewPresenceDelegate handlerNewPresence = null; //OnNewPresence;
+ private OnRemovePresenceDelegate handlerRemovePresence = null; //OnRemovePresence;
+ private OnBackupDelegate handlerBackup = null; //OnBackup;
+ private OnParcelPrimCountUpdateDelegate handlerParcelPrimCountUpdate = null; //OnParcelPrimCountUpdate;
+ private MoneyTransferEvent handlerMoneyTransfer = null; //OnMoneyTransfer;
+ private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd;
+ private OnShutdownDelegate handlerShutdown = null; //OnShutdown;
+ private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab;
+ private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab;
+ private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset
+ private NewRezScript handlerRezScript = null; //OnRezScript;
+ private RemoveScript handlerRemoveScript = null; //OnRemoveScript;
+ private StartScript handlerStartScript = null; //OnStartScript;
+ private StopScript handlerStopScript = null; //OnStopScript;
+ private SceneGroupMoved handlerSceneGroupMove = null; //OnSceneGroupMove;
+ private SceneGroupGrabed handlerSceneGroupGrab = null; //OnSceneGroupGrab;
+ private LandObjectAdded handlerLandObjectAdded = null; //OnLandObjectAdded;
+ private LandObjectRemoved handlerLandObjectRemoved = null; //OnLandObjectRemoved;
+ private AvatarEnteringNewParcel handlerAvatarEnteringNewParcel = null; //OnAvatarEnteringNewParcel;
+ private IncomingInstantMessage handlerIncomingInstantMessage = null; //OnIncomingInstantMessage;
+ private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
+ private ClientClosed handlerClientClosed = null; //OnClientClosed;
+ private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
+ private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
+ private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
+ private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
+ private DeregisterCapsEvent handlerDeregisterCaps = null; // OnDeregisterCaps;
+ private ChatFromWorldEvent handlerChatFromWorld = null; // OnChatFromWorld;
+ private ChatFromClientEvent handlerChatFromClient = null; // OnChatFromClient;
+ private ChatBroadcastEvent handlerChatBroadcast = null; // OnChatBroadcast;
+ private NewInventoryItemUploadComplete handlerNewInventoryItemUpdateComplete = null;
+ private RequestChangeWaterHeight handlerRequestChangeWaterHeight = null; //OnRequestChangeWaterHeight
+ private ScriptControlEvent handlerScriptControlEvent = null;
+ private SignificantClientMovement handlerSignificantClientMovement = null;
+
+ private LandBuy handlerLandBuy = null;
+ private LandBuy handlerValidateLandBuy = null;
+ private AvatarKillData handlerAvatarKill = null;
+
+ private NoticeNoLandDataFromStorage handlerNoticeNoLandDataFromStorage = null;
+ private IncomingLandDataFromStorage handlerIncomingLandDataFromStorage = null;
+ private SetAllowForcefulBan handlerSetAllowForcefulBan = null;
+ private RequestParcelPrimCountUpdate handlerRequestParcelPrimCountUpdate = null;
+ private ParcelPrimCountTainted handlerParcelPrimCountTainted = null;
+ private ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = null;
+ private ScriptTimerEvent handlerScriptTimerEvent = null;
+ private EstateToolsTimeUpdate handlerEstateToolsTimeUpdate = null;
+
+ private ScriptColliding handlerCollidingStart = null;
+ private ScriptColliding handlerColliding = null;
+ private ScriptColliding handlerCollidingEnd = null;
+ private GetScriptRunning handlerGetScriptRunning = null;
+
+ private SunLindenHour handlerSunGetLindenHour = null;
+ private OnSetRootAgentSceneDelegate handlerSetRootAgentScene = null;
+
+ private OarFileLoaded handlerOarFileLoaded = null;
+ private OarFileSaved handlerOarFileSaved = null;
+
+ private EmptyScriptCompileQueue handlerEmptyScriptCompileQueue = null;
+
+ public void TriggerGetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
+ {
+ handlerGetScriptRunning = OnGetScriptRunning;
+ if (handlerGetScriptRunning != null)
+ handlerGetScriptRunning(controllingClient, objectID, itemID);
+ }
+
+ public void TriggerOnScriptChangedEvent(uint localID, uint change)
+ {
+ handlerScriptChangedEvent = OnScriptChangedEvent;
+ if (handlerScriptChangedEvent != null)
+ handlerScriptChangedEvent(localID, change);
+ }
+
+ public void TriggerOnClientMovement(ScenePresence avatar)
+ {
+ handlerClientMovement = OnClientMovement;
+ if (handlerClientMovement != null)
+ handlerClientMovement(avatar);
+ }
+
+ public void TriggerPermissionError(UUID user, string reason)
+ {
+ handlerPermissionError = OnPermissionError;
+ if (handlerPermissionError != null)
+ handlerPermissionError(user, reason);
+ }
+
+ public void TriggerOnPluginConsole(string[] args)
+ {
+ handlerPluginConsole = OnPluginConsole;
+ if (handlerPluginConsole != null)
+ handlerPluginConsole(args);
+ }
+
+ public void TriggerOnFrame()
+ {
+ handlerFrame = OnFrame;
+ if (handlerFrame != null)
+ {
+ handlerFrame();
+ }
+ }
+
+ public void TriggerOnNewClient(IClientAPI client)
+ {
+ handlerNewClient = OnNewClient;
+ if (handlerNewClient != null)
+ handlerNewClient(client);
+
+ if (client is IClientCore)
+ {
+ handlerClientConnect = OnClientConnect;
+ handlerClientConnect((IClientCore) client);
+ }
+ }
+
+ public void TriggerOnNewPresence(ScenePresence presence)
+ {
+ handlerNewPresence = OnNewPresence;
+ if (handlerNewPresence != null)
+ handlerNewPresence(presence);
+ }
+
+ public void TriggerOnRemovePresence(UUID agentId)
+ {
+ handlerRemovePresence = OnRemovePresence;
+ if (handlerRemovePresence != null)
+ {
+ handlerRemovePresence(agentId);
+ }
+ }
+
+ public void TriggerOnBackup(IRegionDataStore dstore)
+ {
+ handlerBackup = OnBackup;
+ if (handlerBackup != null)
+ {
+ handlerBackup(dstore, false);
+ }
+ }
+
+ public void TriggerParcelPrimCountUpdate()
+ {
+ handlerParcelPrimCountUpdate = OnParcelPrimCountUpdate;
+ if (handlerParcelPrimCountUpdate != null)
+ {
+ handlerParcelPrimCountUpdate();
+ }
+ }
+
+ public void TriggerMoneyTransfer(Object sender, MoneyTransferArgs e)
+ {
+ handlerMoneyTransfer = OnMoneyTransfer;
+ if (handlerMoneyTransfer != null)
+ {
+ handlerMoneyTransfer(sender, e);
+ }
+ }
+
+ public void TriggerTerrainTick()
+ {
+ handlerTerrainTick = OnTerrainTick;
+ if (handlerTerrainTick != null)
+ {
+ handlerTerrainTick();
+ }
+ }
+
+ public void TriggerParcelPrimCountAdd(SceneObjectGroup obj)
+ {
+ handlerParcelPrimCountAdd = OnParcelPrimCountAdd;
+ if (handlerParcelPrimCountAdd != null)
+ {
+ handlerParcelPrimCountAdd(obj);
+ }
+ }
+
+ public void TriggerObjectBeingRemovedFromScene(SceneObjectGroup obj)
+ {
+ handlerObjectBeingRemovedFromScene = OnObjectBeingRemovedFromScene;
+ if (handlerObjectBeingRemovedFromScene != null)
+ {
+ handlerObjectBeingRemovedFromScene(obj);
+ }
+ }
+
+ public void TriggerShutdown()
+ {
+ handlerShutdown = OnShutdown;
+ if (handlerShutdown != null)
+ handlerShutdown();
+ }
+
+ public void TriggerObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
+ {
+ handlerObjectGrab = OnObjectGrab;
+ if (handlerObjectGrab != null)
+ {
+ handlerObjectGrab(localID, originalID, offsetPos, remoteClient, surfaceArgs);
+ }
+ }
+
+ public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient)
+ {
+ handlerObjectDeGrab = OnObjectDeGrab;
+ if (handlerObjectDeGrab != null)
+ {
+ handlerObjectDeGrab(localID, originalID, remoteClient);
+ }
+ }
+
+ public void TriggerScriptReset(uint localID, UUID itemID)
+ {
+ handlerScriptReset = OnScriptReset;
+ if (handlerScriptReset != null)
+ {
+ handlerScriptReset(localID, itemID);
+ }
+ }
+
+ public void TriggerRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
+ {
+ handlerRezScript = OnRezScript;
+ if (handlerRezScript != null)
+ {
+ handlerRezScript(localID, itemID, script, startParam,
+ postOnRez, engine, stateSource);
+ }
+ }
+
+ public void TriggerStartScript(uint localID, UUID itemID)
+ {
+ handlerStartScript = OnStartScript;
+ if (handlerStartScript != null)
+ {
+ handlerStartScript(localID, itemID);
+ }
+ }
+
+ public void TriggerStopScript(uint localID, UUID itemID)
+ {
+ handlerStopScript = OnStopScript;
+ if (handlerStopScript != null)
+ {
+ handlerStopScript(localID, itemID);
+ }
+ }
+
+ public void TriggerRemoveScript(uint localID, UUID itemID)
+ {
+ handlerRemoveScript = OnRemoveScript;
+ if (handlerRemoveScript != null)
+ {
+ handlerRemoveScript(localID, itemID);
+ }
+ }
+
+ public bool TriggerGroupMove(UUID groupID, Vector3 delta)
+ {
+ handlerSceneGroupMove = OnSceneGroupMove;
+
+ if (handlerSceneGroupMove != null)
+ {
+ return handlerSceneGroupMove(groupID, delta);
+ }
+ return true;
+ }
+
+ public void TriggerGroupGrab(UUID groupID, Vector3 offset, UUID userID)
+ {
+ handlerSceneGroupGrab = OnSceneGroupGrab;
+ if (handlerSceneGroupGrab != null)
+ {
+ handlerSceneGroupGrab(groupID, offset, userID);
+ }
+ }
+
+ public void TriggerLandObjectAdded(ILandObject newParcel)
+ {
+ handlerLandObjectAdded = OnLandObjectAdded;
+
+ if (handlerLandObjectAdded != null)
+ {
+ handlerLandObjectAdded(newParcel);
+ }
+ }
+
+ public void TriggerLandObjectRemoved(UUID globalID)
+ {
+ handlerLandObjectRemoved = OnLandObjectRemoved;
+ if (handlerLandObjectRemoved != null)
+ {
+ handlerLandObjectRemoved(globalID);
+ }
+ }
+
+ public void TriggerLandObjectUpdated(uint localParcelID, ILandObject newParcel)
+ {
+ //triggerLandObjectRemoved(localParcelID);
+
+ TriggerLandObjectAdded(newParcel);
+ }
+
+ public void TriggerAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
+ {
+ handlerAvatarEnteringNewParcel = OnAvatarEnteringNewParcel;
+
+ if (handlerAvatarEnteringNewParcel != null)
+ {
+ handlerAvatarEnteringNewParcel(avatar, localLandID, regionID);
+ }
+ }
+
+ public void TriggerIncomingInstantMessage(GridInstantMessage message)
+ {
+ handlerIncomingInstantMessage = OnIncomingInstantMessage;
+ if (handlerIncomingInstantMessage != null)
+ {
+ handlerIncomingInstantMessage(message);
+ }
+ }
+
+ public void TriggerUnhandledInstantMessage(GridInstantMessage message)
+ {
+ handlerUnhandledInstantMessage = OnUnhandledInstantMessage;
+ if (handlerUnhandledInstantMessage != null)
+ {
+ handlerUnhandledInstantMessage(message);
+ }
+ }
+
+ public void TriggerClientClosed(UUID ClientID)
+ {
+ handlerClientClosed = OnClientClosed;
+ if (handlerClientClosed != null)
+ {
+ handlerClientClosed(ClientID);
+ }
+ }
+
+ public void TriggerOnMakeChildAgent(ScenePresence presence)
+ {
+ handlerMakeChildAgent = OnMakeChildAgent;
+ if (handlerMakeChildAgent != null)
+ {
+ handlerMakeChildAgent(presence);
+ }
+ }
+
+ public void TriggerOnMakeRootAgent(ScenePresence presence)
+ {
+ handlerMakeRootAgent = OnMakeRootAgent;
+ if (handlerMakeRootAgent != null)
+ {
+ handlerMakeRootAgent(presence);
+ }
+ }
+
+ public void TriggerOnRegisterCaps(UUID agentID, Caps caps)
+ {
+ handlerRegisterCaps = OnRegisterCaps;
+ if (handlerRegisterCaps != null)
+ {
+ handlerRegisterCaps(agentID, caps);
+ }
+ }
+
+ public void TriggerOnDeregisterCaps(UUID agentID, Caps caps)
+ {
+ handlerDeregisterCaps = OnDeregisterCaps;
+ if (handlerDeregisterCaps != null)
+ {
+ handlerDeregisterCaps(agentID, caps);
+ }
+ }
+
+ public void TriggerOnNewInventoryItemUploadComplete(UUID agentID, UUID AssetID, String AssetName, int userlevel)
+ {
+ handlerNewInventoryItemUpdateComplete = OnNewInventoryItemUploadComplete;
+ if (handlerNewInventoryItemUpdateComplete != null)
+ {
+ handlerNewInventoryItemUpdateComplete(agentID, AssetID, AssetName, userlevel);
+ }
+ }
+
+ public void TriggerLandBuy(Object sender, LandBuyArgs e)
+ {
+ handlerLandBuy = OnLandBuy;
+ if (handlerLandBuy != null)
+ {
+ handlerLandBuy(sender, e);
+ }
+ }
+
+ public void TriggerValidateLandBuy(Object sender, LandBuyArgs e)
+ {
+ handlerValidateLandBuy = OnValidateLandBuy;
+ if (handlerValidateLandBuy != null)
+ {
+ handlerValidateLandBuy(sender, e);
+ }
+ }
+
+ public void TriggerAtTargetEvent(uint localID, uint handle, Vector3 targetpos, Vector3 currentpos)
+ {
+ handlerScriptAtTargetEvent = OnScriptAtTargetEvent;
+ if (handlerScriptAtTargetEvent != null)
+ {
+ handlerScriptAtTargetEvent(localID, handle, targetpos, currentpos);
+ }
+ }
+
+ public void TriggerNotAtTargetEvent(uint localID)
+ {
+ handlerScriptNotAtTargetEvent = OnScriptNotAtTargetEvent;
+ if (handlerScriptNotAtTargetEvent != null)
+ {
+ handlerScriptNotAtTargetEvent(localID);
+ }
+ }
+
+ public void TriggerRequestChangeWaterHeight(float height)
+ {
+ handlerRequestChangeWaterHeight = OnRequestChangeWaterHeight;
+ if (handlerRequestChangeWaterHeight != null)
+ {
+ handlerRequestChangeWaterHeight(height);
+ }
+ }
+
+ public void TriggerAvatarKill(uint KillerObjectLocalID, ScenePresence DeadAvatar)
+ {
+ handlerAvatarKill = OnAvatarKilled;
+ if (handlerAvatarKill != null)
+ {
+ handlerAvatarKill(KillerObjectLocalID, DeadAvatar);
+ }
+ }
+
+ public void TriggerSignificantClientMovement(IClientAPI client)
+ {
+ handlerSignificantClientMovement = OnSignificantClientMovement;
+ if (handlerSignificantClientMovement != null)
+ {
+ handlerSignificantClientMovement(client);
+ }
+ }
+
+ public void TriggerOnChatFromWorld(Object sender, OSChatMessage chat)
+ {
+ handlerChatFromWorld = OnChatFromWorld;
+ if (handlerChatFromWorld != null)
+ {
+ handlerChatFromWorld(sender, chat);
+ }
+ }
+
+ public void TriggerOnChatFromClient(Object sender, OSChatMessage chat)
+ {
+ handlerChatFromClient = OnChatFromClient;
+ if (handlerChatFromClient != null)
+ {
+ handlerChatFromClient(sender, chat);
+ }
+ }
+
+ public void TriggerOnChatBroadcast(Object sender, OSChatMessage chat)
+ {
+ handlerChatBroadcast = OnChatBroadcast;
+ if (handlerChatBroadcast != null)
+ {
+ handlerChatBroadcast(sender, chat);
+ }
+ }
+
+ internal void TriggerControlEvent(uint p, UUID scriptUUID, UUID avatarID, uint held, uint _changed)
+ {
+ handlerScriptControlEvent = OnScriptControlEvent;
+ if (handlerScriptControlEvent != null)
+ {
+ handlerScriptControlEvent(p, scriptUUID, avatarID, held, _changed);
+ }
+ }
+
+ public void TriggerNoticeNoLandDataFromStorage()
+ {
+ handlerNoticeNoLandDataFromStorage = OnNoticeNoLandDataFromStorage;
+ if (handlerNoticeNoLandDataFromStorage != null)
+ {
+ handlerNoticeNoLandDataFromStorage();
+
+ }
+ }
+
+ public void TriggerIncomingLandDataFromStorage(List landData)
+ {
+ handlerIncomingLandDataFromStorage = OnIncomingLandDataFromStorage;
+ if (handlerIncomingLandDataFromStorage != null)
+ {
+ handlerIncomingLandDataFromStorage(landData);
+
+ }
+ }
+
+ public void TriggerSetAllowForcefulBan(bool allow)
+ {
+ handlerSetAllowForcefulBan = OnSetAllowForcefulBan;
+ if (handlerSetAllowForcefulBan != null)
+ {
+ handlerSetAllowForcefulBan(allow);
+
+ }
+ }
+
+ public void TriggerRequestParcelPrimCountUpdate()
+ {
+ handlerRequestParcelPrimCountUpdate = OnRequestParcelPrimCountUpdate;
+ if (handlerRequestParcelPrimCountUpdate != null)
+ {
+ handlerRequestParcelPrimCountUpdate();
+ }
+ }
+
+ public void TriggerParcelPrimCountTainted()
+ {
+ handlerParcelPrimCountTainted = OnParcelPrimCountTainted;
+ if (handlerParcelPrimCountTainted != null)
+ {
+ handlerParcelPrimCountTainted();
+ }
+ }
+
+ // this lets us keep track of nasty script events like timer, etc.
+ public void TriggerTimerEvent(uint objLocalID, double Interval)
+ {
+ handlerScriptTimerEvent = OnScriptTimerEvent;
+ if (handlerScriptTimerEvent != null)
+ {
+ handlerScriptTimerEvent(objLocalID, Interval);
+ }
+ }
+
+ public void TriggerEstateToolsTimeUpdate(ulong regionHandle, bool FixedTime, bool useEstateTime, float LindenHour)
+ {
+ handlerEstateToolsTimeUpdate = OnEstateToolsTimeUpdate;
+ if (handlerEstateToolsTimeUpdate != null)
+ {
+ handlerEstateToolsTimeUpdate(regionHandle, FixedTime, useEstateTime, LindenHour);
+ }
+ }
+
+ public float GetSunLindenHour()
+ {
+ handlerSunGetLindenHour = OnGetSunLindenHour;
+ if (handlerSunGetLindenHour != null)
+ {
+ return handlerSunGetLindenHour();
+ }
+ return 6;
+ }
+
+ public void TriggerOarFileLoaded(string message)
+ {
+ handlerOarFileLoaded = OnOarFileLoaded;
+ if (handlerOarFileLoaded != null)
+ handlerOarFileLoaded(message);
+ }
+
+ public void TriggerOarFileSaved(string message)
+ {
+ handlerOarFileSaved = OnOarFileSaved;
+ if (handlerOarFileSaved != null)
+ handlerOarFileSaved(message);
+ }
+
+ public void TriggerEmptyScriptCompileQueue(int numScriptsFailed, string message)
+ {
+ handlerEmptyScriptCompileQueue = OnEmptyScriptCompileQueue;
+ if (handlerEmptyScriptCompileQueue != null)
+ handlerEmptyScriptCompileQueue(numScriptsFailed, message);
+ }
+
+ public void TriggerScriptCollidingStart(uint localId, ColliderArgs colliders)
+ {
+ handlerCollidingStart = OnScriptColliderStart;
+ if (handlerCollidingStart != null)
+ handlerCollidingStart(localId, colliders);
+ }
+
+ public void TriggerScriptColliding(uint localId, ColliderArgs colliders)
+ {
+ handlerColliding = OnScriptColliding;
+ if (handlerColliding != null)
+ handlerColliding(localId, colliders);
+ }
+
+ public void TriggerScriptCollidingEnd(uint localId, ColliderArgs colliders)
+ {
+ handlerCollidingEnd = OnScriptCollidingEnd;
+ if (handlerCollidingEnd != null)
+ handlerCollidingEnd(localId, colliders);
+ }
+
+ public void TriggerSetRootAgentScene(UUID agentID, Scene scene)
+ {
+ handlerSetRootAgentScene = OnSetRootAgentScene;
+ if (handlerSetRootAgentScene != null)
+ handlerSetRootAgentScene(agentID, scene);
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
new file mode 100644
index 0000000..bd9c260
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
@@ -0,0 +1,376 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+using log4net;
+using Nini.Config;
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+// using OpenSim.Region.Environment;
+using OpenSim.Region.Framework.Scenes;
+
+//using HyperGrid.Framework;
+//using OpenSim.Region.Communications.Hypergrid;
+
+namespace OpenSim.Region.Framework.Scenes.Hypergrid
+{
+ public class HGAssetMapper
+ {
+ #region Fields
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ // This maps between asset server URLs and asset server clients
+ private Dictionary m_assetServers = new Dictionary();
+
+ // This maps between asset UUIDs and asset servers
+ private Dictionary m_assetMap = new Dictionary();
+
+ private Scene m_scene;
+ #endregion
+
+ #region Constructor
+
+ public HGAssetMapper(Scene scene)
+ {
+ m_scene = scene;
+ }
+
+ #endregion
+
+ #region Internal functions
+
+ private string UserAssetURL(UUID userID)
+ {
+ CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
+ if (uinfo != null)
+ return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI;
+ return null;
+ }
+
+ private bool IsLocalUser(UUID userID)
+ {
+ CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
+
+ if (uinfo != null)
+ {
+ if (HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile))
+ {
+ m_log.Debug("[HGScene]: Home user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
+ return true;
+ }
+ }
+
+ m_log.Debug("[HGScene]: Foreign user " + uinfo.UserProfile.FirstName + " " + uinfo.UserProfile.SurName);
+ return false;
+ }
+
+ private bool IsInAssetMap(UUID uuid)
+ {
+ return m_assetMap.ContainsKey(uuid);
+ }
+
+ private bool FetchAsset(GridAssetClient asscli, UUID assetID, bool isTexture)
+ {
+ // I'm not going over 3 seconds since this will be blocking processing of all the other inbound
+ // packets from the client.
+ int pollPeriod = 200;
+ int maxPolls = 15;
+
+ AssetBase asset;
+
+ // Maybe it came late, and it's already here. Check first.
+ if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset))
+ {
+ m_log.Debug("[HGScene]: Asset already in asset cache. " + assetID);
+ return true;
+ }
+
+
+ asscli.RequestAsset(assetID, isTexture);
+
+ do
+ {
+ Thread.Sleep(pollPeriod);
+
+ if (m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset) && (asset != null))
+ {
+ m_log.Debug("[HGScene]: Asset made it to asset cache. " + asset.Metadata.Name + " " + assetID);
+ // I think I need to store it in the asset DB too.
+ // For now, let me just do it for textures and scripts
+ if (((AssetType)asset.Metadata.Type == AssetType.Texture) ||
+ ((AssetType)asset.Metadata.Type == AssetType.LSLBytecode) ||
+ ((AssetType)asset.Metadata.Type == AssetType.LSLText))
+ {
+ AssetBase asset1 = new AssetBase();
+ Copy(asset, asset1);
+ m_scene.AssetCache.AssetServer.StoreAsset(asset1);
+ }
+ return true;
+ }
+ } while (--maxPolls > 0);
+
+ m_log.WarnFormat("[HGScene]: {0} {1} was not received before the retrieval timeout was reached",
+ isTexture ? "texture" : "asset", assetID.ToString());
+
+ return false;
+ }
+
+ private bool PostAsset(GridAssetClient asscli, UUID assetID)
+ {
+ AssetBase asset1;
+ m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset1);
+
+ if (asset1 != null)
+ {
+ // See long comment in AssetCache.AddAsset
+ if (!asset1.Metadata.Temporary || asset1.Metadata.Local)
+ {
+ // The asset cache returns instances of subclasses of AssetBase:
+ // TextureImage or AssetInfo. So in passing them to the remote
+ // server we first need to convert this to instances of AssetBase,
+ // which is the serializable class for assets.
+ AssetBase asset = new AssetBase();
+ Copy(asset1, asset);
+
+ asscli.StoreAsset(asset);
+ }
+ return true;
+ }
+ else
+ m_log.Warn("[HGScene]: Tried to post asset to remote server, but asset not in local cache.");
+
+ return false;
+ }
+
+ private void Copy(AssetBase from, AssetBase to)
+ {
+ to.Data = from.Data;
+ to.Metadata.Description = from.Metadata.Description;
+ to.Metadata.FullID = from.Metadata.FullID;
+ to.Metadata.ID = from.Metadata.ID;
+ to.Metadata.Local = from.Metadata.Local;
+ to.Metadata.Name = from.Metadata.Name;
+ to.Metadata.Temporary = from.Metadata.Temporary;
+ to.Metadata.Type = from.Metadata.Type;
+
+ }
+
+ private void _guardedAdd(Dictionary lst, UUID obj, bool val)
+ {
+ if (!lst.ContainsKey(obj))
+ lst.Add(obj, val);
+ }
+
+ private void SniffTextureUUIDs(Dictionary uuids, SceneObjectGroup sog)
+ {
+ try
+ {
+ _guardedAdd(uuids, sog.RootPart.Shape.Textures.DefaultTexture.TextureID, true);
+ }
+ catch (Exception) { }
+
+ foreach (Primitive.TextureEntryFace tface in sog.RootPart.Shape.Textures.FaceTextures)
+ {
+ try
+ {
+ _guardedAdd(uuids, tface.TextureID, true);
+ }
+ catch (Exception) { }
+ }
+
+ foreach (SceneObjectPart sop in sog.Children.Values)
+ {
+ try
+ {
+ _guardedAdd(uuids, sop.Shape.Textures.DefaultTexture.TextureID, true);
+ }
+ catch (Exception) { }
+ foreach (Primitive.TextureEntryFace tface in sop.Shape.Textures.FaceTextures)
+ {
+ try
+ {
+ _guardedAdd(uuids, tface.TextureID, true);
+ }
+ catch (Exception) { }
+ }
+ }
+ }
+
+ private void SniffTaskInventoryUUIDs(Dictionary uuids, SceneObjectGroup sog)
+ {
+ TaskInventoryDictionary tinv = sog.RootPart.TaskInventory;
+
+ foreach (TaskInventoryItem titem in tinv.Values)
+ {
+ uuids.Add(titem.AssetID, (InventoryType)titem.Type == InventoryType.Texture);
+ }
+ }
+
+ private Dictionary SniffUUIDs(AssetBase asset)
+ {
+ Dictionary uuids = new Dictionary();
+ if ((asset != null) && ((AssetType)asset.Metadata.Type == AssetType.Object))
+ {
+ string ass_str = Utils.BytesToString(asset.Data);
+ SceneObjectGroup sog = new SceneObjectGroup(ass_str, true);
+
+ SniffTextureUUIDs(uuids, sog);
+
+ // We need to sniff further...
+ SniffTaskInventoryUUIDs(uuids, sog);
+
+ }
+
+ return uuids;
+ }
+
+ private Dictionary SniffUUIDs(UUID assetID)
+ {
+ //Dictionary uuids = new Dictionary();
+
+ AssetBase asset;
+ m_scene.CommsManager.AssetCache.TryGetCachedAsset(assetID, out asset);
+
+ return SniffUUIDs(asset);
+ }
+
+ private void Dump(Dictionary lst)
+ {
+ m_log.Debug("XXX -------- UUID DUMP ------- XXX");
+ foreach (KeyValuePair kvp in lst)
+ m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
+ m_log.Debug("XXX -------- UUID DUMP ------- XXX");
+ }
+
+ #endregion
+
+
+ #region Public interface
+
+ public void Get(UUID itemID, UUID ownerID)
+ {
+ if (!IsInAssetMap(itemID) && !IsLocalUser(ownerID))
+ {
+ // Get the item from the remote asset server onto the local AssetCache
+ // and place an entry in m_assetMap
+
+ GridAssetClient asscli = null;
+ string userAssetURL = UserAssetURL(ownerID);
+ if (userAssetURL != null)
+ {
+ m_assetServers.TryGetValue(userAssetURL, out asscli);
+ if (asscli == null)
+ {
+ m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
+ asscli = new GridAssetClient(userAssetURL);
+ asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
+ m_assetServers.Add(userAssetURL, asscli);
+ }
+
+ m_log.Debug("[HGScene]: Fetching object " + itemID + " to asset server " + userAssetURL);
+ bool success = FetchAsset(asscli, itemID, false); // asscli.RequestAsset(item.ItemID, false);
+
+ // OK, now fetch the inside.
+ Dictionary ids = SniffUUIDs(itemID);
+ Dump(ids);
+ foreach (KeyValuePair kvp in ids)
+ FetchAsset(asscli, kvp.Key, kvp.Value);
+
+
+ if (success)
+ {
+ m_log.Debug("[HGScene]: Successfully fetched item from remote asset server " + userAssetURL);
+ m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Could not fetch asset from remote asset server " + userAssetURL);
+ }
+ else
+ m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
+ }
+ }
+
+ public void Post(UUID itemID, UUID ownerID)
+ {
+ if (!IsLocalUser(ownerID))
+ {
+ // Post the item from the local AssetCache ontp the remote asset server
+ // and place an entry in m_assetMap
+
+ GridAssetClient asscli = null;
+ string userAssetURL = UserAssetURL(ownerID);
+ if (userAssetURL != null)
+ {
+ m_assetServers.TryGetValue(userAssetURL, out asscli);
+ if (asscli == null)
+ {
+ m_log.Debug("[HGScene]: Starting new GridAssetClient for " + userAssetURL);
+ asscli = new GridAssetClient(userAssetURL);
+ asscli.SetReceiver(m_scene.CommsManager.AssetCache); // Straight to the asset cache!
+ m_assetServers.Add(userAssetURL, asscli);
+ }
+ m_log.Debug("[HGScene]: Posting object " + itemID + " to asset server " + userAssetURL);
+ bool success = PostAsset(asscli, itemID);
+
+ // Now the inside
+ Dictionary ids = SniffUUIDs(itemID);
+ Dump(ids);
+ foreach (KeyValuePair kvp in ids)
+ PostAsset(asscli, kvp.Key);
+
+ if (success)
+ {
+ m_log.Debug("[HGScene]: Successfully posted item to remote asset server " + userAssetURL);
+ if (!m_assetMap.ContainsKey(itemID))
+ m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Could not post asset to remote asset server " + userAssetURL);
+
+ //if (!m_assetMap.ContainsKey(itemID))
+ // m_assetMap.Add(itemID, asscli);
+ }
+ else
+ m_log.Warn("[HGScene]: Unable to locate foreign user's asset server");
+
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs
new file mode 100644
index 0000000..f36075e
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.Inventory.cs
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading;
+
+using log4net;
+using Nini.Config;
+using OpenMetaverse;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+// using OpenSim.Region.Environment;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.Framework.Scenes.Hypergrid
+{
+ public partial class HGScene : Scene
+ {
+ #region Fields
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private HGAssetMapper m_assMapper;
+
+ #endregion
+
+ #region Constructors
+
+ public HGScene(RegionInfo regInfo, AgentCircuitManager authen,
+ CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
+ AssetCache assetCach, StorageManager storeManager,
+ ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
+ bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
+ : base(regInfo, authen, commsMan, sceneGridService, assetCach, storeManager, moduleLoader,
+ dumpAssetsToFile, physicalPrim, SeeIntoRegionFromNeighbor, config, simulatorVersion)
+ {
+ m_log.Info("[HGScene]: Starting HGScene.");
+ m_assMapper = new HGAssetMapper(this);
+
+ EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
+ }
+
+ #endregion
+
+ #region Event handlers
+
+ public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(avatarID);
+ if (userInfo != null)
+ {
+ m_assMapper.Post(assetID, avatarID);
+ }
+ }
+
+ #endregion
+
+ #region Overrides of Scene.Inventory methods
+
+ ///
+ /// CapsUpdateInventoryItemAsset
+ ///
+ public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
+ {
+ UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
+
+ UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
+
+ return newAssetID;
+ }
+
+ ///
+ /// DeleteToInventory
+ ///
+ public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
+ {
+ UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient);
+
+ if (!assetID.Equals(UUID.Zero))
+ {
+ UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
+ }
+ else
+ m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
+
+ return assetID;
+ }
+
+ ///
+ /// RezObject
+ ///
+ public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+ if (userInfo != null)
+ {
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ m_assMapper.Get(item.AssetID, remoteClient.AgentId);
+
+ }
+ }
+ }
+
+ // OK, we're done fetching. Pass it up to the default RezObject
+ return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, attachment);
+
+ }
+
+
+ #endregion
+
+ }
+
+}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs
new file mode 100644
index 0000000..a52fdc6
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGScene.cs
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+using OpenMetaverse;
+
+using OpenSim.Framework;
+
+using OpenSim.Framework.Communications.Cache;
+// using OpenSim.Region.Environment;
+using OpenSim.Region.Framework.Scenes;
+using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
+
+namespace OpenSim.Region.Framework.Scenes.Hypergrid
+{
+ public partial class HGScene : Scene
+ {
+ ///
+ /// Teleport an avatar to their home region
+ ///
+ ///
+ ///
+ public override void TeleportClientHome(UUID agentId, IClientAPI client)
+ {
+ m_log.Debug("[HGScene]: TeleportClientHome " + client.FirstName + " " + client.LastName);
+
+ CachedUserInfo uinfo = CommsManager.UserProfileCacheService.GetUserDetails(agentId);
+ if (uinfo != null)
+ {
+ UserProfileData UserProfile = uinfo.UserProfile;
+
+ if (UserProfile != null)
+ {
+ RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
+ //if (regionInfo != null)
+ //{
+ // UserProfile.HomeRegionID = regionInfo.RegionID;
+ // //CommsManager.UserService.UpdateUserProfile(UserProfile);
+ //}
+ if (regionInfo == null)
+ {
+ // can't find the Home region: Tell viewer and abort
+ client.SendTeleportFailed("Your home-region could not be found.");
+ return;
+ }
+ RequestTeleportLocation(
+ client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
+ (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
+ }
+ }
+ else
+ client.SendTeleportFailed("Sorry! I lost your home-region information.");
+
+ }
+
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
new file mode 100644
index 0000000..d0dc4f7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -0,0 +1,360 @@
+/**
+ * Copyright (c) 2008, Contributors. All rights reserved.
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the Organizations nor the names of Individual
+ * Contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Reflection;
+using System.Threading;
+using log4net;
+using OpenMetaverse;
+using OSD = OpenMetaverse.StructuredData.OSD;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Communications.Capabilities;
+using OpenSim.Region.Framework.Scenes;
+// using OpenSim.Region.Environment;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Region.Framework.Scenes.Hypergrid
+{
+ public class HGSceneCommunicationService : SceneCommunicationService
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public readonly IHyperlink m_hg;
+
+ public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan)
+ {
+ m_hg = hg;
+ }
+
+
+ ///
+ /// Try to teleport an agent to a new region.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
+ Vector3 lookAt, uint teleportFlags)
+ {
+ if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
+ return;
+
+ bool destRegionUp = true;
+
+ IEventQueue eq = avatar.Scene.RequestModuleInterface();
+
+ if (regionHandle == m_regionInfo.RegionHandle)
+ {
+ // Teleport within the same region
+ if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0)
+ {
+ Vector3 emergencyPos = new Vector3(128, 128, 128);
+
+ m_log.WarnFormat(
+ "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
+ position, avatar.Name, avatar.UUID, emergencyPos);
+ position = emergencyPos;
+ }
+ // TODO: Get proper AVG Height
+ float localAVHeight = 1.56f;
+ float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y);
+ float newPosZ = posZLimit + localAVHeight;
+ if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
+ {
+ position.Z = newPosZ;
+ }
+
+ // Only send this if the event queue is null
+ if (eq == null)
+ avatar.ControllingClient.SendTeleportLocationStart();
+
+
+ avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
+ avatar.Teleport(position);
+ }
+ else
+ {
+ RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
+ if (reg != null)
+ {
+
+ uint newRegionX = (uint)(reg.RegionHandle >> 40);
+ uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
+ uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
+ uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
+
+ ///
+ /// Hypergrid mod start
+ ///
+ ///
+ bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
+ bool isHomeUser = true;
+ ulong realHandle = regionHandle;
+ CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
+ if (uinfo != null)
+ {
+ isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile);
+ realHandle = m_hg.FindRegionHandle(regionHandle);
+ Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
+ }
+ ///
+ /// Hypergrid mod stop
+ ///
+ ///
+
+ if (eq == null)
+ avatar.ControllingClient.SendTeleportLocationStart();
+
+
+ // Let's do DNS resolution only once in this process, please!
+ // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
+ // it's actually doing a lot of work.
+ IPEndPoint endPoint = reg.ExternalEndPoint;
+ if (endPoint.Address == null)
+ {
+ // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses.
+ destRegionUp = false;
+ }
+
+ if (destRegionUp)
+ {
+ // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
+ // both regions
+ if (avatar.ParentID != (uint)0)
+ avatar.StandUp();
+
+ if (!avatar.ValidateAttachments())
+ {
+ avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
+ return;
+ }
+
+ // the avatar.Close below will clear the child region list. We need this below for (possibly)
+ // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
+ //List childRegions = new List(avatar.GetKnownRegionList());
+ // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
+ // failure at this point (unlike a border crossing failure). So perhaps this can never fail
+ // once we reach here...
+ //avatar.Scene.RemoveCapsHandler(avatar.UUID);
+
+ string capsPath = String.Empty;
+ AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo();
+ agentCircuit.BaseFolder = UUID.Zero;
+ agentCircuit.InventoryFolder = UUID.Zero;
+ agentCircuit.startpos = position;
+ agentCircuit.child = true;
+ if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
+ {
+ // brand new agent, let's create a new caps seed
+ agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
+ }
+
+ //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit))
+ if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit))
+ {
+ avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
+ return;
+ }
+
+ // Let's close some agents
+ if (isHyperLink) // close them all except this one
+ {
+ List regions = new List(avatar.KnownChildRegionHandles);
+ regions.Remove(avatar.Scene.RegionInfo.RegionHandle);
+ SendCloseChildAgentConnections(avatar.UUID, regions);
+ }
+ else // close just a few
+ avatar.CloseChildAgents(newRegionX, newRegionY);
+
+ if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
+ {
+ capsPath
+ = "http://"
+ + reg.ExternalHostName
+ + ":"
+ + reg.HttpPort
+ + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
+
+ if (eq != null)
+ {
+ eq.EnableSimulator(realHandle, endPoint, avatar.UUID);
+
+ // ES makes the client send a UseCircuitCode message to the destination,
+ // which triggers a bunch of things there.
+ // So let's wait
+ Thread.Sleep(2000);
+
+ eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath);
+ }
+ else
+ {
+ avatar.ControllingClient.InformClientOfNeighbour(realHandle, endPoint);
+ // TODO: make Event Queue disablable!
+ }
+ }
+ else
+ {
+ // child agent already there
+ agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle);
+ capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort
+ + "/CAPS/" + agentCircuit.CapsPath + "0000/";
+ }
+
+ //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
+ // position, false);
+
+ //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
+ // position, false))
+ //{
+ // avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
+ // // We should close that agent we just created over at destination...
+ // List lst = new List();
+ // lst.Add(realHandle);
+ // SendCloseChildAgentAsync(avatar.UUID, lst);
+ // return;
+ //}
+
+ SetInTransit(avatar.UUID);
+ // Let's send a full update of the agent. This is a synchronous call.
+ AgentData agent = new AgentData();
+ avatar.CopyTo(agent);
+ agent.Position = position;
+ agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort +
+ "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/";
+
+ m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
+
+ m_log.DebugFormat(
+ "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID);
+
+
+ ///
+ /// Hypergrid mod: realHandle instead of reg.RegionHandle
+ ///
+ ///
+ if (eq != null)
+ {
+ eq.TeleportFinishEvent(realHandle, 13, endPoint,
+ 4, teleportFlags, capsPath, avatar.UUID);
+ }
+ else
+ {
+ avatar.ControllingClient.SendRegionTeleport(realHandle, 13, endPoint, 4,
+ teleportFlags, capsPath);
+ }
+ ///
+ /// Hypergrid mod stop
+ ///
+
+
+ // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
+ // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
+ // that the client contacted the destination before we send the attachments and close things here.
+ if (!WaitForCallback(avatar.UUID))
+ {
+ // Client never contacted destination. Let's restore everything back
+ avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
+
+ ResetFromTransit(avatar.UUID);
+ // Yikes! We should just have a ref to scene here.
+ avatar.Scene.InformClientOfNeighbours(avatar);
+
+ // Finally, kill the agent we just created at the destination.
+ m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID);
+
+ return;
+ }
+
+ // Can't go back from here
+ if (KiPrimitive != null)
+ {
+ KiPrimitive(avatar.LocalId);
+ }
+
+ avatar.MakeChildAgent();
+
+ // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
+ avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
+
+
+ // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
+ ///
+ /// Hypergrid mod: extra check for isHyperLink
+ ///
+ if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
+ {
+ Thread.Sleep(5000);
+ avatar.Close();
+ CloseConnection(avatar.UUID);
+ }
+ // if (teleport success) // seems to be always success here
+ // the user may change their profile information in other region,
+ // so the userinfo in UserProfileCache is not reliable any more, delete it
+ if (avatar.Scene.NeedSceneCacheClear(avatar.UUID) || isHyperLink)
+ {
+ m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
+ m_log.DebugFormat(
+ "[HGSceneCommService]: User {0} is going to another region, profile cache removed",
+ avatar.UUID);
+ }
+ }
+ else
+ {
+ avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
+ }
+ }
+ else
+ {
+ // TP to a place that doesn't exist (anymore)
+ // Inform the viewer about that
+ avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
+
+ // and set the map-tile to '(Offline)'
+ uint regX, regY;
+ Utils.LongToUInts(regionHandle, out regX, out regY);
+
+ MapBlockData block = new MapBlockData();
+ block.X = (ushort)(regX / Constants.RegionSize);
+ block.Y = (ushort)(regY / Constants.RegionSize);
+ block.Access = 254; // == not there
+
+ List blocks = new List();
+ blocks.Add(block);
+ avatar.ControllingClient.SendMapBlock(blocks, 0);
+ }
+ }
+ }
+
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/IScenePresenceBody.cs b/OpenSim/Region/Framework/Scenes/IScenePresenceBody.cs
new file mode 100644
index 0000000..bd5ad33
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/IScenePresenceBody.cs
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public interface IScenePresenceBody
+ {
+ void processMovement(IClientAPI remoteClient, uint flags, Quaternion bodyRotation);
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/ReturnInfo.cs b/OpenSim/Region/Framework/Scenes/ReturnInfo.cs
new file mode 100644
index 0000000..43d07f5
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/ReturnInfo.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using OpenMetaverse;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public struct ReturnInfo
+ {
+ public int count;
+ public Vector3 location;
+ public string objectName;
+ public string reason;
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
new file mode 100644
index 0000000..e366c79
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -0,0 +1,2665 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using System.Timers;
+using OpenMetaverse;
+using log4net;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Region.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public partial class Scene
+ {
+ private static readonly ILog m_log
+ = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Allows asynchronous derezzing of objects from the scene into a client's inventory.
+ ///
+ protected AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter;
+
+ ///
+ /// Start all the scripts in the scene which should be started.
+ ///
+ public void CreateScriptInstances()
+ {
+ m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
+
+ foreach (EntityBase group in Entities)
+ {
+ if (group is SceneObjectGroup)
+ {
+ ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
+ }
+ }
+ }
+
+ public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
+ {
+ IMoneyModule money=RequestModuleInterface();
+ if (money != null)
+ {
+ money.ApplyUploadCharge(agentID);
+ }
+
+ AddInventoryItem(agentID, item);
+ }
+
+ public bool AddInventoryItemReturned(UUID AgentId, InventoryItemBase item)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(AgentId);
+ if (userInfo != null)
+ {
+ userInfo.AddItem(item);
+ return true;
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Agent was not found for add of item {1} {2}", item.Name, item.ID);
+
+ return false;
+ }
+ }
+
+ public void AddInventoryItem(UUID AgentID, InventoryItemBase item)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(AgentID);
+
+ if (userInfo != null)
+ {
+ userInfo.AddItem(item);
+
+ int userlevel = 0;
+ if (Permissions.IsGod(AgentID))
+ {
+ userlevel = 1;
+ }
+ // TODO: remove this cruft once MasterAvatar is fully deprecated
+ //
+ if (m_regInfo.MasterAvatarAssignedUUID == AgentID)
+ {
+ userlevel = 2;
+ }
+ EventManager.TriggerOnNewInventoryItemUploadComplete(AgentID, item.AssetID, item.Name, userlevel);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Agent {1} was not found for add of item {2} {3}",
+ AgentID, item.Name, item.ID);
+
+ return;
+ }
+ }
+
+ ///
+ /// Add an inventory item to an avatar's inventory.
+ ///
+ /// The remote client controlling the avatar
+ /// The item. This structure contains all the item metadata, including the folder
+ /// in which the item is to be placed.
+ public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null)
+ {
+ AddInventoryItem(remoteClient.AgentId, item);
+ remoteClient.SendInventoryItemCreateUpdate(item);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not resolve user {0} for adding an inventory item",
+ remoteClient.AgentId);
+ }
+ }
+
+ ///
+ /// Capability originating call to update the asset of an item in an agent's inventory
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+ if (userInfo != null)
+ {
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ if ((InventoryType)item.InvType == InventoryType.Notecard)
+ {
+ if (!Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
+ {
+ remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
+ return UUID.Zero;
+ }
+
+ remoteClient.SendAgentAlertMessage("Notecard saved", false);
+ }
+ else if ((InventoryType)item.InvType == InventoryType.LSL)
+ {
+ if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
+ {
+ remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
+ return UUID.Zero;
+ }
+
+ remoteClient.SendAgentAlertMessage("Script saved", false);
+ }
+
+ AssetBase asset =
+ CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data);
+ AssetCache.AddAsset(asset);
+
+ item.AssetID = asset.Metadata.FullID;
+ userInfo.UpdateItem(item);
+
+ // remoteClient.SendInventoryItemCreateUpdate(item);
+ return (asset.Metadata.FullID);
+ }
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not resolve user {0} for caps inventory update",
+ remoteClient.AgentId);
+ }
+
+ return UUID.Zero;
+ }
+
+ ///
+ /// CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])
+ ///
+ public UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
+ {
+ ScenePresence avatar;
+
+ if (TryGetAvatar(avatarId, out avatar))
+ {
+ return CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: " +
+ "Avatar {0} cannot be found to update its inventory item asset",
+ avatarId);
+ }
+
+ return UUID.Zero;
+ }
+
+ ///
+ /// Capability originating call to update the asset of a script in a prim's (task's) inventory
+ ///
+ ///
+ ///
+ /// The prim which contains the item to update
+ /// Indicates whether the script to update is currently running
+ ///
+ public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
+ UUID primId, bool isScriptRunning, byte[] data)
+ {
+ if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
+ {
+ remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
+ return;
+ }
+
+ // Retrieve group
+ SceneObjectPart part = GetSceneObjectPart(primId);
+ SceneObjectGroup group = part.ParentGroup;
+ if (null == group)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
+ itemId, primId);
+
+ return;
+ }
+
+ // Retrieve item
+ TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId);
+
+ if (null == item)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update "
+ + " but the item does not exist in this inventory",
+ itemId, part.Name, part.UUID);
+
+ return;
+ }
+
+ AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data);
+ AssetCache.AddAsset(asset);
+
+ if (isScriptRunning)
+ {
+ part.Inventory.RemoveScriptInstance(item.ItemID);
+ }
+
+ // Update item with new asset
+ item.AssetID = asset.Metadata.FullID;
+ group.UpdateInventoryItem(item);
+ part.GetProperties(remoteClient);
+
+ // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
+ if (isScriptRunning)
+ {
+ // Needs to determine which engine was running it and use that
+ //
+ part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
+ }
+ else
+ {
+ remoteClient.SendAgentAlertMessage("Script saved", false);
+ }
+ }
+
+ ///
+ /// CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])
+ ///
+ public void CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
+ UUID primId, bool isScriptRunning, byte[] data)
+ {
+ ScenePresence avatar;
+
+ if (TryGetAvatar(avatarId, out avatar))
+ {
+ CapsUpdateTaskInventoryScriptAsset(
+ avatar.ControllingClient, itemId, primId, isScriptRunning, data);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Avatar {0} cannot be found to update its prim item asset",
+ avatarId);
+ }
+ }
+
+ ///
+ /// Update an item which is either already in the client's inventory or is within
+ /// a transaction
+ ///
+ ///
+ /// The transaction ID. If this is UUID.Zero we will
+ /// assume that we are not in a transaction
+ /// The ID of the updated item
+ /// The name of the updated item
+ /// The description of the updated item
+ /// The permissions of the updated item
+/* public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
+ UUID itemID, string name, string description,
+ uint nextOwnerMask)*/
+ public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID,
+ UUID itemID, InventoryItemBase itemUpd)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null && userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ if (UUID.Zero == transactionID)
+ {
+ item.Name = itemUpd.Name;
+ item.Description = itemUpd.Description;
+ item.NextPermissions = itemUpd.NextPermissions;
+ item.CurrentPermissions |= 8; // Slam!
+ item.EveryOnePermissions = itemUpd.EveryOnePermissions;
+ item.GroupPermissions = itemUpd.GroupPermissions;
+
+ item.GroupID = itemUpd.GroupID;
+ item.GroupOwned = itemUpd.GroupOwned;
+ item.CreationDate = itemUpd.CreationDate;
+ // The client sends zero if its newly created?
+
+ if (itemUpd.CreationDate == 0)
+ item.CreationDate = Util.UnixTimeSinceEpoch();
+ else
+ item.CreationDate = itemUpd.CreationDate;
+
+ // TODO: Check if folder changed and move item
+ //item.NextPermissions = itemUpd.Folder;
+ item.InvType = itemUpd.InvType;
+ item.SalePrice = itemUpd.SalePrice;
+ item.SaleType = itemUpd.SaleType;
+ item.Flags = itemUpd.Flags;
+
+ userInfo.UpdateItem(item);
+ }
+ else
+ {
+ IAgentAssetTransactions agentTransactions = this.RequestModuleInterface();
+ if (agentTransactions != null)
+ {
+ agentTransactions.HandleItemUpdateFromTransaction(
+ remoteClient, transactionID, item);
+ }
+ }
+ }
+ else
+ {
+ m_log.Error(
+ "[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update.");
+ }
+ }
+ else
+ {
+ m_log.Error(
+ "[AGENT INVENTORY]: Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
+ }
+ }
+
+ ///
+ /// Give an inventory item from one user to another
+ ///
+ ///
+ /// ID of the sender of the item
+ ///
+ public virtual void GiveInventoryItem(IClientAPI recipientClient, UUID senderId, UUID itemId)
+ {
+ InventoryItemBase itemCopy = GiveInventoryItem(recipientClient.AgentId, senderId, itemId);
+
+ if (itemCopy != null)
+ recipientClient.SendBulkUpdateInventory(itemCopy);
+ }
+
+ ///
+ /// Give an inventory item from one user to another
+ ///
+ ///
+ /// ID of the sender of the item
+ ///
+ /// The inventory item copy given, null if the give was unsuccessful
+ public virtual InventoryItemBase GiveInventoryItem(UUID recipient, UUID senderId, UUID itemId)
+ {
+ return GiveInventoryItem(recipient, senderId, itemId, UUID.Zero);
+ }
+
+ ///
+ /// Give an inventory item from one user to another
+ ///
+ ///
+ /// ID of the sender of the item
+ ///
+ ///
+ /// The id of the folder in which the copy item should go. If UUID.Zero then the item is placed in the most
+ /// appropriate default folder.
+ ///
+ ///
+ /// The inventory item copy given, null if the give was unsuccessful
+ ///
+ public virtual InventoryItemBase GiveInventoryItem(
+ UUID recipient, UUID senderId, UUID itemId, UUID recipientFolderId)
+ {
+ // Retrieve the item from the sender
+ CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId);
+
+ if (senderUserInfo == null)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to find sending user {0} for item {1}", senderId, itemId);
+
+ return null;
+ }
+
+ if (senderUserInfo.RootFolder != null)
+ {
+ InventoryItemBase item = senderUserInfo.RootFolder.FindItem(itemId);
+
+ if (item != null)
+ {
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
+ return null;
+ }
+
+ CachedUserInfo recipientUserInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(recipient);
+
+ if (recipientUserInfo != null)
+ {
+ if (!recipientUserInfo.HasReceivedInventory)
+ CommsManager.UserProfileCacheService.RequestInventoryForUser(recipient);
+
+ // Insert a copy of the item into the recipient
+ InventoryItemBase itemCopy = new InventoryItemBase();
+ itemCopy.Owner = recipient;
+ itemCopy.Creator = item.Creator;
+ itemCopy.ID = UUID.Random();
+ itemCopy.AssetID = item.AssetID;
+ itemCopy.Description = item.Description;
+ itemCopy.Name = item.Name;
+ itemCopy.AssetType = item.AssetType;
+ itemCopy.InvType = item.InvType;
+ itemCopy.Folder = recipientFolderId;
+
+ if (Permissions.PropagatePermissions())
+ {
+ if (item.InvType == 6)
+ {
+ itemCopy.BasePermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
+ itemCopy.BasePermissions |= (item.CurrentPermissions & 7) << 13;
+ }
+ else
+ {
+ itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions;
+ }
+
+ itemCopy.CurrentPermissions = itemCopy.BasePermissions;
+ if ((item.CurrentPermissions & 8) != 0) // Propagate slam bit
+ {
+ itemCopy.BasePermissions &= item.NextPermissions;
+ itemCopy.CurrentPermissions = itemCopy.BasePermissions;
+ itemCopy.CurrentPermissions |= 8;
+ }
+
+ itemCopy.NextPermissions = item.NextPermissions;
+ itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
+ itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
+ }
+ else
+ {
+ itemCopy.CurrentPermissions = item.CurrentPermissions;
+ itemCopy.NextPermissions = item.NextPermissions;
+ itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
+ itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions;
+ itemCopy.BasePermissions = item.BasePermissions;
+ }
+ itemCopy.GroupID = UUID.Zero;
+ itemCopy.GroupOwned = false;
+ itemCopy.Flags = item.Flags;
+ itemCopy.SalePrice = item.SalePrice;
+ itemCopy.SaleType = item.SaleType;
+
+ itemCopy.CreationDate = item.CreationDate;
+
+ recipientUserInfo.AddItem(itemCopy);
+
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ senderUserInfo.DeleteItem(itemId);
+ }
+
+ return itemCopy;
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find userinfo for recipient user {0} of item {1}, {2} from {3}",
+ recipient, item.Name,
+ item.ID, senderId);
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to find item {0} to give to {1}", itemId, senderId);
+
+ return null;
+ }
+ }
+ else
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemId.ToString() + ", no root folder");
+ return null;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Give an entire inventory folder from one user to another. The entire contents (including all descendent
+ /// folders) is given.
+ ///
+ ///
+ /// ID of the sender of the item
+ ///
+ ///
+ /// The id of the receipient folder in which the send folder should be placed. If UUID.Zero then the
+ /// recipient folder is the root folder
+ ///
+ ///
+ /// The inventory folder copy given, null if the copy was unsuccessful
+ ///
+ public virtual InventoryFolderImpl GiveInventoryFolder(
+ UUID recipientId, UUID senderId, UUID folderId, UUID recipientParentFolderId)
+ {
+ // Retrieve the folder from the sender
+ CachedUserInfo senderUserInfo = CommsManager.UserProfileCacheService.GetUserDetails(senderId);
+
+ if (null == senderUserInfo)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to find sending user {0} for folder {1}", senderId, folderId);
+
+ return null;
+ }
+
+ if (!senderUserInfo.HasReceivedInventory)
+ {
+ m_log.DebugFormat(
+ "[AGENT INVENTORY]: Could not give inventory folder - have not yet received inventory for {0}",
+ senderId);
+
+ return null;
+ }
+
+ InventoryFolderImpl folder = senderUserInfo.RootFolder.FindFolder(folderId);
+
+ if (null == folder)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find inventory folder {0} to give", folderId);
+
+ return null;
+ }
+
+ CachedUserInfo recipientUserInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(recipientId);
+
+ if (null == recipientUserInfo)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to find receiving user {0} for folder {1}", recipientId, folderId);
+
+ return null;
+ }
+
+ if (recipientParentFolderId == UUID.Zero)
+ recipientParentFolderId = recipientUserInfo.RootFolder.ID;
+
+ UUID newFolderId = UUID.Random();
+ recipientUserInfo.CreateFolder(folder.Name, newFolderId, (ushort)folder.Type, recipientParentFolderId);
+
+ // XXX: Messy - we should really get this back in the CreateFolder call
+ InventoryFolderImpl copiedFolder = recipientUserInfo.RootFolder.FindFolder(newFolderId);
+
+ // Give all the subfolders
+ List subFolders = folder.RequestListOfFolderImpls();
+ foreach (InventoryFolderImpl childFolder in subFolders)
+ {
+ GiveInventoryFolder(recipientId, senderId, childFolder.ID, copiedFolder.ID);
+ }
+
+ // Give all the items
+ List items = folder.RequestListOfItems();
+ foreach (InventoryItemBase item in items)
+ {
+ GiveInventoryItem(recipientId, senderId, item.ID, copiedFolder.ID);
+ }
+
+ return copiedFolder;
+ }
+
+ public void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID,
+ UUID newFolderID, string newName)
+ {
+ m_log.DebugFormat(
+ "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}",
+ remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName);
+
+ InventoryItemBase item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(oldItemID);
+
+ if (item == null)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID);
+ if (userInfo == null)
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find user " + oldAgentID.ToString());
+ return;
+ }
+
+ if (userInfo.RootFolder != null)
+ {
+ item = userInfo.RootFolder.FindItem(oldItemID);
+
+ if (item == null)
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
+ return;
+ }
+ }
+ else
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
+ return;
+ }
+ }
+
+ AssetBase asset
+ = AssetCache.GetAsset(
+ item.AssetID, (item.AssetType == (int)AssetType.Texture ? true : false));
+
+ if (asset != null)
+ {
+ if (newName != String.Empty)
+ {
+ asset.Metadata.Name = newName;
+ }
+ else
+ {
+ newName = item.Name;
+ }
+
+ if (remoteClient.AgentId == oldAgentID)
+ {
+ CreateNewInventoryItem(
+ remoteClient, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
+ item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
+ }
+ else
+ {
+ CreateNewInventoryItem(
+ remoteClient, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
+ item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
+ item.Name, item.AssetID);
+ }
+ }
+
+ ///
+ /// Create a new asset data structure.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data)
+ {
+ AssetBase asset = new AssetBase();
+ asset.Metadata.Name = name;
+ asset.Metadata.Description = description;
+ asset.Metadata.Type = assetType;
+ asset.Metadata.FullID = UUID.Random();
+ asset.Data = (data == null) ? new byte[1] : data;
+
+ return asset;
+ }
+
+ ///
+ /// Move an item within the agent's inventory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void MoveInventoryItem(IClientAPI remoteClient, UUID folderID, UUID itemID, int length,
+ string newName)
+ {
+ m_log.DebugFormat(
+ "[AGENT INVENTORY]: Moving item {0} to {1} for {2}", itemID, folderID, remoteClient.AgentId);
+
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo == null)
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
+
+ return;
+ }
+
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ if (newName != String.Empty)
+ {
+ item.Name = newName;
+ }
+ item.Folder = folderID;
+
+ userInfo.DeleteItem(item.ID);
+
+ AddInventoryItem(remoteClient, item);
+ }
+ else
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString());
+
+ return;
+ }
+ }
+ else
+ {
+ m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString() + ", no root folder");
+
+ return;
+ }
+ }
+
+ ///
+ /// Create a new inventory item.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void CreateNewInventoryItem(IClientAPI remoteClient, UUID folderID, string name, uint flags, uint callbackID,
+ AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
+ {
+ CreateNewInventoryItem(
+ remoteClient, folderID, name, flags, callbackID, asset, invType,
+ (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
+ }
+
+ ///
+ /// Create a new Inventory Item
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void CreateNewInventoryItem(
+ IClientAPI remoteClient, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
+ uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null)
+ {
+ InventoryItemBase item = new InventoryItemBase();
+ item.Owner = remoteClient.AgentId;
+ item.Creator = remoteClient.AgentId;
+ item.ID = UUID.Random();
+ item.AssetID = asset.Metadata.FullID;
+ item.Description = asset.Metadata.Description;
+ item.Name = name;
+ item.Flags = flags;
+ item.AssetType = asset.Metadata.Type;
+ item.InvType = invType;
+ item.Folder = folderID;
+ item.CurrentPermissions = currentMask;
+ item.NextPermissions = nextOwnerMask;
+ item.EveryOnePermissions = everyoneMask;
+ item.GroupPermissions = groupMask;
+ item.BasePermissions = baseMask;
+ item.CreationDate = creationDate;
+
+ userInfo.AddItem(item);
+ remoteClient.SendInventoryItemCreateUpdate(item);
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "No user details associated with client {0} uuid {1} in CreateNewInventoryItem!",
+ remoteClient.Name, remoteClient.AgentId);
+ }
+ }
+
+ ///
+ /// Create a new inventory item. Called when the client creates a new item directly within their
+ /// inventory (e.g. by selecting a context inventory menu option).
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
+ uint callbackID, string description, string name, sbyte invType,
+ sbyte assetType,
+ byte wearableType, uint nextOwnerMask, int creationDate)
+ {
+ m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
+
+ if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
+ return;
+
+ if (transactionID == UUID.Zero)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null)
+ {
+ ScenePresence presence;
+ TryGetAvatar(remoteClient.AgentId, out presence);
+ byte[] data = null;
+
+ if (invType == 3 && presence != null) // OpenMetaverse.asset.assettype.landmark = 3 - needs to be turned into an enum
+ {
+ Vector3 pos = presence.AbsolutePosition;
+ string strdata = String.Format(
+ "Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
+ presence.Scene.RegionInfo.RegionID,
+ pos.X, pos.Y, pos.Z,
+ presence.RegionHandle);
+ data = Encoding.ASCII.GetBytes(strdata);
+ }
+
+ AssetBase asset = CreateAsset(name, description, assetType, data);
+ AssetCache.AddAsset(asset);
+
+ CreateNewInventoryItem(remoteClient, folderID, asset.Metadata.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "userInfo for agent uuid {0} unexpectedly null in CreateNewInventoryItem",
+ remoteClient.AgentId);
+ }
+ }
+ else
+ {
+ IAgentAssetTransactions agentTransactions = this.RequestModuleInterface();
+ if (agentTransactions != null)
+ {
+ agentTransactions.HandleItemCreationFromTransaction(
+ remoteClient, transactionID, folderID, callbackID, description,
+ name, invType, assetType, wearableType, nextOwnerMask);
+ }
+ }
+ }
+
+ ///
+ /// Remove an inventory item for the client's inventory
+ ///
+ ///
+ ///
+ private void RemoveInventoryItem(IClientAPI remoteClient, UUID itemID)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo == null)
+ {
+ m_log.WarnFormat(
+ "[AGENT INVENTORY]: Failed to find user {0} {1} to delete inventory item {2}",
+ remoteClient.Name, remoteClient.AgentId, itemID);
+
+ return;
+ }
+
+ userInfo.DeleteItem(itemID);
+ }
+
+ ///
+ /// Removes an inventory folder. Although there is a packet in the Linden protocol for this, it may be
+ /// legacy and not currently used (purge folder is used to remove folders from trash instead).
+ ///
+ ///
+ ///
+ private void RemoveInventoryFolder(IClientAPI remoteClient, UUID folderID)
+ {
+ CachedUserInfo userInfo
+ = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo == null)
+ {
+ m_log.Warn("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
+ return;
+ }
+
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase folder = userInfo.RootFolder.FindItem(folderID);
+
+ if (folder != null)
+ {
+ m_log.WarnFormat(
+ "[AGENT INVENTORY]: Remove folder not implemented in request by {0} {1} for {2}",
+ remoteClient.Name, remoteClient.AgentId, folderID);
+
+ // doesn't work just yet, commented out. will fix in next patch.
+ // userInfo.DeleteItem(folder);
+ }
+ }
+ }
+
+ private SceneObjectGroup GetGroupByPrim(uint localID)
+ {
+ List EntityList = GetEntities();
+
+ foreach (EntityBase ent in EntityList)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ if (((SceneObjectGroup) ent).HasChildPrim(localID))
+ return (SceneObjectGroup) ent;
+ }
+ }
+ return null;
+ }
+
+ ///
+ /// Send the details of a prim's inventory to the client.
+ ///
+ ///
+ ///
+ public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID)
+ {
+ SceneObjectGroup group = GetGroupByPrim(primLocalID);
+ if (group != null)
+ {
+ bool fileChange = group.GetPartInventoryFileName(remoteClient, primLocalID);
+ if (fileChange)
+ {
+ if (XferManager != null)
+ {
+ group.RequestInventoryFile(remoteClient, primLocalID, XferManager);
+ }
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID);
+ }
+ }
+
+ ///
+ /// Remove an item from a prim (task) inventory
+ ///
+ /// Unused at the moment but retained since the avatar ID might
+ /// be necessary for a permissions check at some stage.
+ ///
+ ///
+ public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ SceneObjectGroup group = part.ParentGroup;
+ if (group != null)
+ {
+ TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
+ if (item == null)
+ return;
+
+ if (item.Type == 10)
+ {
+ EventManager.TriggerRemoveScript(localID, itemID);
+ }
+ group.RemoveInventoryItem(localID, itemID);
+ part.GetProperties(remoteClient);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Removal of item {0} requested of prim {1} but this prim does not exist",
+ itemID,
+ localID);
+ }
+ }
+
+ private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
+ {
+ TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
+
+ if (null == taskItem)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for creating an avatar"
+ + " inventory item from a prim's inventory item "
+ + " but the required item does not exist in the prim's inventory",
+ itemId, part.Name, part.UUID);
+
+ return null;
+ }
+
+ if ((destAgent != taskItem.OwnerID) && ((taskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
+ {
+ return null;
+ }
+
+ InventoryItemBase agentItem = new InventoryItemBase();
+
+ agentItem.ID = UUID.Random();
+ agentItem.Creator = taskItem.CreatorID;
+ agentItem.Owner = destAgent;
+ agentItem.AssetID = taskItem.AssetID;
+ agentItem.Description = taskItem.Description;
+ agentItem.Name = taskItem.Name;
+ agentItem.AssetType = taskItem.Type;
+ agentItem.InvType = taskItem.InvType;
+ agentItem.Flags = taskItem.Flags;
+
+ if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
+ {
+ if (taskItem.InvType == 6)
+ agentItem.BasePermissions = taskItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13);
+ else
+ agentItem.BasePermissions = taskItem.BasePermissions;
+ agentItem.BasePermissions &= taskItem.NextPermissions;
+ agentItem.CurrentPermissions = agentItem.BasePermissions | 8;
+ agentItem.NextPermissions = taskItem.NextPermissions;
+ agentItem.EveryOnePermissions = taskItem.EveryonePermissions & taskItem.NextPermissions;
+ agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
+ }
+ else
+ {
+ agentItem.BasePermissions = taskItem.BasePermissions;
+ agentItem.CurrentPermissions = taskItem.CurrentPermissions;
+ agentItem.NextPermissions = taskItem.NextPermissions;
+ agentItem.EveryOnePermissions = taskItem.EveryonePermissions;
+ agentItem.GroupPermissions = taskItem.GroupPermissions;
+ }
+
+ if (!Permissions.BypassPermissions())
+ {
+ if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ part.Inventory.RemoveInventoryItem(itemId);
+ }
+
+ return agentItem;
+ }
+
+ ///
+ /// Move the given item in the given prim to a folder in the client's inventory
+ ///
+ ///
+ ///
+ ///
+ ///
+ public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId)
+ {
+ InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId);
+
+ if (agentItem == null)
+ return null;
+
+ agentItem.Folder = folderId;
+ AddInventoryItem(remoteClient, agentItem);
+ return agentItem;
+ }
+
+ ///
+ /// ClientMoveTaskInventoryItem
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void ClientMoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, uint primLocalId, UUID itemId)
+ {
+ SceneObjectPart part = GetSceneObjectPart(primLocalId);
+
+ if (null == part)
+ {
+ m_log.WarnFormat(
+ "[PRIM INVENTORY]: " +
+ "Move of inventory item {0} from prim with local id {1} failed because the prim could not be found",
+ itemId, primLocalId);
+
+ return;
+ }
+
+ TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
+
+ if (null == taskItem)
+ {
+ m_log.WarnFormat("[PRIM INVENTORY]: Move of inventory item {0} from prim with local id {1} failed"
+ + " because the inventory item could not be found",
+ itemId, primLocalId);
+
+ return;
+ }
+
+ // Only owner can copy
+ if (remoteClient.AgentId != taskItem.OwnerID)
+ return;
+
+ MoveTaskInventoryItem(remoteClient, folderId, part, itemId);
+ }
+
+ ///
+ /// MoveTaskInventoryItem
+ ///
+ ///
+ ///
+ ///
+ ///
+ public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId)
+ {
+ ScenePresence avatar;
+
+ if (TryGetAvatar(avatarId, out avatar))
+ {
+ return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId);
+ }
+ else
+ {
+ CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(avatarId);
+ if (profile == null || profile.RootFolder == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Avatar {0} cannot be found to add item",
+ avatarId);
+ }
+ if (!profile.HasReceivedInventory)
+ CommsManager.UserProfileCacheService.RequestInventoryForUser(avatarId);
+ InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(avatarId, part, itemId);
+
+ if (agentItem == null)
+ return null;
+
+ agentItem.Folder = folderId;
+
+ AddInventoryItem(avatarId, agentItem);
+
+ return agentItem;
+ }
+ }
+
+ ///
+ /// Copy a task (prim) inventory item to another task (prim)
+ ///
+ ///
+ ///
+ ///
+ public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId)
+ {
+ TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId);
+
+ if (srcTaskItem == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving"
+ + " but the item does not exist in this inventory",
+ itemId, part.Name, part.UUID);
+
+ return;
+ }
+
+ SceneObjectPart destPart = GetSceneObjectPart(destId);
+
+ if (destPart == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Could not find prim for ID {0}",
+ destId);
+ return;
+ }
+
+ // Can't transfer this
+ //
+ if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0))
+ return;
+
+ if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0)
+ {
+ // object cannot copy items to an object owned by a different owner
+ // unless llAllowInventoryDrop has been called
+
+ return;
+ }
+
+ // must have both move and modify permission to put an item in an object
+ if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0)
+ {
+ return;
+ }
+
+ TaskInventoryItem destTaskItem = new TaskInventoryItem();
+
+ destTaskItem.ItemID = UUID.Random();
+ destTaskItem.CreatorID = srcTaskItem.CreatorID;
+ destTaskItem.AssetID = srcTaskItem.AssetID;
+ destTaskItem.GroupID = destPart.GroupID;
+ destTaskItem.OwnerID = destPart.OwnerID;
+ destTaskItem.ParentID = destPart.UUID;
+ destTaskItem.ParentPartID = destPart.UUID;
+
+ destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
+ destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
+ destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
+ destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
+ destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
+ destTaskItem.Flags = srcTaskItem.Flags;
+
+ if (destPart.OwnerID != part.OwnerID)
+ {
+ if (Permissions.PropagatePermissions())
+ {
+ destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.CurrentPermissions |= 8; // Slam!
+ }
+ }
+
+ destTaskItem.Description = srcTaskItem.Description;
+ destTaskItem.Name = srcTaskItem.Name;
+ destTaskItem.InvType = srcTaskItem.InvType;
+ destTaskItem.Type = srcTaskItem.Type;
+
+ destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID);
+
+ if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ part.Inventory.RemoveInventoryItem(itemId);
+
+ ScenePresence avatar;
+
+ if (TryGetAvatar(srcTaskItem.OwnerID, out avatar))
+ {
+ destPart.GetProperties(avatar.ControllingClient);
+ }
+ }
+
+ public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List items)
+ {
+ CachedUserInfo profile = CommsManager.UserProfileCacheService.GetUserDetails(destID);
+ if (profile == null || profile.RootFolder == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Avatar {0} cannot be found to add items",
+ destID);
+ return UUID.Zero;
+ }
+
+ UUID newFolderID = UUID.Random();
+
+ profile.CreateFolder(category, newFolderID, 0xffff, profile.RootFolder.ID);
+
+ foreach (UUID itemID in items)
+ {
+ InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(destID, host, itemID);
+
+ if (agentItem != null)
+ {
+ agentItem.Folder = newFolderID;
+
+ AddInventoryItem(destID, agentItem);
+ }
+ }
+
+ ScenePresence avatar;
+
+ if (TryGetAvatar(destID, out avatar))
+ {
+ profile.SendInventoryDecendents(avatar.ControllingClient,
+ profile.RootFolder.ID, true, false);
+ profile.SendInventoryDecendents(avatar.ControllingClient,
+ newFolderID, false, true);
+ }
+
+ return newFolderID;
+ }
+
+ ///
+ /// Update an item in a prim (task) inventory.
+ /// This method does not handle scripts, RezScript(IClientAPI, UUID, unit)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo,
+ uint primLocalID)
+ {
+ UUID itemID = itemInfo.ItemID;
+
+ // Find the prim we're dealing with
+ SceneObjectPart part = GetSceneObjectPart(primLocalID);
+
+ if (part != null)
+ {
+ TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID);
+ bool allowInventoryDrop = (part.GetEffectiveObjectFlags()
+ & (uint)PrimFlags.AllowInventoryDrop) != 0;
+
+ // Explicity allow anyone to add to the inventory if the
+ // AllowInventoryDrop flag has been set. Don't however let
+ // them update an item unless they pass the external checks
+ //
+ if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)
+ && (currentItem != null || !allowInventoryDrop))
+ return;
+
+ if (currentItem == null)
+ {
+ UUID copyID = UUID.Random();
+ if (itemID != UUID.Zero)
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null && userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ // Try library
+ // XXX clumsy, possibly should be one call
+ if (null == item)
+ {
+ item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID);
+ }
+
+ if (item != null)
+ {
+ part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID);
+ m_log.InfoFormat(
+ "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
+ item.Name, primLocalID, remoteClient.Name);
+ part.GetProperties(remoteClient);
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ RemoveInventoryItem(remoteClient, itemID);
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!",
+ itemID, remoteClient.Name);
+ }
+ }
+ }
+ }
+ else // Updating existing item with new perms etc
+ {
+ IAgentAssetTransactions agentTransactions = this.RequestModuleInterface();
+ if (agentTransactions != null)
+ {
+ agentTransactions.HandleTaskItemUpdateFromTransaction(
+ remoteClient, part, transactionID, currentItem);
+ }
+ if (part.Inventory.UpdateInventoryItem(itemInfo))
+ part.GetProperties(remoteClient);
+ }
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "[PRIM INVENTORY]: " +
+ "Update with item {0} requested of prim {1} for {2} but this prim does not exist",
+ itemID, primLocalID, remoteClient.Name);
+ }
+ }
+
+ ///
+ /// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory
+ ///
+ ///
+ ///
+ ///
+ public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
+ {
+ UUID itemID = itemBase.ID;
+ UUID copyID = UUID.Random();
+
+ if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory
+ {
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (userInfo != null && userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ // Try library
+ // XXX clumsy, possibly should be one call
+ if (null == item)
+ {
+ item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID);
+ }
+
+ if (item != null)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ if (part != null)
+ {
+ if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
+ return;
+
+ part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID);
+ // TODO: switch to posting on_rez here when scripts
+ // have state in inventory
+ part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
+
+ // m_log.InfoFormat("[PRIMINVENTORY]: " +
+ // "Rezzed script {0} into prim local ID {1} for user {2}",
+ // item.inventoryName, localID, remoteClient.Name);
+ part.GetProperties(remoteClient);
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Could not rez script {0} into prim local ID {1} for user {2}"
+ + " because the prim could not be found in the region!",
+ item.Name, localID, remoteClient.Name);
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
+ itemID, remoteClient.Name);
+ }
+ }
+ }
+ else // script has been rezzed directly into a prim's inventory
+ {
+ SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
+ if (part == null)
+ return;
+
+ if (part.OwnerID != remoteClient.AgentId)
+ return;
+
+ if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
+ return;
+
+ if (!Permissions.CanCreateObjectInventory(
+ itemBase.InvType, part.UUID, remoteClient.AgentId))
+ return;
+
+ AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"));
+ AssetCache.AddAsset(asset);
+
+ TaskInventoryItem taskItem = new TaskInventoryItem();
+
+ taskItem.ResetIDs(itemBase.Folder);
+ taskItem.ParentID = itemBase.Folder;
+ taskItem.CreationDate = (uint)itemBase.CreationDate;
+ taskItem.Name = itemBase.Name;
+ taskItem.Description = itemBase.Description;
+ taskItem.Type = itemBase.AssetType;
+ taskItem.InvType = itemBase.InvType;
+ taskItem.OwnerID = itemBase.Owner;
+ taskItem.CreatorID = itemBase.Creator;
+ taskItem.BasePermissions = itemBase.BasePermissions;
+ taskItem.CurrentPermissions = itemBase.CurrentPermissions;
+ taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
+ taskItem.GroupPermissions = itemBase.GroupPermissions;
+ taskItem.NextPermissions = itemBase.NextPermissions;
+ taskItem.GroupID = itemBase.GroupID;
+ taskItem.GroupPermissions = 0;
+ taskItem.Flags = itemBase.Flags;
+ taskItem.PermsGranter = UUID.Zero;
+ taskItem.PermsMask = 0;
+ taskItem.AssetID = asset.Metadata.FullID;
+
+ part.Inventory.AddInventoryItem(taskItem, false);
+ part.GetProperties(remoteClient);
+
+ part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
+ }
+ }
+
+ ///
+ /// Rez a script into a prim's inventory from another prim
+ ///
+ ///
+ ///
+ ///
+ public void RezScript(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
+ {
+ TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
+
+ if (srcTaskItem == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for rezzing a script but the "
+ + " item does not exist in this inventory",
+ srcId, srcPart.Name, srcPart.UUID);
+
+ return;
+ }
+
+ SceneObjectPart destPart = GetSceneObjectPart(destId);
+
+ if (destPart == null)
+ {
+ m_log.ErrorFormat(
+ "[PRIM INVENTORY]: " +
+ "Could not find script for ID {0}",
+ destId);
+ return;
+ }
+
+ // Must own the object, and have modify rights
+ if (srcPart.OwnerID != destPart.OwnerID)
+ return;
+
+ if ((destPart.OwnerMask & (uint)PermissionMask.Modify) == 0)
+ return;
+
+ if (destPart.ScriptAccessPin != pin)
+ {
+ m_log.WarnFormat(
+ "[PRIM INVENTORY]: " +
+ "Script in object {0} : {1}, attempted to load script {2} : {3} into object {4} : {5} with invalid pin {6}",
+ srcPart.Name, srcId, srcTaskItem.Name, srcTaskItem.ItemID, destPart.Name, destId, pin);
+ // the LSL Wiki says we are supposed to shout on the DEBUG_CHANNEL -
+ // "Object: Task Object trying to illegally load script onto task Other_Object!"
+ // How do we shout from in here?
+ return;
+ }
+
+ TaskInventoryItem destTaskItem = new TaskInventoryItem();
+
+ destTaskItem.ItemID = UUID.Random();
+ destTaskItem.CreatorID = srcTaskItem.CreatorID;
+ destTaskItem.AssetID = srcTaskItem.AssetID;
+ destTaskItem.GroupID = destPart.GroupID;
+ destTaskItem.OwnerID = destPart.OwnerID;
+ destTaskItem.ParentID = destPart.UUID;
+ destTaskItem.ParentPartID = destPart.UUID;
+
+ destTaskItem.BasePermissions = srcTaskItem.BasePermissions;
+ destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions;
+ destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions;
+ destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions;
+ destTaskItem.NextPermissions = srcTaskItem.NextPermissions;
+ destTaskItem.Flags = srcTaskItem.Flags;
+
+ if (destPart.OwnerID != srcPart.OwnerID)
+ {
+ if (Permissions.PropagatePermissions())
+ {
+ destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
+ srcTaskItem.NextPermissions;
+ destTaskItem.CurrentPermissions |= 8; // Slam!
+ }
+ }
+
+ destTaskItem.Description = srcTaskItem.Description;
+ destTaskItem.Name = srcTaskItem.Name;
+ destTaskItem.InvType = srcTaskItem.InvType;
+ destTaskItem.Type = srcTaskItem.Type;
+
+ destPart.Inventory.AddInventoryItemExclusive(destTaskItem, false);
+
+ if (running > 0)
+ {
+ destPart.Inventory.CreateScriptInstance(destTaskItem, 0, false, DefaultScriptEngine, 0);
+ }
+
+ ScenePresence avatar;
+
+ if (TryGetAvatar(srcTaskItem.OwnerID, out avatar))
+ {
+ destPart.GetProperties(avatar.ControllingClient);
+ }
+ }
+
+ ///
+ /// Called when an object is removed from the environment into inventory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
+ UUID groupID, DeRezAction action, UUID destinationID)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ if (part == null)
+ return;
+
+ if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
+ return;
+
+ // Can't delete child prims
+ if (part != part.ParentGroup.RootPart)
+ return;
+
+ SceneObjectGroup grp = part.ParentGroup;
+
+ //force a database backup/update on this SceneObjectGroup
+ //So that we know the database is upto date, for when deleting the object from it
+ ForceSceneObjectBackup(grp);
+
+ bool permissionToTake = false;
+ bool permissionToDelete = false;
+
+ if (action == DeRezAction.SaveToExistingUserInventoryItem)
+ {
+ if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero)
+ {
+ permissionToTake = true;
+ permissionToDelete = false;
+ }
+ }
+ else if (action == DeRezAction.TakeCopy)
+ {
+ permissionToTake =
+ Permissions.CanTakeCopyObject(
+ grp.UUID,
+ remoteClient.AgentId);
+ }
+ else if (action == DeRezAction.GodTakeCopy)
+ {
+ permissionToTake =
+ Permissions.IsGod(
+ remoteClient.AgentId);
+ }
+ else if (action == DeRezAction.Take)
+ {
+ permissionToTake =
+ Permissions.CanTakeObject(
+ grp.UUID,
+ remoteClient.AgentId);
+
+ //If they can take, they can delete!
+ permissionToDelete = permissionToTake;
+ }
+ else if (action == DeRezAction.Delete)
+ {
+ permissionToTake =
+ Permissions.CanDeleteObject(
+ grp.UUID,
+ remoteClient.AgentId);
+ permissionToDelete = permissionToTake;
+ }
+ else if (action == DeRezAction.Return)
+ {
+ if (remoteClient != null)
+ {
+ permissionToTake =
+ Permissions.CanReturnObject(
+ grp.UUID,
+ remoteClient.AgentId);
+ permissionToDelete = permissionToTake;
+
+ if (permissionToDelete)
+ {
+ AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
+ }
+ }
+ else // Auto return passes through here with null agent
+ {
+ permissionToTake = true;
+ permissionToDelete = true;
+ }
+ }
+ else
+ {
+ m_log.DebugFormat(
+ "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name);
+ return;
+ }
+
+ if (permissionToTake)
+ {
+ m_asyncSceneObjectDeleter.DeleteToInventory(
+ action, destinationID, grp, remoteClient,
+ permissionToDelete);
+ }
+ else if (permissionToDelete)
+ {
+ DeleteSceneObject(grp, false);
+ }
+ }
+
+ private bool WaitForInventory(CachedUserInfo info)
+ {
+ // 200 Seconds wait. This is called in the context of the
+ // background delete thread, so we can afford to waste time
+ // here.
+ //
+ int count = 200;
+
+ while (count > 0)
+ {
+ System.Threading.Thread.Sleep(100);
+ count--;
+ if (info.HasReceivedInventory)
+ return true;
+ }
+ m_log.DebugFormat("Timed out waiting for inventory of user {0}",
+ info.UserProfile.ID.ToString());
+ return false;
+ }
+
+ ///
+ /// Delete a scene object from a scene and place in the given avatar's inventory.
+ /// Returns the UUID of the newly created asset.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
+ SceneObjectGroup objectGroup, IClientAPI remoteClient)
+ {
+ UUID assetID = UUID.Zero;
+
+ string sceneObjectXml = objectGroup.ToXmlString();
+
+ // Get the user info of the item destination
+ //
+ CachedUserInfo userInfo;
+
+ if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
+ action == DeRezAction.SaveToExistingUserInventoryItem)
+ {
+ // Take or take copy require a taker
+ // Saving changes requires a local user
+ //
+ if (remoteClient == null)
+ return UUID.Zero;
+
+ userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
+ remoteClient.AgentId);
+ }
+ else
+ {
+ // All returns / deletes go to the object owner
+ //
+ userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
+ objectGroup.RootPart.OwnerID);
+ }
+
+ if (userInfo == null) // Can't proceed
+ {
+ return UUID.Zero;
+ }
+
+ if (!userInfo.HasReceivedInventory)
+ {
+ // Async inventory requests will queue, but they will never
+ // execute unless inventory is actually fetched
+ //
+ CommsManager.UserProfileCacheService.RequestInventoryForUser(
+ userInfo.UserProfile.ID);
+ }
+
+ if (userInfo != null)
+ {
+ // If we're returning someone's item, it goes back to the
+ // owner's Lost And Found folder.
+ // Delete is treated like return in this case
+ // Deleting your own items makes them go to trash
+ //
+
+ InventoryFolderBase folder = null;
+ InventoryItemBase item = null;
+
+ if (DeRezAction.SaveToExistingUserInventoryItem == action)
+ {
+ item = userInfo.RootFolder.FindItem(
+ objectGroup.RootPart.FromUserInventoryItemID);
+
+ if (null == item)
+ {
+ m_log.DebugFormat(
+ "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
+ objectGroup.Name, objectGroup.UUID);
+ return UUID.Zero;
+ }
+ }
+ else
+ {
+ // Folder magic
+ //
+ if (action == DeRezAction.Delete)
+ {
+ // Deleting someone else's item
+ //
+ if (remoteClient == null ||
+ objectGroup.OwnerID != remoteClient.AgentId)
+ {
+ // Folder skeleton may not be loaded and we
+ // have to wait for the inventory to find
+ // the destination folder
+ //
+ if (!WaitForInventory(userInfo))
+ return UUID.Zero;
+ folder = userInfo.FindFolderForType(
+ (int)AssetType.LostAndFoundFolder);
+ }
+ else
+ {
+ // Assume inventory skeleton was loaded during login
+ // and all folders can be found
+ //
+ folder = userInfo.FindFolderForType(
+ (int)AssetType.TrashFolder);
+ }
+ }
+ else if (action == DeRezAction.Return)
+ {
+ // Wait if needed
+ //
+ if (!userInfo.HasReceivedInventory)
+ {
+ if (!WaitForInventory(userInfo))
+ return UUID.Zero;
+ }
+
+ // Dump to lost + found unconditionally
+ //
+ folder = userInfo.FindFolderForType(
+ (int)AssetType.LostAndFoundFolder);
+ }
+
+ if (folderID == UUID.Zero && folder == null)
+ {
+ // Catch all. Use lost & found
+ //
+ if (!userInfo.HasReceivedInventory)
+ {
+ if (!WaitForInventory(userInfo))
+ return UUID.Zero;
+ }
+
+ folder = userInfo.FindFolderForType(
+ (int)AssetType.LostAndFoundFolder);
+ }
+
+ if (folder == null) // None of the above
+ {
+ folder = userInfo.RootFolder.FindFolder(folderID);
+
+ if (folder == null) // Nowhere to put it
+ {
+ return UUID.Zero;
+ }
+ }
+
+ item = new InventoryItemBase();
+ item.Creator = objectGroup.RootPart.CreatorID;
+ item.ID = UUID.Random();
+ item.InvType = (int)InventoryType.Object;
+ item.Folder = folder.ID;
+ item.Owner = userInfo.UserProfile.ID;
+
+ }
+
+ AssetBase asset = CreateAsset(
+ objectGroup.GetPartName(objectGroup.RootPart.LocalId),
+ objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
+ (sbyte)AssetType.Object,
+ Utils.StringToBytes(sceneObjectXml));
+ AssetCache.AddAsset(asset);
+ assetID = asset.Metadata.FullID;
+
+ if (DeRezAction.SaveToExistingUserInventoryItem == action)
+ {
+ item.AssetID = asset.Metadata.FullID;
+ userInfo.UpdateItem(item);
+ }
+ else
+ {
+ item.AssetID = asset.Metadata.FullID;
+
+ if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions())
+ {
+ uint perms=objectGroup.GetEffectivePermissions();
+ uint nextPerms=(perms & 7) << 13;
+ if ((nextPerms & (uint)PermissionMask.Copy) == 0)
+ perms &= ~(uint)PermissionMask.Copy;
+ if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
+ perms &= ~(uint)PermissionMask.Transfer;
+ if ((nextPerms & (uint)PermissionMask.Modify) == 0)
+ perms &= ~(uint)PermissionMask.Modify;
+
+ item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
+ item.CurrentPermissions = item.BasePermissions;
+ item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
+ item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
+ item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
+ item.CurrentPermissions |= 8; // Slam!
+ }
+ else
+ {
+ item.BasePermissions = objectGroup.GetEffectivePermissions();
+ item.CurrentPermissions = objectGroup.GetEffectivePermissions();
+ item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
+ item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
+ item.GroupPermissions = objectGroup.RootPart.GroupMask;
+
+ item.CurrentPermissions |= 8; // Slam!
+ }
+
+ // TODO: add the new fields (Flags, Sale info, etc)
+ item.CreationDate = Util.UnixTimeSinceEpoch();
+ item.Description = asset.Metadata.Description;
+ item.Name = asset.Metadata.Name;
+ item.AssetType = asset.Metadata.Type;
+
+ userInfo.AddItem(item);
+
+ if (remoteClient != null && item.Owner == remoteClient.AgentId)
+ {
+ remoteClient.SendInventoryItemCreateUpdate(item);
+ }
+ else
+ {
+ ScenePresence notifyUser = GetScenePresence(item.Owner);
+ if (notifyUser != null)
+ {
+ notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item);
+ }
+ }
+ }
+ }
+
+ return assetID;
+ }
+
+ public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID)
+ {
+ SceneObjectGroup objectGroup = grp;
+ if (objectGroup != null)
+ {
+ if (!grp.HasGroupChanged)
+ {
+ m_log.InfoFormat("[ATTACHMENT]: Save request for {0} which is unchanged", grp.UUID);
+ return;
+ }
+
+ m_log.InfoFormat(
+ "[ATTACHMENT]: Updating asset for attachment {0}, attachpoint {1}",
+ grp.UUID, grp.GetAttachmentPoint());
+
+ string sceneObjectXml = objectGroup.ToXmlString();
+
+ CachedUserInfo userInfo =
+ CommsManager.UserProfileCacheService.GetUserDetails(agentID);
+ if (userInfo != null && userInfo.RootFolder != null)
+ {
+ Queue searchfolders = new Queue();
+ searchfolders.Enqueue(userInfo.RootFolder);
+
+ UUID foundFolder = UUID.Zero;
+ InventoryItemBase item = null;
+
+ // search through folders to find the asset.
+ while (searchfolders.Count > 0)
+ {
+ InventoryFolderImpl fld = searchfolders.Dequeue();
+ lock (fld)
+ {
+ if (fld != null)
+ {
+ if (fld.Items.ContainsKey(assetID))
+ {
+ item = fld.Items[assetID];
+ foundFolder = fld.ID;
+ searchfolders.Clear();
+ break;
+ }
+ else
+ {
+ foreach (InventoryFolderImpl subfld in fld.RequestListOfFolderImpls())
+ {
+ searchfolders.Enqueue(subfld);
+ }
+ }
+ }
+ }
+ }
+
+ if (foundFolder != UUID.Zero && item != null)
+ {
+ AssetBase asset = CreateAsset(
+ objectGroup.GetPartName(objectGroup.LocalId),
+ objectGroup.GetPartDescription(objectGroup.LocalId),
+ (sbyte)AssetType.Object,
+ Utils.StringToBytes(sceneObjectXml));
+ AssetCache.AddAsset(asset);
+
+ item.AssetID = asset.Metadata.FullID;
+ item.Description = asset.Metadata.Description;
+ item.Name = asset.Metadata.Name;
+ item.AssetType = asset.Metadata.Type;
+ item.InvType = (int)InventoryType.Object;
+ item.Folder = foundFolder;
+
+ userInfo.UpdateItem(item);
+
+ // this gets called when the agent loggs off!
+ if (remoteClient != null)
+ {
+ remoteClient.SendInventoryItemCreateUpdate(item);
+ }
+ }
+ }
+ }
+ }
+
+ public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
+ {
+ itemID = UUID.Zero;
+ if (grp != null)
+ {
+ string sceneObjectXml = grp.ToXmlString();
+
+ CachedUserInfo userInfo =
+ CommsManager.UserProfileCacheService.GetUserDetails(AgentId);
+ if (userInfo != null)
+ {
+ AssetBase asset = CreateAsset(
+ grp.GetPartName(grp.LocalId),
+ grp.GetPartDescription(grp.LocalId),
+ (sbyte)AssetType.Object,
+ Utils.StringToBytes(sceneObjectXml));
+ AssetCache.AddAsset(asset);
+
+ InventoryItemBase item = new InventoryItemBase();
+ item.Creator = grp.RootPart.CreatorID;
+ item.Owner = remoteClient.AgentId;
+ item.ID = UUID.Random();
+ item.AssetID = asset.Metadata.FullID;
+ item.Description = asset.Metadata.Description;
+ item.Name = asset.Metadata.Name;
+ item.AssetType = asset.Metadata.Type;
+ item.InvType = (int)InventoryType.Object;
+
+ item.Folder = UUID.Zero; // Objects folder!
+
+ if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions())
+ {
+ item.BasePermissions = grp.RootPart.NextOwnerMask;
+ item.CurrentPermissions = grp.RootPart.NextOwnerMask;
+ item.NextPermissions = grp.RootPart.NextOwnerMask;
+ item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
+ item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
+ }
+ else
+ {
+ item.BasePermissions = grp.RootPart.BaseMask;
+ item.CurrentPermissions = grp.RootPart.OwnerMask;
+ item.NextPermissions = grp.RootPart.NextOwnerMask;
+ item.EveryOnePermissions = grp.RootPart.EveryoneMask;
+ item.GroupPermissions = grp.RootPart.GroupMask;
+ }
+ item.CreationDate = Util.UnixTimeSinceEpoch();
+
+ // sets assetID so client can show asset as 'attached' in inventory
+ grp.SetFromAssetID(item.ID);
+
+ userInfo.AddItem(item);
+ remoteClient.SendInventoryItemCreateUpdate(item);
+
+ itemID = item.ID;
+ return item.AssetID;
+ }
+ return UUID.Zero;
+ }
+ return UUID.Zero;
+ }
+
+ ///
+ /// Event Handler Rez an object into a scene
+ /// Calls the non-void event handler
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public virtual void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID)
+ {
+ RezObject(
+ remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
+ RezSelected, RemoveItem, fromTaskID, false);
+ }
+
+ ///
+ /// Rez an object into the scene from the user's inventory
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The SceneObjectGroup rezzed or null if rez was unsuccessful.
+ public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
+ UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
+ bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
+ {
+ // Work out position details
+ byte bRayEndIsIntersection = (byte)0;
+
+ if (RayEndIsIntersection)
+ {
+ bRayEndIsIntersection = (byte)1;
+ }
+ else
+ {
+ bRayEndIsIntersection = (byte)0;
+ }
+
+ Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
+
+
+ Vector3 pos = GetNewRezLocation(
+ RayStart, RayEnd, RayTargetID, Quaternion.Identity,
+ BypassRayCast, bRayEndIsIntersection,true,scale, false);
+
+ // Rez object
+ CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+ if (userInfo != null)
+ {
+ // Do NOT use HasReceivedInventory here, this is called
+ // from within ItemReceive during login for attachments.
+ // Using HasReceivedInventory here will break attachment
+ // persistence!
+ //
+ if (userInfo.RootFolder != null)
+ {
+ InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ AssetBase rezAsset = AssetCache.GetAsset(item.AssetID, false);
+
+ if (rezAsset != null)
+ {
+ UUID itemId = UUID.Zero;
+
+ // If we have permission to copy then link the rezzed object back to the user inventory
+ // item that it came from. This allows us to enable 'save object to inventory'
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
+ {
+ itemId = item.ID;
+ }
+ }
+
+ string xmlData = Utils.BytesToString(rezAsset.Data);
+ SceneObjectGroup group = new SceneObjectGroup(itemId, xmlData, true);
+
+ if (!Permissions.CanRezObject(
+ group.Children.Count, remoteClient.AgentId, pos)
+ && !attachment)
+ {
+ return null;
+ }
+
+ group.ResetIDs();
+
+ AddNewSceneObject(group, true);
+
+ // if attachment we set it's asset id so object updates can reflect that
+ // if not, we set it's position in world.
+ if (!attachment)
+ {
+ pos = GetNewRezLocation(
+ RayStart, RayEnd, RayTargetID, Quaternion.Identity,
+ BypassRayCast, bRayEndIsIntersection, true, group.GroupScale(), false);
+ group.AbsolutePosition = pos;
+ }
+ else
+ {
+ group.SetFromAssetID(itemID);
+ }
+
+ SceneObjectPart rootPart = null;
+ try
+ {
+ rootPart = group.GetChildPart(group.UUID);
+ }
+ catch (NullReferenceException)
+ {
+ string isAttachment = "";
+
+ if (attachment)
+ isAttachment = " Object was an attachment";
+
+ m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
+ }
+
+ // Since renaming the item in the inventory does not affect the name stored
+ // in the serialization, transfer the correct name from the inventory to the
+ // object itself before we rez.
+ rootPart.Name = item.Name;
+ rootPart.Description = item.Description;
+
+ List partList = new List(group.Children.Values);
+
+ group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
+ if (rootPart.OwnerID != item.Owner)
+ {
+ //Need to kill the for sale here
+ rootPart.ObjectSaleType = 0;
+ rootPart.SalePrice = 10;
+
+ if (Permissions.PropagatePermissions())
+ {
+ if ((item.CurrentPermissions & 8) != 0)
+ {
+ foreach (SceneObjectPart part in partList)
+ {
+ part.EveryoneMask = item.EveryOnePermissions;
+ part.NextOwnerMask = item.NextPermissions;
+ part.GroupMask = 0; // DO NOT propagate here
+ }
+ }
+ group.ApplyNextOwnerPermissions();
+ }
+ }
+
+ foreach (SceneObjectPart part in partList)
+ {
+ if (part.OwnerID != item.Owner)
+ {
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = item.Owner;
+ part.Inventory.ChangeInventoryOwner(item.Owner);
+ }
+ else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
+ {
+ part.EveryoneMask = item.EveryOnePermissions;
+ part.NextOwnerMask = item.NextPermissions;
+
+ part.GroupMask = 0; // DO NOT propagate here
+ }
+ }
+
+ rootPart.TrimPermissions();
+
+ if (!attachment)
+ {
+ if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
+ {
+ group.ClearPartAttachmentData();
+ }
+ }
+
+ if (!attachment)
+ {
+ // Fire on_rez
+ group.CreateScriptInstances(0, true, DefaultScriptEngine, 0);
+
+ rootPart.ScheduleFullUpdate();
+ }
+
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ {
+ // If this is done on attachments, no
+ // copy ones will be lost, so avoid it
+ //
+ if (!attachment)
+ userInfo.DeleteItem(item.ID);
+ }
+ }
+
+ return rootPart.ParentGroup;
+ }
+ }
+ }
+ else
+ m_log.WarnFormat("[AGENT INVENTORY]: Root folder not found in {0}", RegionInfo.RegionName);
+ }
+ else
+ m_log.WarnFormat("[AGENT INVENTORY]: User profile not found in {0}", RegionInfo.RegionName);
+
+ return null;
+ }
+
+ ///
+ /// Rez an object into the scene from a prim's inventory.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The SceneObjectGroup rezzed or null if rez was unsuccessful
+ public virtual SceneObjectGroup RezObject(
+ SceneObjectPart sourcePart, TaskInventoryItem item,
+ Vector3 pos, Quaternion rot, Vector3 vel, int param)
+ {
+ // Rez object
+ if (item != null)
+ {
+ UUID ownerID = item.OwnerID;
+
+ AssetBase rezAsset = AssetCache.GetAsset(item.AssetID, false);
+
+ if (rezAsset != null)
+ {
+ string xmlData = Utils.BytesToString(rezAsset.Data);
+ SceneObjectGroup group = new SceneObjectGroup(xmlData, true);
+
+ if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos))
+ {
+ return null;
+ }
+ group.ResetIDs();
+
+ AddNewSceneObject(group, true);
+
+ // we set it's position in world.
+ group.AbsolutePosition = pos;
+
+ SceneObjectPart rootPart = group.GetChildPart(group.UUID);
+
+ // Since renaming the item in the inventory does not affect the name stored
+ // in the serialization, transfer the correct name from the inventory to the
+ // object itself before we rez.
+ rootPart.Name = item.Name;
+ rootPart.Description = item.Description;
+
+ List partList = new List(group.Children.Values);
+
+ group.SetGroup(sourcePart.GroupID, null);
+
+ if (rootPart.OwnerID != item.OwnerID)
+ {
+ if (Permissions.PropagatePermissions())
+ {
+ if ((item.CurrentPermissions & 8) != 0)
+ {
+ foreach (SceneObjectPart part in partList)
+ {
+ part.EveryoneMask = item.EveryonePermissions;
+ part.NextOwnerMask = item.NextPermissions;
+ }
+ }
+ group.ApplyNextOwnerPermissions();
+ }
+ }
+
+ foreach (SceneObjectPart part in partList)
+ {
+ if (part.OwnerID != item.OwnerID)
+ {
+ part.LastOwnerID = part.OwnerID;
+ part.OwnerID = item.OwnerID;
+ part.Inventory.ChangeInventoryOwner(item.OwnerID);
+ }
+ else if ((item.CurrentPermissions & 8) != 0) // Slam!
+ {
+ part.EveryoneMask = item.EveryonePermissions;
+ part.NextOwnerMask = item.NextPermissions;
+ }
+ }
+ rootPart.TrimPermissions();
+ if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
+ {
+ group.ClearPartAttachmentData();
+ }
+ group.UpdateGroupRotation(rot);
+ //group.ApplyPhysics(m_physicalPrim);
+ if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
+ {
+ group.RootPart.ApplyImpulse((vel * group.GetMass()), false);
+ group.Velocity = vel;
+ rootPart.ScheduleFullUpdate();
+ }
+ group.CreateScriptInstances(param, true, DefaultScriptEngine, 2);
+ rootPart.ScheduleFullUpdate();
+
+ if (!Permissions.BypassPermissions())
+ {
+ if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
+ sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
+ }
+ return rootPart.ParentGroup;
+ }
+ }
+
+ return null;
+ }
+
+ public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId)
+ {
+ foreach (SceneObjectGroup grp in returnobjects)
+ {
+ AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
+ DeRezObject(null, grp.RootPart.LocalId,
+ grp.RootPart.GroupID, DeRezAction.Return, UUID.Zero);
+ }
+
+ return true;
+ }
+
+ public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running)
+ {
+ SceneObjectPart part = GetSceneObjectPart(objectID);
+ if (part == null)
+ return;
+
+ if (running)
+ EventManager.TriggerStartScript(part.LocalId, itemID);
+ else
+ EventManager.TriggerStopScript(part.LocalId, itemID);
+ }
+
+ public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID,
+ uint AttachmentPt)
+ {
+ SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
+
+ if (att == null)
+ {
+ DetachSingleAttachmentToInv(itemID, remoteClient);
+ return UUID.Zero;
+ }
+
+ return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt);
+ }
+
+ public UUID RezSingleAttachment(SceneObjectGroup att,
+ IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
+ {
+ if (!att.IsDeleted)
+ AttachmentPt = att.RootPart.AttachmentPoint;
+
+ ScenePresence presence;
+ if (TryGetAvatar(remoteClient.AgentId, out presence))
+ {
+ presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID);
+ IAvatarFactory ava = RequestModuleInterface();
+ if (ava != null)
+ {
+ ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ }
+
+ }
+ return att.UUID;
+ }
+
+ public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
+ {
+ m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
+ }
+
+ public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
+ {
+ if (UUID.Zero == itemID)
+ {
+ m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
+ return;
+ }
+
+ if (0 == AttachmentPt)
+ {
+ m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error attachment point.");
+ return;
+ }
+
+ if (null == att.RootPart)
+ {
+ m_log.Error("[SCENE INVENTORY]: Unable to save attachment for a prim without the rootpart!");
+ return;
+ }
+
+ ScenePresence presence;
+ if (TryGetAvatar(remoteClient.AgentId, out presence))
+ {
+ presence.Appearance.SetAttachment((int)AttachmentPt, itemID, att.UUID);
+ IAvatarFactory ava = RequestModuleInterface();
+ if (ava != null)
+ {
+ m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt);
+ ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ }
+ }
+ }
+
+ public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient)
+ {
+ SceneObjectPart part = GetSceneObjectPart(itemID);
+ if (part == null || part.ParentGroup == null)
+ return;
+
+ UUID inventoryID = part.ParentGroup.GetFromAssetID();
+
+ ScenePresence presence;
+ if (TryGetAvatar(remoteClient.AgentId, out presence))
+ {
+ if (!Permissions.CanRezObject(part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
+ return;
+
+ presence.Appearance.DetachAttachment(itemID);
+ IAvatarFactory ava = RequestModuleInterface();
+ if (ava != null)
+ {
+ ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ }
+ part.ParentGroup.DetachToGround();
+ CachedUserInfo userInfo =
+ CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+ if (userInfo != null)
+ {
+ userInfo.DeleteItem(inventoryID);
+ remoteClient.SendRemoveInventoryItem(inventoryID);
+ }
+ }
+ }
+
+ public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
+ {
+ ScenePresence presence;
+ if (TryGetAvatar(remoteClient.AgentId, out presence))
+ {
+ presence.Appearance.DetachAttachment(itemID);
+ IAvatarFactory ava = RequestModuleInterface();
+ if (ava != null)
+ {
+ ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ }
+
+ }
+
+ m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
+ }
+
+ public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
+ {
+ EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);
+ }
+
+ void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List localIDs)
+ {
+ if (!Permissions.IsGod(remoteClient.AgentId))
+ return;
+
+ foreach (uint localID in localIDs)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ if (part != null && part.ParentGroup != null)
+ {
+ part.ParentGroup.SetOwnerId(ownerID);
+ part.Inventory.ChangeInventoryOwner(ownerID);
+ part.ParentGroup.SetGroup(groupID, remoteClient);
+ }
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
new file mode 100644
index 0000000..039b81b
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Collections.Generic;
+using System.Threading;
+using OpenMetaverse;
+using OpenMetaverse.Packets;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public partial class Scene
+ {
+ protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
+ UUID fromID, bool fromAgent, bool broadcast)
+ {
+ OSChatMessage args = new OSChatMessage();
+
+ args.Message = Utils.BytesToString(message);
+ args.Channel = channel;
+ args.Type = type;
+ args.Position = fromPos;
+ args.SenderUUID = fromID;
+ args.Scene = this;
+
+ if (fromAgent)
+ {
+ ScenePresence user = GetScenePresence(fromID);
+ if (user != null)
+ args.Sender = user.ControllingClient;
+ }
+ else
+ {
+ SceneObjectPart obj = GetSceneObjectPart(fromID);
+ args.SenderObject = obj;
+ }
+
+ args.From = fromName;
+ //args.
+
+ if (broadcast)
+ EventManager.TriggerOnChatBroadcast(this, args);
+ else
+ EventManager.TriggerOnChatFromWorld(this, args);
+
+ }
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
+ UUID fromID, bool fromAgent)
+ {
+ SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, false);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SimChatBroadcast(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName,
+ UUID fromID, bool fromAgent)
+ {
+ SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true);
+ }
+
+ ///
+ /// Invoked when the client selects a prim.
+ ///
+ ///
+ ///
+ public void SelectPrim(uint primLocalID, IClientAPI remoteClient)
+ {
+ List EntityList = GetEntities();
+
+ foreach (EntityBase ent in EntityList)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ if (((SceneObjectGroup) ent).LocalId == primLocalID)
+ {
+ ((SceneObjectGroup) ent).GetProperties(remoteClient);
+ ((SceneObjectGroup) ent).IsSelected = true;
+ // A prim is only tainted if it's allowed to be edited by the person clicking it.
+ if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)
+ || Permissions.CanMoveObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId))
+ {
+ EventManager.TriggerParcelPrimCountTainted();
+ }
+ break;
+ }
+ else
+ {
+ // We also need to check the children of this prim as they
+ // can be selected as well and send property information
+ bool foundPrim = false;
+ foreach (KeyValuePair child in ((SceneObjectGroup) ent).Children)
+ {
+ if (child.Value.LocalId == primLocalID)
+ {
+ child.Value.GetProperties(remoteClient);
+ foundPrim = true;
+ break;
+ }
+ }
+ if (foundPrim) break;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Handle the deselection of a prim from the client.
+ ///
+ ///
+ ///
+ public void DeselectPrim(uint primLocalID, IClientAPI remoteClient)
+ {
+ SceneObjectPart part = GetSceneObjectPart(primLocalID);
+ if (part == null)
+ return;
+
+ // The prim is in the process of being deleted.
+ if (null == part.ParentGroup.RootPart)
+ return;
+
+ // A deselect packet contains all the local prims being deselected. However, since selection is still
+ // group based we only want the root prim to trigger a full update - otherwise on objects with many prims
+ // we end up sending many duplicate ObjectUpdates
+ if (part.ParentGroup.RootPart.LocalId != part.LocalId)
+ return;
+
+ bool isAttachment = false;
+
+ // This is wrong, wrong, wrong. Selection should not be
+ // handled by group, but by prim. Legacy cruft.
+ // TODO: Make selection flagging per prim!
+ //
+ part.ParentGroup.IsSelected = false;
+
+ if (part.ParentGroup.IsAttachment)
+ isAttachment = true;
+ else
+ part.ParentGroup.ScheduleGroupForFullUpdate();
+
+ // If it's not an attachment, and we are allowed to move it,
+ // then we might have done so. If we moved across a parcel
+ // boundary, we will need to recount prims on the parcels.
+ // For attachments, that makes no sense.
+ //
+ if (!isAttachment)
+ {
+ if (Permissions.CanEditObject(
+ part.UUID, remoteClient.AgentId)
+ || Permissions.CanMoveObject(
+ part.UUID, remoteClient.AgentId))
+ EventManager.TriggerParcelPrimCountTainted();
+ }
+ }
+
+ public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount,
+ int transactiontype, string description)
+ {
+ EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount,
+ transactiontype, description);
+
+ EventManager.TriggerMoneyTransfer(this, args);
+ }
+
+ public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned,
+ bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated)
+ {
+ EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned,
+ removeContribution, parcelLocalID, parcelArea,
+ parcelPrice, authenticated);
+
+ // First, allow all validators a stab at it
+ m_eventManager.TriggerValidateLandBuy(this, args);
+
+ // Then, check validation and transfer
+ m_eventManager.TriggerLandBuy(this, args);
+ }
+
+ public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List surfaceArgs)
+ {
+ List EntityList = GetEntities();
+
+ SurfaceTouchEventArgs surfaceArg = null;
+ if (surfaceArgs != null && surfaceArgs.Count > 0)
+ surfaceArg = surfaceArgs[0];
+
+ foreach (EntityBase ent in EntityList)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ SceneObjectGroup obj = ent as SceneObjectGroup;
+ if (obj != null)
+ {
+ // Is this prim part of the group
+ if (obj.HasChildPrim(localID))
+ {
+ // Currently only grab/touch for the single prim
+ // the client handles rez correctly
+ obj.ObjectGrabHandler(localID, offsetPos, remoteClient);
+
+ SceneObjectPart part = obj.GetChildPart(localID);
+
+ // If the touched prim handles touches, deliver it
+ // If not, deliver to root prim
+ if ((part.ScriptEvents & scriptEvents.touch_start) != 0)
+ EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
+ else
+ EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
+
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient)
+ {
+ List EntityList = GetEntities();
+
+ foreach (EntityBase ent in EntityList)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ SceneObjectGroup obj = ent as SceneObjectGroup;
+
+ // Is this prim part of the group
+ if (obj.HasChildPrim(localID))
+ {
+ SceneObjectPart part=obj.GetChildPart(localID);
+ if (part != null)
+ {
+ // If the touched prim handles touches, deliver it
+ // If not, deliver to root prim
+ if ((part.ScriptEvents & scriptEvents.touch_end) != 0)
+ EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient);
+ else
+ EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient);
+
+ return;
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
+ {
+ //EventManager.TriggerAvatarPickerRequest();
+
+ List AvatarResponses = new List();
+ AvatarResponses = m_sceneGridService.GenerateAgentPickerRequestResponse(RequestID, query);
+
+ AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
+ // TODO: don't create new blocks if recycling an old packet
+
+ AvatarPickerReplyPacket.DataBlock[] searchData =
+ new AvatarPickerReplyPacket.DataBlock[AvatarResponses.Count];
+ AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
+
+ agentData.AgentID = avatarID;
+ agentData.QueryID = RequestID;
+ replyPacket.AgentData = agentData;
+ //byte[] bytes = new byte[AvatarResponses.Count*32];
+
+ int i = 0;
+ foreach (AvatarPickerAvatar item in AvatarResponses)
+ {
+ UUID translatedIDtem = item.AvatarID;
+ searchData[i] = new AvatarPickerReplyPacket.DataBlock();
+ searchData[i].AvatarID = translatedIDtem;
+ searchData[i].FirstName = Utils.StringToBytes((string) item.firstName);
+ searchData[i].LastName = Utils.StringToBytes((string) item.lastName);
+ i++;
+ }
+ if (AvatarResponses.Count == 0)
+ {
+ searchData = new AvatarPickerReplyPacket.DataBlock[0];
+ }
+ replyPacket.Data = searchData;
+
+ AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
+ agent_data.AgentID = replyPacket.AgentData.AgentID;
+ agent_data.QueryID = replyPacket.AgentData.QueryID;
+
+ List data_args = new List();
+ for (i = 0; i < replyPacket.Data.Length; i++)
+ {
+ AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
+ data_arg.AvatarID = replyPacket.Data[i].AvatarID;
+ data_arg.FirstName = replyPacket.Data[i].FirstName;
+ data_arg.LastName = replyPacket.Data[i].LastName;
+ data_args.Add(data_arg);
+ }
+ client.SendAvatarPickerReply(agent_data, data_args);
+ }
+
+ public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID,
+ UUID itemID)
+ {
+ SceneObjectPart part=GetSceneObjectPart(objectID);
+ if (part == null)
+ return;
+
+ if (Permissions.CanResetScript(objectID, itemID, remoteClient.AgentId))
+ {
+ EventManager.TriggerScriptReset(part.LocalId, itemID);
+ }
+ }
+
+ ///
+ /// Handle a fetch inventory request from the client
+ ///
+ ///
+ ///
+ ///
+ public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID)
+ {
+ if (ownerID == CommsManager.UserProfileCacheService.LibraryRoot.Owner)
+ {
+ //Console.WriteLine("request info for library item");
+ return;
+ }
+
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ if (userProfile.HasReceivedInventory)
+ {
+ InventoryItemBase item = null;
+ if (userProfile.RootFolder == null)
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: User {0} {1} does not have a root folder.",
+ remoteClient.Name, remoteClient.AgentId);
+ else
+ item = userProfile.RootFolder.FindItem(itemID);
+
+ if (item != null)
+ {
+ remoteClient.SendInventoryItemDetails(ownerID, item);
+ }
+ }
+ }
+
+ ///
+ /// Tell the client about the various child items and folders contained in the requested folder.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
+ bool fetchFolders, bool fetchItems, int sortOrder)
+ {
+ // FIXME MAYBE: We're not handling sortOrder!
+
+ // TODO: This code for looking in the folder for the library should be folded back into the
+ // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc.
+ // can be handled transparently).
+ InventoryFolderImpl fold = null;
+ if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
+ {
+ remoteClient.SendInventoryFolderDetails(
+ fold.Owner, folderID, fold.RequestListOfItems(),
+ fold.RequestListOfFolders(), fetchFolders, fetchItems);
+ return;
+ }
+
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ userProfile.SendInventoryDecendents(remoteClient, folderID, fetchFolders, fetchItems);
+ }
+
+ ///
+ /// Handle the caps inventory descendents fetch.
+ ///
+ /// Since the folder structure is sent to the client on login, I believe we only need to handle items.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// null if the inventory look up failed
+ public List HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
+ bool fetchFolders, bool fetchItems, int sortOrder)
+ {
+// m_log.DebugFormat(
+// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
+// fetchFolders, fetchItems, folderID, agentID);
+
+ // FIXME MAYBE: We're not handling sortOrder!
+
+ // TODO: This code for looking in the folder for the library should be folded back into the
+ // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc.
+ // can be handled transparently).
+ InventoryFolderImpl fold;
+ if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
+ {
+ return fold.RequestListOfItems();
+ }
+
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(agentID);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat("[AGENT INVENTORY]: Could not find user profile for {0}", agentID);
+ return null;
+ }
+
+ // XXX: When a client crosses into a scene, their entire inventory is fetched
+ // asynchronously. If the client makes a request before the inventory is received, we need
+ // to give the inventory a chance to come in.
+ //
+ // This is a crude way of dealing with that by retrying the lookup. It's not quite as bad
+ // in CAPS as doing this with the udp request, since here it won't hold up other packets.
+ // In fact, here we'll be generous and try for longer.
+ if (!userProfile.HasReceivedInventory)
+ {
+ int attempts = 0;
+ while (attempts++ < 30)
+ {
+ m_log.DebugFormat(
+ "[INVENTORY CACHE]: Poll number {0} for inventory items in folder {1} for user {2}",
+ attempts, folderID, agentID);
+
+ Thread.Sleep(2000);
+
+ if (userProfile.HasReceivedInventory)
+ {
+ break;
+ }
+ }
+ }
+
+ if (userProfile.HasReceivedInventory)
+ {
+ if ((fold = userProfile.RootFolder.FindFolder(folderID)) != null)
+ {
+ return fold.RequestListOfItems();
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "[AGENT INVENTORY]: Could not find folder {0} requested by user {1}",
+ folderID, agentID);
+ return null;
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID);
+ return null;
+ }
+ }
+
+ ///
+ /// Handle an inventory folder creation request from the client.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType,
+ string folderName, UUID parentID)
+ {
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ if (!userProfile.CreateFolder(folderName, folderID, folderType, parentID))
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ }
+ }
+
+ ///
+ /// Handle a client request to update the inventory folder
+ ///
+ ///
+ /// FIXME: We call add new inventory folder because in the data layer, we happen to use an SQL REPLACE
+ /// so this will work to rename an existing folder. Needless to say, to rely on this is very confusing,
+ /// and needs to be changed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void HandleUpdateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort type, string name,
+ UUID parentID)
+ {
+// m_log.DebugFormat(
+// "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId);
+
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ if (!userProfile.UpdateFolder(name, folderID, type, parentID))
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to update folder for user {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ }
+ }
+
+ ///
+ /// Handle an inventory folder move request from the client.
+ ///
+ ///
+ ///
+ ///
+ public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID)
+ {
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ if (!userProfile.MoveFolder(folderID, parentID))
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to move folder {0} to {1} for user {2}",
+ folderID, parentID, remoteClient.Name);
+ }
+ }
+
+ ///
+ /// This should delete all the items and folders in the given directory.
+ ///
+ ///
+ ///
+ public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID)
+ {
+ CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
+
+ if (null == userProfile)
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Could not find user profile for {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ return;
+ }
+
+ if (!userProfile.PurgeFolder(folderID))
+ {
+ m_log.ErrorFormat(
+ "[AGENT INVENTORY]: Failed to purge folder for user {0} {1}",
+ remoteClient.Name, remoteClient.AgentId);
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
new file mode 100644
index 0000000..6aa617f
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -0,0 +1,1334 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public class ScenePermissions
+ {
+ private Scene m_scene;
+
+ public ScenePermissions(Scene scene)
+ {
+ m_scene = scene;
+ }
+
+ #region Object Permission Checks
+
+ public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectIDID);
+ private List GenerateClientFlagsCheckFunctions = new List();
+
+ public void AddGenerateClientFlagsHandler(GenerateClientFlagsHandler delegateFunc)
+ {
+ if (!GenerateClientFlagsCheckFunctions.Contains(delegateFunc))
+ GenerateClientFlagsCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveGenerateClientFlagsHandler(GenerateClientFlagsHandler delegateFunc)
+ {
+ if (GenerateClientFlagsCheckFunctions.Contains(delegateFunc))
+ GenerateClientFlagsCheckFunctions.Remove(delegateFunc);
+ }
+
+ public uint GenerateClientFlags(UUID userID, UUID objectID)
+ {
+ SceneObjectPart part=m_scene.GetSceneObjectPart(objectID);
+
+ if (part == null)
+ return 0;
+
+ // libomv will moan about PrimFlags.ObjectYouOfficer being
+ // obsolete...
+ #pragma warning disable 0612
+ uint perms=part.GetEffectiveObjectFlags() |
+ (uint)PrimFlags.ObjectModify |
+ (uint)PrimFlags.ObjectCopy |
+ (uint)PrimFlags.ObjectMove |
+ (uint)PrimFlags.ObjectTransfer |
+ (uint)PrimFlags.ObjectYouOwner |
+ (uint)PrimFlags.ObjectAnyOwner |
+ (uint)PrimFlags.ObjectOwnerModify |
+ (uint)PrimFlags.ObjectYouOfficer;
+ #pragma warning restore 0612
+
+ foreach (GenerateClientFlagsHandler check in GenerateClientFlagsCheckFunctions)
+ {
+ perms &= check(userID, objectID);
+ }
+ return perms;
+ }
+
+ public delegate void SetBypassPermissionsHandler(bool value);
+ private List SetBypassPermissionsCheckFunctions = new List();
+
+ public void AddSetBypassPermissionsHandler(SetBypassPermissionsHandler delegateFunc)
+ {
+ if (!SetBypassPermissionsCheckFunctions.Contains(delegateFunc))
+ SetBypassPermissionsCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveSetBypassPermissionsHandler(SetBypassPermissionsHandler delegateFunc)
+ {
+ if (SetBypassPermissionsCheckFunctions.Contains(delegateFunc))
+ SetBypassPermissionsCheckFunctions.Remove(delegateFunc);
+ }
+
+ public void SetBypassPermissions(bool value)
+ {
+ foreach (SetBypassPermissionsHandler check in SetBypassPermissionsCheckFunctions)
+ {
+ check(value);
+ }
+ }
+
+ public delegate bool BypassPermissionsHandler();
+ private List BypassPermissionsCheckFunctions = new List();
+
+ public void AddBypassPermissionsHandler(BypassPermissionsHandler delegateFunc)
+ {
+ if (!BypassPermissionsCheckFunctions.Contains(delegateFunc))
+ BypassPermissionsCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveBypassPermissionsHandler(BypassPermissionsHandler delegateFunc)
+ {
+ if (BypassPermissionsCheckFunctions.Contains(delegateFunc))
+ BypassPermissionsCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool BypassPermissions()
+ {
+ foreach (BypassPermissionsHandler check in BypassPermissionsCheckFunctions)
+ {
+ if (check() == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool PropagatePermissionsHandler();
+ private List PropagatePermissionsCheckFunctions = new List();
+
+ public void AddPropagatePermissionsHandler(PropagatePermissionsHandler delegateFunc)
+ {
+ if (!PropagatePermissionsCheckFunctions.Contains(delegateFunc))
+ PropagatePermissionsCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemovePropagatePermissionsHandler(PropagatePermissionsHandler delegateFunc)
+ {
+ if (PropagatePermissionsCheckFunctions.Contains(delegateFunc))
+ PropagatePermissionsCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool PropagatePermissions()
+ {
+ foreach (PropagatePermissionsHandler check in PropagatePermissionsCheckFunctions)
+ {
+ if (check() == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #region REZ OBJECT
+ public delegate bool CanRezObjectHandler(int objectCount, UUID owner, Vector3 objectPosition, Scene scene);
+ private List CanRezObjectCheckFunctions = new List();
+
+ public void AddRezObjectHandler(CanRezObjectHandler delegateFunc)
+ {
+ if (!CanRezObjectCheckFunctions.Contains(delegateFunc))
+ CanRezObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveRezObjectHandler(CanRezObjectHandler delegateFunc)
+ {
+ if (CanRezObjectCheckFunctions.Contains(delegateFunc))
+ CanRezObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition)
+ {
+ foreach (CanRezObjectHandler check in CanRezObjectCheckFunctions)
+ {
+ if (check(objectCount, owner,objectPosition, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region DELETE OBJECT
+ public delegate bool CanDeleteObjectHandler(UUID objectID, UUID deleter, Scene scene);
+ private List CanDeleteObjectCheckFunctions = new List();
+
+ public void AddDeleteObjectHandler(CanDeleteObjectHandler delegateFunc)
+ {
+ if (!CanDeleteObjectCheckFunctions.Contains(delegateFunc))
+ CanDeleteObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveDeleteObjectHandler(CanDeleteObjectHandler delegateFunc)
+ {
+ if (CanDeleteObjectCheckFunctions.Contains(delegateFunc))
+ CanDeleteObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanDeleteObject(UUID objectID, UUID deleter)
+ {
+ foreach (CanDeleteObjectHandler check in CanDeleteObjectCheckFunctions)
+ {
+ if (check(objectID,deleter,m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region TAKE OBJECT
+ public delegate bool CanTakeObjectHandler(UUID objectID, UUID stealer, Scene scene);
+ private List CanTakeObjectCheckFunctions = new List();
+
+ public void AddTakeObjectHandler(CanTakeObjectHandler delegateFunc)
+ {
+ if (!CanTakeObjectCheckFunctions.Contains(delegateFunc))
+ CanTakeObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveTakeObjectHandler(CanTakeObjectHandler delegateFunc)
+ {
+ if (CanTakeObjectCheckFunctions.Contains(delegateFunc))
+ CanTakeObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanTakeObject(UUID objectID, UUID AvatarTakingUUID)
+ {
+ foreach (CanTakeObjectHandler check in CanTakeObjectCheckFunctions)
+ {
+ if (check(objectID, AvatarTakingUUID, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region TAKE COPY OBJECT
+ public delegate bool CanTakeCopyObjectHandler(UUID objectID, UUID userID, Scene inScene);
+ private List CanTakeCopyObjectCheckFunctions = new List();
+
+ public void AddTakeCopyObjectHandler(CanTakeCopyObjectHandler delegateFunc)
+ {
+ if (!CanTakeCopyObjectCheckFunctions.Contains(delegateFunc))
+ CanTakeCopyObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveTakeCopyObjectHandler(CanTakeCopyObjectHandler delegateFunc)
+ {
+ if (CanTakeCopyObjectCheckFunctions.Contains(delegateFunc))
+ CanTakeCopyObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanTakeCopyObject(UUID objectID, UUID userID)
+ {
+ foreach (CanTakeCopyObjectHandler check in CanTakeCopyObjectCheckFunctions)
+ {
+ if (check(objectID,userID,m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region DUPLICATE OBJECT
+ public delegate bool CanDuplicateObjectHandler(int objectCount, UUID objectID, UUID owner, Scene scene, Vector3 objectPosition);
+ private List CanDuplicateObjectCheckFunctions = new List();
+
+ public void AddDuplicateObjectHandler(CanDuplicateObjectHandler delegateFunc)
+ {
+ if (!CanDuplicateObjectCheckFunctions.Contains(delegateFunc))
+ CanDuplicateObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveDuplicateObjectHandler(CanDuplicateObjectHandler delegateFunc)
+ {
+ if (CanDuplicateObjectCheckFunctions.Contains(delegateFunc))
+ CanDuplicateObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanDuplicateObject(int objectCount, UUID objectID, UUID owner, Vector3 objectPosition)
+ {
+ foreach (CanDuplicateObjectHandler check in CanDuplicateObjectCheckFunctions)
+ {
+ if (check(objectCount, objectID, owner, m_scene, objectPosition) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region EDIT OBJECT
+ public delegate bool CanEditObjectHandler(UUID objectID, UUID editorID, Scene scene);
+ private List CanEditObjectCheckFunctions = new List();
+
+ public void AddEditObjectHandler(CanEditObjectHandler delegateFunc)
+ {
+ if (!CanEditObjectCheckFunctions.Contains(delegateFunc))
+ CanEditObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveEditObjectHandler(CanEditObjectHandler delegateFunc)
+ {
+ if (CanEditObjectCheckFunctions.Contains(delegateFunc))
+ CanEditObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanEditObject(UUID objectID, UUID editorID)
+ {
+ foreach (CanEditObjectHandler check in CanEditObjectCheckFunctions)
+ {
+ if (check(objectID, editorID, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanEditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene);
+ private List CanEditObjectInventoryCheckFunctions = new List();
+
+ public void AddEditObjectInventoryHandler(CanEditObjectInventoryHandler delegateFunc)
+ {
+ if (!CanEditObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanEditObjectInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveEditObjectInventoryHandler(CanEditObjectInventoryHandler delegateFunc)
+ {
+ if (CanEditObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanEditObjectInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanEditObjectInventory(UUID objectID, UUID editorID)
+ {
+ foreach (CanEditObjectInventoryHandler check in CanEditObjectInventoryCheckFunctions)
+ {
+ if (check(objectID, editorID, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region MOVE OBJECT
+ public delegate bool CanMoveObjectHandler(UUID objectID, UUID moverID, Scene scene);
+ private List CanMoveObjectCheckFunctions = new List();
+
+ public void AddMoveObjectHandler(CanMoveObjectHandler delegateFunc)
+ {
+ if (!CanMoveObjectCheckFunctions.Contains(delegateFunc))
+ CanMoveObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveMoveObjectHandler(CanMoveObjectHandler delegateFunc)
+ {
+ if (CanMoveObjectCheckFunctions.Contains(delegateFunc))
+ CanMoveObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanMoveObject(UUID objectID, UUID moverID)
+ {
+ foreach (CanMoveObjectHandler check in CanMoveObjectCheckFunctions)
+ {
+ if (check(objectID,moverID,m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region OBJECT ENTRY
+ public delegate bool CanObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene);
+ private List CanObjectEntryCheckFunctions = new List();
+
+ public void AddObjectEntryHandler(CanObjectEntryHandler delegateFunc)
+ {
+ if (!CanObjectEntryCheckFunctions.Contains(delegateFunc))
+ CanObjectEntryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveObjectEntryHandler(CanObjectEntryHandler delegateFunc)
+ {
+ if (CanObjectEntryCheckFunctions.Contains(delegateFunc))
+ CanObjectEntryCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanObjectEntry(UUID objectID, bool enteringRegion, Vector3 newPoint)
+ {
+ foreach (CanObjectEntryHandler check in CanObjectEntryCheckFunctions)
+ {
+ if (check(objectID, enteringRegion, newPoint, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region RETURN OBJECT
+ public delegate bool CanReturnObjectHandler(UUID objectID, UUID returnerID, Scene scene);
+ private List CanReturnObjectCheckFunctions = new List();
+
+ public void AddReturnObjectHandler(CanReturnObjectHandler delegateFunc)
+ {
+ if (!CanReturnObjectCheckFunctions.Contains(delegateFunc))
+ CanReturnObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveReturnObjectHandler(CanReturnObjectHandler delegateFunc)
+ {
+ if (CanReturnObjectCheckFunctions.Contains(delegateFunc))
+ CanReturnObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanReturnObject(UUID objectID, UUID returnerID)
+ {
+ foreach (CanReturnObjectHandler check in CanReturnObjectCheckFunctions)
+ {
+ if (check(objectID,returnerID,m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region INSTANT MESSAGE
+ public delegate bool CanInstantMessageHandler(UUID user, UUID target, Scene startScene);
+ private List CanInstantMessageCheckFunctions = new List();
+
+ public void AddInstantMessageHandler(CanInstantMessageHandler delegateFunc)
+ {
+ if (!CanInstantMessageCheckFunctions.Contains(delegateFunc))
+ CanInstantMessageCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveInstantMessageHandler(CanInstantMessageHandler delegateFunc)
+ {
+ if (CanInstantMessageCheckFunctions.Contains(delegateFunc))
+ CanInstantMessageCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanInstantMessage(UUID user, UUID target)
+ {
+ foreach (CanInstantMessageHandler check in CanInstantMessageCheckFunctions)
+ {
+ if (check(user, target, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region INVENTORY TRANSFER
+ public delegate bool CanInventoryTransferHandler(UUID user, UUID target, Scene startScene);
+ private List CanInventoryTransferCheckFunctions = new List();
+
+ public void AddInventoryTransferHandler(CanInventoryTransferHandler delegateFunc)
+ {
+ if (!CanInventoryTransferCheckFunctions.Contains(delegateFunc))
+ CanInventoryTransferCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveInventoryTransferHandler(CanInventoryTransferHandler delegateFunc)
+ {
+ if (CanInventoryTransferCheckFunctions.Contains(delegateFunc))
+ CanInventoryTransferCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanInventoryTransfer(UUID user, UUID target)
+ {
+ foreach (CanInventoryTransferHandler check in CanInventoryTransferCheckFunctions)
+ {
+ if (check(user, target, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region VIEW SCRIPT
+ public delegate bool CanViewScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
+ private List CanViewScriptCheckFunctions = new List();
+
+ public void AddViewScriptHandler(CanViewScriptHandler delegateFunc)
+ {
+ if (!CanViewScriptCheckFunctions.Contains(delegateFunc))
+ CanViewScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveViewScriptHandler(CanViewScriptHandler delegateFunc)
+ {
+ if (CanViewScriptCheckFunctions.Contains(delegateFunc))
+ CanViewScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanViewScript(UUID script, UUID objectID, UUID user)
+ {
+ foreach (CanViewScriptHandler check in CanViewScriptCheckFunctions)
+ {
+ if (check(script, objectID, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanViewNotecardHandler(UUID script, UUID objectID, UUID user, Scene scene);
+ private List CanViewNotecardCheckFunctions = new List();
+
+ public void AddViewNotecardHandler(CanViewNotecardHandler delegateFunc)
+ {
+ if (!CanViewNotecardCheckFunctions.Contains(delegateFunc))
+ CanViewNotecardCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveViewNotecardHandler(CanViewNotecardHandler delegateFunc)
+ {
+ if (CanViewNotecardCheckFunctions.Contains(delegateFunc))
+ CanViewNotecardCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanViewNotecard(UUID script, UUID objectID, UUID user)
+ {
+ foreach (CanViewNotecardHandler check in CanViewNotecardCheckFunctions)
+ {
+ if (check(script, objectID, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region EDIT SCRIPT
+ public delegate bool CanEditScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
+ private List CanEditScriptCheckFunctions = new List();
+
+ public void AddEditScriptHandler(CanEditScriptHandler delegateFunc)
+ {
+ if (!CanEditScriptCheckFunctions.Contains(delegateFunc))
+ CanEditScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveEditScriptHandler(CanEditScriptHandler delegateFunc)
+ {
+ if (CanEditScriptCheckFunctions.Contains(delegateFunc))
+ CanEditScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanEditScript(UUID script, UUID objectID, UUID user)
+ {
+ foreach (CanEditScriptHandler check in CanEditScriptCheckFunctions)
+ {
+ if (check(script, objectID, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanEditNotecardHandler(UUID notecard, UUID objectID, UUID user, Scene scene);
+ private List CanEditNotecardCheckFunctions = new List();
+
+ public void AddEditNotecardHandler(CanEditNotecardHandler delegateFunc)
+ {
+ if (!CanEditNotecardCheckFunctions.Contains(delegateFunc))
+ CanEditNotecardCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveEditNotecardHandler(CanEditNotecardHandler delegateFunc)
+ {
+ if (CanEditNotecardCheckFunctions.Contains(delegateFunc))
+ CanEditNotecardCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanEditNotecard(UUID script, UUID objectID, UUID user)
+ {
+ foreach (CanEditNotecardHandler check in CanEditNotecardCheckFunctions)
+ {
+ if (check(script, objectID, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region RUN SCRIPT (When Script Placed in Object)
+ public delegate bool CanRunScriptHandler(UUID script, UUID objectID, UUID user, Scene scene);
+ private List CanRunScriptCheckFunctions = new List();
+
+ public void AddRunScriptHandler(CanRunScriptHandler delegateFunc)
+ {
+ if (!CanRunScriptCheckFunctions.Contains(delegateFunc))
+ CanRunScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveRunScriptHandler(CanRunScriptHandler delegateFunc)
+ {
+ if (CanRunScriptCheckFunctions.Contains(delegateFunc))
+ CanRunScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanRunScript(UUID script, UUID objectID, UUID user)
+ {
+ foreach (CanRunScriptHandler check in CanRunScriptCheckFunctions)
+ {
+ if (check(script, objectID, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region START SCRIPT (When Script run box is Checked after placed in object)
+ public delegate bool CanStartScriptHandler(UUID script, UUID user, Scene scene);
+ private List CanStartScriptCheckFunctions = new List();
+
+ public void AddStartScriptHandler(CanStartScriptHandler delegateFunc)
+ {
+ if (!CanStartScriptCheckFunctions.Contains(delegateFunc))
+ CanStartScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveStartScriptHandler(CanStartScriptHandler delegateFunc)
+ {
+ if (CanStartScriptCheckFunctions.Contains(delegateFunc))
+ CanStartScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanStartScript(UUID script, UUID user)
+ {
+ foreach (CanStartScriptHandler check in CanStartScriptCheckFunctions)
+ {
+ if (check(script, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region STOP SCRIPT (When Script run box is unchecked after placed in object)
+ public delegate bool CanStopScriptHandler(UUID script, UUID user, Scene scene);
+ private List CanStopScriptCheckFunctions = new List();
+
+ public void AddStopScriptHandler(CanStopScriptHandler delegateFunc)
+ {
+ if (!CanStopScriptCheckFunctions.Contains(delegateFunc))
+ CanStopScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveStopScriptHandler(CanStopScriptHandler delegateFunc)
+ {
+ if (CanStopScriptCheckFunctions.Contains(delegateFunc))
+ CanStopScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanStopScript(UUID script, UUID user)
+ {
+ foreach (CanStopScriptHandler check in CanStopScriptCheckFunctions)
+ {
+ if (check(script, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region RESET SCRIPT
+ public delegate bool CanResetScriptHandler(UUID prim, UUID script, UUID user, Scene scene);
+ private List CanResetScriptCheckFunctions = new List();
+
+ public void AddResetScriptHandler(CanResetScriptHandler delegateFunc)
+ {
+ if (!CanResetScriptCheckFunctions.Contains(delegateFunc))
+ CanResetScriptCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveResetScriptHandler(CanResetScriptHandler delegateFunc)
+ {
+ if (CanResetScriptCheckFunctions.Contains(delegateFunc))
+ CanResetScriptCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanResetScript(UUID prim, UUID script, UUID user)
+ {
+ foreach (CanResetScriptHandler check in CanResetScriptCheckFunctions)
+ {
+ if (check(prim, script, user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region TERRAFORM LAND
+ public delegate bool CanTerraformLandHandler(UUID user, Vector3 position, Scene requestFromScene);
+ private List CanTerraformLandCheckFunctions = new List();
+
+ public void AddTerraformLandHandler(CanTerraformLandHandler delegateFunc)
+ {
+ if (!CanTerraformLandCheckFunctions.Contains(delegateFunc))
+ CanTerraformLandCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveTerraformLandHandler(CanTerraformLandHandler delegateFunc)
+ {
+ if (CanTerraformLandCheckFunctions.Contains(delegateFunc))
+ CanTerraformLandCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanTerraformLand(UUID user, Vector3 pos)
+ {
+ foreach (CanTerraformLandHandler check in CanTerraformLandCheckFunctions)
+ {
+ if (check(user, pos, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region RUN CONSOLE COMMAND
+ public delegate bool CanRunConsoleCommandHandler(UUID user, Scene requestFromScene);
+ private List CanRunConsoleCommandCheckFunctions = new List();
+
+ public void AddRunConsoleCommandHandler(CanRunConsoleCommandHandler delegateFunc)
+ {
+ if (!CanRunConsoleCommandCheckFunctions.Contains(delegateFunc))
+ CanRunConsoleCommandCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveRunConsoleCommandHandler(CanRunConsoleCommandHandler delegateFunc)
+ {
+ if (CanRunConsoleCommandCheckFunctions.Contains(delegateFunc))
+ CanRunConsoleCommandCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanRunConsoleCommand(UUID user)
+ {
+ foreach (CanRunConsoleCommandHandler check in CanRunConsoleCommandCheckFunctions)
+ {
+ if (check(user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ #region CAN ISSUE ESTATE COMMAND
+ public delegate bool CanIssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand);
+ private List CanIssueEstateCommandCheckFunctions = new List();
+
+ public void AddIssueEstateCommandHandler(CanIssueEstateCommandHandler delegateFunc)
+ {
+ if (!CanIssueEstateCommandCheckFunctions.Contains(delegateFunc))
+ CanIssueEstateCommandCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveIssueEstateCommandHandler(CanIssueEstateCommandHandler delegateFunc)
+ {
+ if (CanIssueEstateCommandCheckFunctions.Contains(delegateFunc))
+ CanIssueEstateCommandCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanIssueEstateCommand(UUID user, bool ownerCommand)
+ {
+ foreach (CanIssueEstateCommandHandler check in CanIssueEstateCommandCheckFunctions)
+ {
+ if (check(user, m_scene, ownerCommand) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ #region CAN BE GODLIKE
+ public delegate bool IsGodHandler(UUID user, Scene requestFromScene);
+ private List IsGodCheckFunctions = new List();
+
+ public void AddIsGodHandler(IsGodHandler delegateFunc)
+ {
+ if (!IsGodCheckFunctions.Contains(delegateFunc))
+ IsGodCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveIsGodHandler(IsGodHandler delegateFunc)
+ {
+ if (IsGodCheckFunctions.Contains(delegateFunc))
+ IsGodCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool IsGod(UUID user)
+ {
+ foreach (IsGodHandler check in IsGodCheckFunctions)
+ {
+ if (check(user, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ #region EDIT PARCEL
+ public delegate bool CanEditParcelHandler(UUID user, ILandObject parcel, Scene scene);
+ private List CanEditParcelCheckFunctions = new List();
+
+ public void AddEditParcelHandler(CanEditParcelHandler delegateFunc)
+ {
+ if (!CanEditParcelCheckFunctions.Contains(delegateFunc))
+ CanEditParcelCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveEditParcelHandler(CanEditParcelHandler delegateFunc)
+ {
+ if (CanEditParcelCheckFunctions.Contains(delegateFunc))
+ CanEditParcelCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanEditParcel(UUID user, ILandObject parcel)
+ {
+ foreach (CanEditParcelHandler check in CanEditParcelCheckFunctions)
+ {
+ if (check(user, parcel, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ #region SELL PARCEL
+ public delegate bool CanSellParcelHandler(UUID user, ILandObject parcel, Scene scene);
+ private List CanSellParcelCheckFunctions = new List();
+
+ public void AddSellParcelHandler(CanSellParcelHandler delegateFunc)
+ {
+ if (!CanSellParcelCheckFunctions.Contains(delegateFunc))
+ CanSellParcelCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveSellParcelHandler(CanSellParcelHandler delegateFunc)
+ {
+ if (CanSellParcelCheckFunctions.Contains(delegateFunc))
+ CanSellParcelCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanSellParcel(UUID user, ILandObject parcel)
+ {
+ foreach (CanSellParcelHandler check in CanSellParcelCheckFunctions)
+ {
+ if (check(user, parcel, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ #region ABANDON PARCEL
+ public delegate bool CanAbandonParcelHandler(UUID user, ILandObject parcel, Scene scene);
+ private List CanAbandonParcelCheckFunctions = new List();
+
+ public void AddAbandonParcelHandler(CanAbandonParcelHandler delegateFunc)
+ {
+ if (!CanAbandonParcelCheckFunctions.Contains(delegateFunc))
+ CanAbandonParcelCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveAbandonParcelHandler(CanAbandonParcelHandler delegateFunc)
+ {
+ if (CanAbandonParcelCheckFunctions.Contains(delegateFunc))
+ CanAbandonParcelCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanAbandonParcel(UUID user, ILandObject parcel)
+ {
+ foreach (CanAbandonParcelHandler check in CanAbandonParcelCheckFunctions)
+ {
+ if (check(user, parcel, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ #endregion
+
+ public delegate bool CanReclaimParcelHandler(UUID user, ILandObject parcel, Scene scene);
+ private List CanReclaimParcelCheckFunctions = new List();
+
+ public void AddReclaimParcelHandler(CanReclaimParcelHandler delegateFunc)
+ {
+ if (!CanReclaimParcelCheckFunctions.Contains(delegateFunc))
+ CanReclaimParcelCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveReclaimParcelHandler(CanReclaimParcelHandler delegateFunc)
+ {
+ if (CanReclaimParcelCheckFunctions.Contains(delegateFunc))
+ CanReclaimParcelCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanReclaimParcel(UUID user, ILandObject parcel)
+ {
+ foreach (CanReclaimParcelHandler check in CanReclaimParcelCheckFunctions)
+ {
+ if (check(user, parcel, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ public delegate bool CanBuyLandHandler(UUID user, ILandObject parcel, Scene scene);
+ private List CanBuyLandCheckFunctions = new List();
+
+ public void AddCanBuyLandHandler(CanBuyLandHandler delegateFunc)
+ {
+ if (!CanBuyLandCheckFunctions.Contains(delegateFunc))
+ CanBuyLandCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanBuyLandHandler(CanBuyLandHandler delegateFunc)
+ {
+ if (CanBuyLandCheckFunctions.Contains(delegateFunc))
+ CanBuyLandCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanBuyLand(UUID user, ILandObject parcel)
+ {
+ foreach (CanBuyLandHandler check in CanBuyLandCheckFunctions)
+ {
+ if (check(user, parcel, m_scene) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanLinkObjectHandler(UUID user, UUID objectID);
+ private List CanLinkObjectCheckFunctions = new List();
+
+ public void AddCanLinkObjectHandler(CanLinkObjectHandler delegateFunc)
+ {
+ if (!CanLinkObjectCheckFunctions.Contains(delegateFunc))
+ CanLinkObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanLinkObjectHandler(CanLinkObjectHandler delegateFunc)
+ {
+ if (CanLinkObjectCheckFunctions.Contains(delegateFunc))
+ CanLinkObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanLinkObject(UUID user, UUID objectID)
+ {
+ foreach (CanLinkObjectHandler check in CanLinkObjectCheckFunctions)
+ {
+ if (check(user, objectID) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanDelinkObjectHandler(UUID user, UUID objectID);
+ private List CanDelinkObjectCheckFunctions = new List();
+
+ public void AddCanDelinkObjectHandler(CanDelinkObjectHandler delegateFunc)
+ {
+ if (!CanDelinkObjectCheckFunctions.Contains(delegateFunc))
+ CanDelinkObjectCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanDelinkObjectHandler(CanDelinkObjectHandler delegateFunc)
+ {
+ if (CanDelinkObjectCheckFunctions.Contains(delegateFunc))
+ CanDelinkObjectCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanDelinkObject(UUID user, UUID objectID)
+ {
+ foreach (CanDelinkObjectHandler check in CanDelinkObjectCheckFunctions)
+ {
+ if (check(user, objectID) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ #endregion
+
+ public delegate bool CanCreateObjectInventoryHandler(int invType, UUID objectID, UUID userID);
+ private List CanCreateObjectInventoryCheckFunctions
+ = new List();
+
+
+ public void AddCanCreateObjectInventoryHandler(CanCreateObjectInventoryHandler delegateFunc)
+ {
+ if (!CanCreateObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanCreateObjectInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanCreateObjectInventoryHandler(CanCreateObjectInventoryHandler delegateFunc)
+ {
+ if (CanCreateObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanCreateObjectInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ ///
+ /// Check whether the specified user is allowed to directly create the given inventory type in a prim's
+ /// inventory (e.g. the New Script button in the 1.21 Linden Lab client).
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool CanCreateObjectInventory(int invType, UUID objectID, UUID userID)
+ {
+ foreach (CanCreateObjectInventoryHandler check in CanCreateObjectInventoryCheckFunctions)
+ {
+ if (check(invType, objectID, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanCopyObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID);
+ private List CanCopyObjectInventoryCheckFunctions = new List();
+
+ public void AddCanCopyObjectInventoryHandler(CanCopyObjectInventoryHandler delegateFunc)
+ {
+ if (!CanCopyObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanCopyObjectInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanCopyObjectInventoryHandler(CanCopyObjectInventoryHandler delegateFunc)
+ {
+ if (CanCopyObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanCopyObjectInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanCopyObjectInventory(UUID itemID, UUID objectID, UUID userID)
+ {
+ foreach (CanCopyObjectInventoryHandler check in CanCopyObjectInventoryCheckFunctions)
+ {
+ if (check(itemID, objectID, userID) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public delegate bool CanDeleteObjectInventoryHandler(UUID itemID, UUID objectID, UUID userID);
+ private List CanDeleteObjectInventoryCheckFunctions
+ = new List();
+
+ public void AddCanDeleteObjectInventoryHandler(CanDeleteObjectInventoryHandler delegateFunc)
+ {
+ if (!CanDeleteObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanDeleteObjectInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanDeleteObjectInventoryHandler(CanDeleteObjectInventoryHandler delegateFunc)
+ {
+ if (CanDeleteObjectInventoryCheckFunctions.Contains(delegateFunc))
+ CanDeleteObjectInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanDeleteObjectInventory(UUID itemID, UUID objectID, UUID userID)
+ {
+ foreach (CanDeleteObjectInventoryHandler check in CanDeleteObjectInventoryCheckFunctions)
+ {
+ if (check(itemID, objectID, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanCreateUserInventoryHandler(int invType, UUID userID);
+ private List CanCreateUserInventoryCheckFunctions
+ = new List();
+
+ public void AddCanCreateUserInventoryHandler(CanCreateUserInventoryHandler delegateFunc)
+ {
+ if (!CanCreateUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanCreateUserInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanCreateUserInventoryHandler(CanCreateUserInventoryHandler delegateFunc)
+ {
+ if (CanCreateUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanCreateUserInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ ///
+ /// Check whether the specified user is allowed to create the given inventory type in their inventory.
+ ///
+ ///
+ ///
+ ///
+ public bool CanCreateUserInventory(int invType, UUID userID)
+ {
+ foreach (CanCreateUserInventoryHandler check in CanCreateUserInventoryCheckFunctions)
+ {
+ if (check(invType, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanEditUserInventoryHandler(UUID itemID, UUID userID);
+ private List CanEditUserInventoryCheckFunctions
+ = new List();
+
+ public void AddCanEditUserInventoryHandler(CanEditUserInventoryHandler delegateFunc)
+ {
+ if (!CanEditUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanEditUserInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanEditUserInventoryHandler(CanEditUserInventoryHandler delegateFunc)
+ {
+ if (CanEditUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanEditUserInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ ///
+ /// Check whether the specified user is allowed to edit the given inventory item within their own inventory.
+ ///
+ ///
+ ///
+ ///
+ public bool CanEditUserInventory(UUID itemID, UUID userID)
+ {
+ foreach (CanEditUserInventoryHandler check in CanEditUserInventoryCheckFunctions)
+ {
+ if (check(itemID, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanCopyUserInventoryHandler(UUID itemID, UUID userID);
+ private List CanCopyUserInventoryCheckFunctions
+ = new List();
+
+ public void AddCanCopyUserInventoryHandler(CanCopyUserInventoryHandler delegateFunc)
+ {
+ if (!CanCopyUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanCopyUserInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanCopyUserInventoryHandler(CanCopyUserInventoryHandler delegateFunc)
+ {
+ if (CanCopyUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanCopyUserInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ ///
+ /// Check whether the specified user is allowed to copy the given inventory item from their own inventory.
+ ///
+ ///
+ ///
+ ///
+ public bool CanCopyUserInventory(UUID itemID, UUID userID)
+ {
+ foreach (CanCopyUserInventoryHandler check in CanCopyUserInventoryCheckFunctions)
+ {
+ if (check(itemID, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanDeleteUserInventoryHandler(UUID itemID, UUID userID);
+ private List CanDeleteUserInventoryCheckFunctions
+ = new List();
+
+ public void AddCanDeleteUserInventoryHandler(CanDeleteUserInventoryHandler delegateFunc)
+ {
+ if (!CanDeleteUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanDeleteUserInventoryCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanDeleteUserInventoryHandler(CanDeleteUserInventoryHandler delegateFunc)
+ {
+ if (CanDeleteUserInventoryCheckFunctions.Contains(delegateFunc))
+ CanDeleteUserInventoryCheckFunctions.Remove(delegateFunc);
+ }
+
+ ///
+ /// Check whether the specified user is allowed to edit the given inventory item within their own inventory.
+ ///
+ ///
+ ///
+ ///
+ public bool CanDeleteUserInventory(UUID itemID, UUID userID)
+ {
+ foreach (CanDeleteUserInventoryHandler check in CanDeleteUserInventoryCheckFunctions)
+ {
+ if (check(itemID, userID) == false)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public delegate bool CanTeleportHandler(UUID userID);
+ private List CanTeleportCheckFunctions = new List();
+
+ public void AddCanTeleportHandler(CanTeleportHandler delegateFunc)
+ {
+ if (!CanTeleportCheckFunctions.Contains(delegateFunc))
+ CanTeleportCheckFunctions.Add(delegateFunc);
+ }
+
+ public void RemoveCanTeleportHandler(CanTeleportHandler delegateFunc)
+ {
+ if (CanTeleportCheckFunctions.Contains(delegateFunc))
+ CanTeleportCheckFunctions.Remove(delegateFunc);
+ }
+
+ public bool CanTeleport(UUID userID)
+ {
+ foreach (CanTeleportHandler check in CanTeleportCheckFunctions)
+ {
+ if (check(userID) == false)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
new file mode 100644
index 0000000..f07391d
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -0,0 +1,4239 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyrightD
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Xml;
+using System.Threading;
+using System.Timers;
+using OpenMetaverse;
+using OpenMetaverse.Imaging;
+using OpenMetaverse.Packets;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes.Scripting;
+using OpenSim.Region.Physics.Manager;
+using Nini.Config;
+using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
+using Image = System.Drawing.Image;
+using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
+using Timer = System.Timers.Timer;
+using OSD = OpenMetaverse.StructuredData.OSD;
+
+namespace OpenSim.Region.Framework.Scenes
+{
+ public delegate bool FilterAvatarList(ScenePresence avatar);
+
+ public partial class Scene : SceneBase
+ {
+ public delegate void SynchronizeSceneHandler(Scene scene);
+ public SynchronizeSceneHandler SynchronizeScene = null;
+ public int splitID = 0;
+
+ private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
+ private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
+
+ #region Fields
+
+ protected Timer m_restartWaitTimer = new Timer();
+
+ public SimStatsReporter StatsReporter;
+
+ protected List m_regionRestartNotifyList = new List();
+ protected List m_neighbours = new List();
+
+ ///
+ /// The scene graph for this scene
+ ///
+ /// TODO: Possibly stop other classes being able to manipulate this directly.
+ public SceneGraph m_sceneGraph;
+
+ ///
+ /// Are we applying physics to any of the prims in this scene?
+ ///
+ public bool m_physicalPrim;
+ public float m_maxNonphys = 65536;
+ public float m_maxPhys = 10;
+ public bool m_clampPrimSize = false;
+ public bool m_trustBinaries = false;
+ public bool m_allowScriptCrossings = false;
+
+ public bool m_seeIntoRegionFromNeighbor;
+ public int MaxUndoCount = 5;
+ private int m_RestartTimerCounter;
+ private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
+ private int m_incrementsof15seconds = 0;
+ private volatile bool m_backingup = false;
+
+ private Dictionary m_returns = new Dictionary();
+
+ protected string m_simulatorVersion = "OpenSimulator Server";
+
+ protected ModuleLoader m_moduleLoader;
+ protected StorageManager m_storageManager;
+ protected AgentCircuitManager m_authenticateHandler;
+ public CommunicationsManager CommsManager;
+
+ protected SceneCommunicationService m_sceneGridService;
+
+ public SceneCommunicationService SceneGridService
+ {
+ get { return m_sceneGridService; }
+ }
+
+ public IXfer XferManager;
+
+ protected IXMLRPC m_xmlrpcModule;
+ protected IWorldComm m_worldCommModule;
+ protected IAvatarFactory m_AvatarFactory;
+ protected IConfigSource m_config;
+ protected IRegionSerialiserModule m_serialiser;
+ protected IInterregionCommsOut m_interregionCommsOut;
+ protected IInterregionCommsIn m_interregionCommsIn;
+ protected IDialogModule m_dialogModule;
+
+ protected ICapabilitiesModule m_capsModule;
+ public ICapabilitiesModule CapsModule
+ {
+ get { return m_capsModule; }
+ }
+
+ // Central Update Loop
+
+ protected int m_fps = 10;
+ protected int m_frame = 0;
+ protected float m_timespan = 0.089f;
+ protected DateTime m_lastupdate = DateTime.Now;
+
+ protected float m_timedilation = 1.0f;
+
+ private int m_update_physics = 1;
+ private int m_update_entitymovement = 1;
+ private int m_update_entities = 1; // Run through all objects checking for updates
+ private int m_update_entitiesquick = 200; // Run through objects that have scheduled updates checking for updates
+ private int m_update_presences = 1; // Update scene presence movements
+ private int m_update_events = 1;
+ private int m_update_backup = 200;
+ private int m_update_terrain = 50;
+ private int m_update_land = 1;
+
+ private int frameMS = 0;
+ private int physicsMS2 = 0;
+ private int physicsMS = 0;
+ private int otherMS = 0;
+
+ private bool m_physics_enabled = true;
+ private bool m_scripts_enabled = true;
+ private string m_defaultScriptEngine;
+ private int m_LastLogin = 0;
+ private Thread HeartbeatThread;
+ private volatile bool shuttingdown = false;
+
+ private object m_deleting_scene_object = new object();
+
+ // the minimum time that must elapse before a changed object will be considered for persisted
+ public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
+ // the maximum time that must elapse before a changed object will be considered for persisted
+ public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
+
+ #endregion
+
+ #region Properties
+
+ public AgentCircuitManager AuthenticateHandler
+ {
+ get { return m_authenticateHandler; }
+ }
+
+ public SceneGraph SceneContents
+ {
+ get { return m_sceneGraph; }
+ }
+
+ // an instance to the physics plugin's Scene object.
+ public PhysicsScene PhysicsScene
+ {
+ get { return m_sceneGraph.PhysicsScene; }
+ set
+ {
+ // If we're not doing the initial set
+ // Then we've got to remove the previous
+ // event handler
+ if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
+ {
+ PhysicsScene.OnJointMoved -= jointMoved;
+ PhysicsScene.OnJointDeactivated -= jointDeactivated;
+ PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
+ }
+
+ m_sceneGraph.PhysicsScene = value;
+
+ if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
+ {
+ // register event handlers to respond to joint movement/deactivation
+ PhysicsScene.OnJointMoved += jointMoved;
+ PhysicsScene.OnJointDeactivated += jointDeactivated;
+ PhysicsScene.OnJointErrorMessage += jointErrorMessage;
+ }
+
+ }
+ }
+
+ // This gets locked so things stay thread safe.
+ public object SyncRoot
+ {
+ get { return m_sceneGraph.m_syncRoot; }
+ }
+
+ public float TimeDilation
+ {
+ get { return m_timedilation; }
+ }
+
+ ///
+ /// This is for llGetRegionFPS
+ ///
+ public float SimulatorFPS
+ {
+ get { return StatsReporter.getLastReportedSimFPS(); }
+ }
+
+ public string DefaultScriptEngine
+ {
+ get { return m_defaultScriptEngine; }
+ }
+
+ // Local reference to the objects in the scene (which are held in the scenegraph)
+ // public Dictionary Objects
+ // {
+ // get { return m_sceneGraph.SceneObjects; }
+ // }
+
+ // Reference to all of the agents in the scene (root and child)
+ protected Dictionary m_scenePresences
+ {
+ get { return m_sceneGraph.ScenePresences; }
+ set { m_sceneGraph.ScenePresences = value; }
+ }
+
+ // protected Dictionary m_sceneObjects
+ // {
+ // get { return m_sceneGraph.SceneObjects; }
+ // set { m_sceneGraph.SceneObjects = value; }
+ // }
+
+ public EntityManager Entities
+ {
+ get { return m_sceneGraph.Entities; }
+ }
+
+ public Dictionary m_restorePresences
+ {
+ get { return m_sceneGraph.RestorePresences; }
+ set { m_sceneGraph.RestorePresences = value; }
+ }
+
+ public int objectCapacity = 45000;
+
+ #endregion
+
+ #region Constructors
+
+ public Scene(RegionInfo regInfo, AgentCircuitManager authen,
+ CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
+ AssetCache assetCach, StorageManager storeManager,
+ ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
+ bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
+ {
+ m_config = config;
+
+ Random random = new Random();
+ m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
+ m_moduleLoader = moduleLoader;
+ m_authenticateHandler = authen;
+ CommsManager = commsMan;
+ m_sceneGridService = sceneGridService;
+ m_storageManager = storeManager;
+ AssetCache = assetCach;
+ m_regInfo = regInfo;
+ m_regionHandle = m_regInfo.RegionHandle;
+ m_regionName = m_regInfo.RegionName;
+ m_datastore = m_regInfo.DataStore;
+
+ m_physicalPrim = physicalPrim;
+ m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
+
+ m_eventManager = new EventManager();
+ m_permissions = new ScenePermissions(this);
+
+ m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
+ m_asyncSceneObjectDeleter.Enabled = true;
+
+ // Load region settings
+ m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
+ if (m_storageManager.EstateDataStore != null)
+ m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
+
+ //Bind Storage Manager functions to some land manager functions for this scene
+ EventManager.OnLandObjectAdded +=
+ new EventManager.LandObjectAdded(m_storageManager.DataStore.StoreLandObject);
+ EventManager.OnLandObjectRemoved +=
+ new EventManager.LandObjectRemoved(m_storageManager.DataStore.RemoveLandObject);
+
+ m_sceneGraph = new SceneGraph(this, m_regInfo);
+
+ // If the scene graph has an Unrecoverable error, restart this sim.
+ // Currently the only thing that causes it to happen is two kinds of specific
+ // Physics based crashes.
+ //
+ // Out of memory
+ // Operating system has killed the plugin
+ m_sceneGraph.UnRecoverableError += RestartNow;
+
+ RegisterDefaultSceneEvents();
+
+ DumpAssetsToFile = dumpAssetsToFile;
+
+ m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
+
+ m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
+
+ StatsReporter = new SimStatsReporter(this);
+ StatsReporter.OnSendStatsResult += SendSimStatsPackets;
+ StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
+
+ StatsReporter.SetObjectCapacity(objectCapacity);
+
+ m_simulatorVersion = simulatorVersion
+ + " (OS " + Util.GetOperatingSystemInformation() + ")"
+ + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString()
+ + " PhysPrim:" + m_physicalPrim.ToString();
+
+ try
+ {
+ // Region config overrides global config
+ //
+ IConfig startupConfig = m_config.Configs["Startup"];
+ m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", 65536.0f);
+ if (RegionInfo.NonphysPrimMax > 0)
+ m_maxNonphys = RegionInfo.NonphysPrimMax;
+
+ m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", 10.0f);
+
+ if (RegionInfo.PhysPrimMax > 0)
+ m_maxPhys = RegionInfo.PhysPrimMax;
+
+ // Here, if clamping is requested in either global or
+ // local config, it will be used
+ //
+ m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", false);
+ if (RegionInfo.ClampPrimSize)
+ m_clampPrimSize = true;
+
+ m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", false);
+ m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", false);
+ m_dontPersistBefore =
+ startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
+ m_dontPersistBefore *= 10000000;
+ m_persistAfter =
+ startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
+ m_persistAfter *= 10000000;
+
+ m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine");
+ }
+ catch
+ {
+ m_log.Warn("[SCENE]: Failed to load StartupConfig");
+ }
+ }
+
+ ///
+ /// Mock constructor for scene group persistency unit tests.
+ /// SceneObjectGroup RegionId property is delegated to Scene.
+ ///
+ ///
+ public Scene(RegionInfo regInfo)
+ {
+ m_regInfo = regInfo;
+ m_eventManager = new EventManager();
+ }
+
+ #endregion
+
+ #region Startup / Close Methods
+
+ public bool ShuttingDown
+ {
+ get { return shuttingdown; }
+ }
+
+ protected virtual void RegisterDefaultSceneEvents()
+ {
+ IDialogModule dm = RequestModuleInterface();
+
+ if (dm != null)
+ m_eventManager.OnPermissionError += dm.SendAlertToUser;
+ }
+
+ public override string GetSimulatorVersion()
+ {
+ return m_simulatorVersion;
+ }
+
+ ///
+ /// Another region is up. Gets called from Grid Comms:
+ /// (OGS1 -> LocalBackEnd -> RegionListened -> SceneCommunicationService)
+ /// We have to tell all our ScenePresences about it, and add it to the
+ /// neighbor list.
+ ///
+ /// We only add it to the neighbor list if it's within 1 region from here.
+ /// Agents may have draw distance values that cross two regions though, so
+ /// we add it to the notify list regardless of distance. We'll check
+ /// the agent's draw distance before notifying them though.
+ ///
+ /// RegionInfo handle for the new region.
+ /// True after all operations complete, throws exceptions otherwise.
+ public override bool OtherRegionUp(RegionInfo otherRegion)
+ {
+ if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
+ {
+ for (int i = 0; i < m_neighbours.Count; i++)
+ {
+ // The purpose of this loop is to re-update the known neighbors
+ // when another region comes up on top of another one.
+ // The latest region in that location ends up in the
+ // 'known neighbors list'
+ // Additionally, the commFailTF property gets reset to false.
+ if (m_neighbours[i].RegionHandle == otherRegion.RegionHandle)
+ {
+ lock (m_neighbours)
+ {
+ m_neighbours[i] = otherRegion;
+ }
+ }
+ }
+
+ // If the value isn't in the neighbours, add it.
+ // If the RegionInfo isn't exact but is for the same XY World location,
+ // then the above loop will fix that.
+
+ if (!(CheckNeighborRegion(otherRegion)))
+ {
+ lock (m_neighbours)
+ {
+ m_neighbours.Add(otherRegion);
+ //m_log.Info("[UP]: " + otherRegion.RegionHandle.ToString());
+ }
+ }
+
+ // If these are cast to INT because long + negative values + abs returns invalid data
+ int resultX = Math.Abs((int)otherRegion.RegionLocX - (int)RegionInfo.RegionLocX);
+ int resultY = Math.Abs((int)otherRegion.RegionLocY - (int)RegionInfo.RegionLocY);
+ if (resultX <= 1 && resultY <= 1)
+ {
+ try
+ {
+ ForEachScenePresence(delegate(ScenePresence agent)
+ {
+ // If agent is a root agent.
+ if (!agent.IsChildAgent)
+ {
+ //agent.ControllingClient.new
+ //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
+ InformClientOfNeighbor(agent, otherRegion);
+ }
+ }
+ );
+ }
+ catch (NullReferenceException)
+ {
+ // This means that we're not booted up completely yet.
+ // This shouldn't happen too often anymore.
+ m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
+ }
+ }
+ else
+ {
+ m_log.Info("[INTERGRID]: Got notice about far away Region: " + otherRegion.RegionName.ToString() +
+ " at (" + otherRegion.RegionLocX.ToString() + ", " +
+ otherRegion.RegionLocY.ToString() + ")");
+ }
+ }
+ return true;
+ }
+
+ public void AddNeighborRegion(RegionInfo region)
+ {
+ lock (m_neighbours)
+ {
+ if (!CheckNeighborRegion(region))
+ {
+ m_neighbours.Add(region);
+ }
+ }
+ }
+
+ public bool CheckNeighborRegion(RegionInfo region)
+ {
+ bool found = false;
+ lock (m_neighbours)
+ {
+ foreach (RegionInfo reg in m_neighbours)
+ {
+ if (reg.RegionHandle == region.RegionHandle)
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ return found;
+ }
+
+ ///
+ /// Given float seconds, this will restart the region.
+ ///
+ /// float indicating duration before restart.
+ public virtual void Restart(float seconds)
+ {
+ // notifications are done in 15 second increments
+ // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
+ // It's a 'Cancel restart' request.
+
+ // RestartNow() does immediate restarting.
+ if (seconds < 15)
+ {
+ m_restartTimer.Stop();
+ m_dialogModule.SendGeneralAlert("Restart Aborted");
+ }
+ else
+ {
+ // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
+ m_restartTimer.Interval = 15000;
+ m_incrementsof15seconds = (int)seconds / 15;
+ m_RestartTimerCounter = 0;
+ m_restartTimer.AutoReset = true;
+ m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
+ m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
+ m_restartTimer.Start();
+ m_dialogModule.SendNotificationToUsersInRegion(
+ UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes");
+ }
+ }
+
+ // The Restart timer has occured.
+ // We have to figure out if this is a notification or if the number of seconds specified in Restart
+ // have elapsed.
+ // If they have elapsed, call RestartNow()
+ public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ m_RestartTimerCounter++;
+ if (m_RestartTimerCounter <= m_incrementsof15seconds)
+ {
+ if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
+ m_dialogModule.SendNotificationToUsersInRegion(
+ UUID.Random(),
+ String.Empty,
+ RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter) * 15) + " seconds");
+ }
+ else
+ {
+ m_restartTimer.Stop();
+ m_restartTimer.AutoReset = false;
+ RestartNow();
+ }
+ }
+
+ // This causes the region to restart immediatley.
+ public void RestartNow()
+ {
+ if (PhysicsScene != null)
+ {
+ PhysicsScene.Dispose();
+ }
+
+ m_log.Error("[REGION]: Closing");
+ Close();
+ m_log.Error("[REGION]: Firing Region Restart Message");
+ base.Restart(0);
+ }
+
+ // This is a helper function that notifies root agents in this region that a new sim near them has come up
+ // This is in the form of a timer because when an instance of OpenSim.exe is started,
+ // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
+ // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
+ // subsequently the agent will never see the region come back online.
+ public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
+ {
+ m_restartWaitTimer.Stop();
+ lock (m_regionRestartNotifyList)
+ {
+ foreach (RegionInfo region in m_regionRestartNotifyList)
+ {
+ try
+ {
+ ForEachScenePresence(delegate(ScenePresence agent)
+ {
+ // If agent is a root agent.
+ if (!agent.IsChildAgent)
+ {
+ //agent.ControllingClient.new
+ //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
+ InformClientOfNeighbor(agent, region);
+ }
+ }
+ );
+ }
+ catch (NullReferenceException)
+ {
+ // This means that we're not booted up completely yet.
+ // This shouldn't happen too often anymore.
+ }
+ }
+
+ // Reset list to nothing.
+ m_regionRestartNotifyList.Clear();
+ }
+ }
+
+ public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine)
+ {
+ if (m_scripts_enabled != !ScriptEngine)
+ {
+ // Tedd! Here's the method to disable the scripting engine!
+ if (ScriptEngine)
+ {
+ m_log.Info("Stopping all Scripts in Scene");
+ foreach (EntityBase ent in Entities)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ ((SceneObjectGroup) ent).RemoveScriptInstances();
+ }
+ }
+ }
+ else
+ {
+ m_log.Info("Starting all Scripts in Scene");
+ lock (Entities)
+ {
+ foreach (EntityBase ent in Entities)
+ {
+ if (ent is SceneObjectGroup)
+ {
+ ((SceneObjectGroup)ent).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
+ }
+ }
+ }
+ }
+ m_scripts_enabled = !ScriptEngine;
+ m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
+ }
+
+ if (m_physics_enabled != !PhysicsEngine)
+ {
+ m_physics_enabled = !PhysicsEngine;
+ }
+ }
+
+ public int GetInaccurateNeighborCount()
+ {
+ lock (m_neighbours)
+ {
+ return m_neighbours.Count;
+ }
+ }
+
+ // This is the method that shuts down the scene.
+ public override void Close()
+ {
+ m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
+
+ // Kick all ROOT agents with the message, 'The simulator is going down'
+ ForEachScenePresence(delegate(ScenePresence avatar)
+ {
+ if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
+ avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
+
+ if (!avatar.IsChildAgent)
+ avatar.ControllingClient.Kick("The simulator is going down.");
+
+ avatar.ControllingClient.SendShutdownConnectionNotice();
+ });
+
+ // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
+ Thread.Sleep(500);
+
+ // Stop all client threads.
+ ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); });
+
+ // Stop updating the scene objects and agents.
+ //m_heartbeatTimer.Close();
+ shuttingdown = true;
+
+ m_log.Debug("[SCENE]: Persisting changed objects");
+ List entities = GetEntities();
+ foreach (EntityBase entity in entities)
+ {
+ if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
+ {
+ ((SceneObjectGroup)entity).ProcessBackup(m_storageManager.DataStore, false);
+ }
+ }
+
+ m_sceneGraph.Close();
+
+ // De-register with region communications (events cleanup)
+ UnRegisterRegionWithComms();
+
+ // call the base class Close method.
+ base.Close();
+ }
+
+ ///
+ /// Start the timer which triggers regular scene updates
+ ///
+ public void StartTimer()
+ {
+ //m_log.Debug("[SCENE]: Starting timer");
+ //m_heartbeatTimer.Enabled = true;
+ //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
+ //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
+ HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat));
+ HeartbeatThread.SetApartmentState(ApartmentState.MTA);
+ HeartbeatThread.Name = "Heartbeat";
+ HeartbeatThread.Priority = ThreadPriority.AboveNormal;
+ ThreadTracker.Add(HeartbeatThread);
+ HeartbeatThread.Start();
+ }
+
+ ///
+ /// Sets up references to modules required by the scene
+ ///
+ public void SetModuleInterfaces()
+ {
+ m_xmlrpcModule = RequestModuleInterface();
+ m_worldCommModule = RequestModuleInterface();
+ XferManager = RequestModuleInterface();
+ m_AvatarFactory = RequestModuleInterface();
+ m_serialiser = RequestModuleInterface();
+ m_interregionCommsOut = RequestModuleInterface();
+ m_interregionCommsIn = RequestModuleInterface();
+ m_dialogModule = RequestModuleInterface();
+ m_capsModule = RequestModuleInterface();
+ }
+
+ #endregion
+
+ #region Update Methods
+
+ ///
+ /// Performs per-frame updates regularly
+ ///
+ ///
+ ///
+ private void Heartbeat(object sender)
+ {
+ Update();
+ }
+
+ ///
+ /// Performs per-frame updates on the scene, this should be the central scene loop
+ ///
+ public override void Update()
+ {
+ int maintc = 0;
+ while (!shuttingdown)
+ {
+ maintc = System.Environment.TickCount;
+
+ TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
+ // Aquire a lock so only one update call happens at once
+ //updateLock.WaitOne();
+ float physicsFPS = 0;
+ //m_log.Info("sadfadf" + m_neighbours.Count.ToString());
+ int agentsInScene = m_sceneGraph.GetRootAgentCount() + m_sceneGraph.GetChildAgentCount();
+
+ if (agentsInScene > 21)
+ {
+ if (m_update_entities == 1)
+ {
+ m_update_entities = 5;
+ StatsReporter.SetUpdateMS(6000);
+ }
+ }
+ else
+ {
+ if (m_update_entities == 5)
+ {
+ m_update_entities = 1;
+ StatsReporter.SetUpdateMS(3000);
+ }
+ }
+
+ frameMS = System.Environment.TickCount;
+ try
+ {
+ // Increment the frame counter
+ m_frame++;
+
+ // Loop it
+ if (m_frame == Int32.MaxValue)
+ m_frame = 0;
+
+ physicsMS2 = System.Environment.TickCount;
+ if ((m_frame % m_update_physics == 0) && m_physics_enabled)
+ m_sceneGraph.UpdatePreparePhysics();
+ physicsMS2 = System.Environment.TickCount - physicsMS2;
+
+ if (m_frame % m_update_entitymovement == 0)
+ m_sceneGraph.UpdateEntityMovement();
+
+ physicsMS = System.Environment.TickCount;
+ if ((m_frame % m_update_physics == 0) && m_physics_enabled)
+ physicsFPS = m_sceneGraph.UpdatePhysics(
+ Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
+ );
+ if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
+ SynchronizeScene(this);
+
+ physicsMS = System.Environment.TickCount - physicsMS;
+ physicsMS += physicsMS2;
+
+ otherMS = System.Environment.TickCount;
+ // run through all entities looking for updates (slow)
+ if (m_frame % m_update_entities == 0)
+ m_sceneGraph.UpdateEntities();
+
+ // run through entities that have scheduled themselves for
+ // updates looking for updates(faster)
+ if (m_frame % m_update_entitiesquick == 0)
+ m_sceneGraph.ProcessUpdates();
+
+ // Run through scenepresences looking for updates
+ if (m_frame % m_update_presences == 0)
+ m_sceneGraph.UpdatePresences();
+
+ // Delete temp-on-rez stuff
+ if (m_frame % m_update_backup == 0)
+ CleanTempObjects();
+
+ if (Region_Status != RegionStatus.SlaveScene)
+ {
+ if (m_frame % m_update_events == 0)
+ UpdateEvents();
+
+ if (m_frame % m_update_backup == 0)
+ {
+ UpdateStorageBackup();
+ }
+
+ if (m_frame % m_update_terrain == 0)
+ UpdateTerrain();
+
+ if (m_frame % m_update_land == 0)
+ UpdateLand();
+ otherMS = System.Environment.TickCount - otherMS;
+ // if (m_frame%m_update_avatars == 0)
+ // UpdateInWorldTime();
+ StatsReporter.AddPhysicsFPS(physicsFPS);
+ StatsReporter.AddTimeDilation(m_timedilation);
+ StatsReporter.AddFPS(1);
+ StatsReporter.AddInPackets(0);
+ StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
+ StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
+ StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
+ StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
+ frameMS = System.Environment.TickCount - frameMS;
+ StatsReporter.addFrameMS(frameMS);
+ StatsReporter.addPhysicsMS(physicsMS);
+ StatsReporter.addOtherMS(otherMS);
+ StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
+ StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
+ }
+ }
+ catch (NotImplementedException)
+ {
+ throw;
+ }
+ catch (AccessViolationException e)
+ {
+ m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ //catch (NullReferenceException e)
+ //{
+ // m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ //}
+ catch (InvalidOperationException e)
+ {
+ m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
+ }
+ finally
+ {
+ //updateLock.ReleaseMutex();
+ // Get actual time dilation
+ float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds);
+
+ // If actual time dilation is greater then one, we're catching up, so subtract
+ // the amount that's greater then 1 from the time dilation
+ if (tmpval > 1.0)
+ {
+ tmpval = tmpval - (tmpval - 1.0f);
+ }
+ m_timedilation = tmpval;
+
+ m_lastupdate = DateTime.Now;
+ }
+ maintc = System.Environment.TickCount - maintc;
+ maintc = (int)(m_timespan * 1000) - maintc;
+
+ if ((maintc < (m_timespan * 1000)) && maintc > 0)
+ Thread.Sleep(maintc);
+ }
+ }
+
+ private void SendSimStatsPackets(SimStats stats)
+ {
+ List StatSendAgents = GetScenePresences();
+ foreach (ScenePresence agent in StatSendAgents)
+ {
+ if (!agent.IsChildAgent)
+ {
+ agent.ControllingClient.SendSimStats(stats);
+ }
+ }
+ }
+
+ private void UpdateLand()
+ {
+ if (LandChannel != null)
+ {
+ if (LandChannel.IsLandPrimCountTainted())
+ {
+ EventManager.TriggerParcelPrimCountUpdate();
+ }
+ }
+ }
+
+ private void UpdateTerrain()
+ {
+ EventManager.TriggerTerrainTick();
+ }
+
+ private void UpdateStorageBackup()
+ {
+ if (!m_backingup)
+ {
+ m_backingup = true;
+ Thread backupthread = new Thread(Backup);
+ backupthread.Name = "BackupWriter";
+ backupthread.IsBackground = true;
+ backupthread.Start();
+ }
+ }
+
+ private void UpdateEvents()
+ {
+ m_eventManager.TriggerOnFrame();
+ }
+
+ ///
+ /// Perform delegate action on all clients subscribing to updates from this region.
+ ///
+ ///
+ public void Broadcast(Action whatToDo)
+ {
+ ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); });
+ }
+
+ ///
+ /// Backup the scene. This acts as the main method of the backup thread.
+ ///
+ ///
+ public void Backup()
+ {
+ lock (m_returns)
+ {
+ EventManager.TriggerOnBackup(m_storageManager.DataStore);
+ m_backingup = false;
+
+ foreach (KeyValuePair ret in m_returns)
+ {
+ UUID transaction = UUID.Random();
+
+ GridInstantMessage msg = new GridInstantMessage();
+ msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
+ msg.toAgentID = new Guid(ret.Key.ToString());
+ msg.imSessionID = new Guid(transaction.ToString());
+ msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
+ msg.fromAgentName = "Server";
+ msg.dialog = (byte)19; // Object msg
+ msg.fromGroup = false;
+ msg.offline = (byte)1;
+ msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = RegionInfo.RegionID.Guid;
+ msg.binaryBucket = new byte[0];
+ if (ret.Value.count > 1)
+ msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
+ else
+ msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
+
+ IMessageTransferModule tr = RequestModuleInterface();
+ if (tr != null)
+ tr.SendInstantMessage(msg, delegate(bool success) {} );
+ }
+ m_returns.Clear();
+ }
+ }
+
+ public void ForceSceneObjectBackup(SceneObjectGroup group)
+ {
+ if (group != null)
+ {
+ group.ProcessBackup(m_storageManager.DataStore, true);
+ }
+ }
+
+ public void AddReturn(UUID agentID, string objectName, Vector3 location, string reason)
+ {
+ lock (m_returns)
+ {
+ if (m_returns.ContainsKey(agentID))
+ {
+ ReturnInfo info = m_returns[agentID];
+ info.count++;
+ m_returns[agentID] = info;
+ }
+ else
+ {
+ ReturnInfo info = new ReturnInfo();
+ info.count = 1;
+ info.objectName = objectName;
+ info.location = location;
+ info.reason = reason;
+ m_returns[agentID] = info;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Load Terrain
+
+ public void ExportWorldMap(string fileName)
+ {
+ List mapBlocks =
+ m_sceneGridService.RequestNeighbourMapBlocks((int)(RegionInfo.RegionLocX - 9),
+ (int)(RegionInfo.RegionLocY - 9),
+ (int)(RegionInfo.RegionLocX + 9),
+ (int)(RegionInfo.RegionLocY + 9));
+ List textures = new List();
+ List bitImages = new List();
+
+ foreach (MapBlockData mapBlock in mapBlocks)
+ {
+ AssetBase texAsset = AssetCache.GetAsset(mapBlock.MapImageId, true);
+
+ if (texAsset != null)
+ {
+ textures.Add(texAsset);
+ }
+ else
+ {
+ texAsset = AssetCache.GetAsset(mapBlock.MapImageId, true);
+ if (texAsset != null)
+ {
+ textures.Add(texAsset);
+ }
+ }
+ }
+
+ foreach (AssetBase asset in textures)
+ {
+ ManagedImage managedImage;
+ Image image;
+
+ if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image))
+ bitImages.Add(image);
+ }
+
+ Bitmap mapTexture = new Bitmap(2560, 2560);
+ Graphics g = Graphics.FromImage(mapTexture);
+ SolidBrush sea = new SolidBrush(Color.DarkBlue);
+ g.FillRectangle(sea, 0, 0, 2560, 2560);
+
+ for (int i = 0; i < mapBlocks.Count; i++)
+ {
+ ushort x = (ushort)((mapBlocks[i].X - RegionInfo.RegionLocX) + 10);
+ ushort y = (ushort)((mapBlocks[i].Y - RegionInfo.RegionLocY) + 10);
+ g.DrawImage(bitImages[i], (x * 128), (y * 128), 128, 128);
+ }
+ mapTexture.Save(fileName, ImageFormat.Jpeg);
+ }
+
+ public void SaveTerrain()
+ {
+ m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
+ }
+
+ ///
+ /// Loads the World heightmap
+ ///
+ public override void LoadWorldMap()
+ {
+ try
+ {
+ double[,] map = m_storageManager.DataStore.LoadTerrain(RegionInfo.RegionID);
+ if (map == null)
+ {
+ m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain.");
+ Heightmap = new TerrainChannel();
+
+ m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
+ }
+ else
+ {
+ Heightmap = new TerrainChannel(map);
+ }
+
+ }
+ catch (Exception e)
+ {
+ m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString());
+ }
+ }
+
+ ///
+ /// Register this region with a grid service
+ ///
+ /// Thrown if registration of the region itself fails.
+ public void RegisterRegionWithGrid()
+ {
+ RegisterCommsEvents();
+
+ // These two 'commands' *must be* next to each other or sim rebooting fails.
+ m_sceneGridService.RegisterRegion(m_interregionCommsOut, RegionInfo);
+ m_sceneGridService.InformNeighborsThatRegionisUp(RegionInfo);
+
+ Dictionary dGridSettings = m_sceneGridService.GetGridSettings();
+
+ if (dGridSettings.ContainsKey("allow_forceful_banlines"))
+ {
+ if (dGridSettings["allow_forceful_banlines"] != "TRUE")
+ {
+ m_log.Info("[GRID]: Grid is disabling forceful parcel banlists");
+ EventManager.TriggerSetAllowForcefulBan(false);
+ }
+ else
+ {
+ m_log.Info("[GRID]: Grid is allowing forceful parcel banlists");
+ EventManager.TriggerSetAllowForcefulBan(true);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void CreateTerrainTexture(bool temporary)
+ {
+ //create a texture asset of the terrain
+ IMapImageGenerator terrain = RequestModuleInterface();
+
+ // Cannot create a map for a nonexistant heightmap yet.
+ if (Heightmap == null)
+ return;
+
+ if (terrain == null)
+ {
+ #region Fallback default maptile generation
+
+ int tc = System.Environment.TickCount;
+ m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");
+ Bitmap mapbmp = new Bitmap(256, 256);
+ double[,] hm = Heightmap.GetDoubles();
+ bool ShadowDebugContinue = true;
+ //Color prim = Color.FromArgb(120, 120, 120);
+ //Vector3 RayEnd = new Vector3(0, 0, 0);
+ //Vector3 RayStart = new Vector3(0, 0, 0);
+ //Vector3 direction = new Vector3(0, 0, -1);
+ //Vector3 AXOrigin = new Vector3();
+ //Vector3 AXdirection = new Vector3();
+ //Ray testRay = new Ray();
+ //EntityIntersection rt = new EntityIntersection();
+ bool terraincorruptedwarningsaid = false;
+
+ float low = 255;
+ float high = 0;
+ for (int x = 0; x < 256; x++)
+ {
+ for (int y = 0; y < 256; y++)
+ {
+ float hmval = (float)hm[x, y];
+ if (hmval < low)
+ low = hmval;
+ if (hmval > high)
+ high = hmval;
+ }
+ }
+
+ float mid = (high + low) * 0.5f;
+
+ // temporary initializer
+ float hfvalue = (float)m_regInfo.RegionSettings.WaterHeight;
+ float hfvaluecompare = hfvalue;
+ float hfdiff = hfvalue;
+ int hfdiffi = 0;
+
+ for (int x = 0; x < 256; x++)
+ {
+ //int tc = System.Environment.TickCount;
+ for (int y = 0; y < 256; y++)
+ {
+ //RayEnd = new Vector3(x, y, 0);
+ //RayStart = new Vector3(x, y, 255);
+
+ //direction = Vector3.Norm(RayEnd - RayStart);
+ //AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
+ //AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
+
+ //testRay = new Ray(AXOrigin, AXdirection);
+ //rt = m_sceneGraph.GetClosestIntersectingPrim(testRay);
+
+ //if (rt.HitTF)
+ //{
+ //mapbmp.SetPixel(x, y, prim);
+ //}
+ //else
+ //{
+ //float tmpval = (float)hm[x, y];
+ float heightvalue = (float)hm[x, y];
+
+ if (heightvalue > (float)m_regInfo.RegionSettings.WaterHeight)
+ {
+ // scale height value
+ heightvalue = low + mid * (heightvalue - low) / mid;
+
+ if (heightvalue > 255)
+ heightvalue = 255;
+
+ if (heightvalue < 0)
+ heightvalue = 0;
+
+ if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
+ heightvalue = 0;
+
+ try
+ {
+ Color green = Color.FromArgb((int)heightvalue, 100, (int)heightvalue);
+
+ // Y flip the cordinates
+ mapbmp.SetPixel(x, (256 - y) - 1, green);
+
+ //X
+ // .
+ //
+ // Shade the terrain for shadows
+ if ((x - 1 > 0) && (y - 1 > 0))
+ {
+ hfvalue = (float)hm[x, y];
+ hfvaluecompare = (float)hm[x - 1, y - 1];
+
+ if (Single.IsInfinity(hfvalue) || Single.IsNaN(hfvalue))
+ hfvalue = 0;
+
+ if (Single.IsInfinity(hfvaluecompare) || Single.IsNaN(hfvaluecompare))
+ hfvaluecompare = 0;
+
+ hfdiff = hfvaluecompare - hfvalue;
+
+ if (hfdiff > 0.3f)
+ {
+
+ }
+ else if (hfdiff < -0.3f)
+ {
+ // We have to desaturate and blacken the land at the same time
+ // we use floats, colors use bytes, so shrink are space down to
+ // 0-255
+
+ try
+ {
+ hfdiffi = Math.Abs((int)((hfdiff * 4) + (hfdiff * 0.5))) + 1;
+ if (hfdiff % 1 != 0)
+ {
+ hfdiffi = hfdiffi + Math.Abs((int)(((hfdiff % 1) * 0.5f) * 10f) - 1);
+ }
+ }
+ catch (System.OverflowException)
+ {
+ m_log.Debug("[MAPTILE]: Shadow failed at value: " + hfdiff.ToString());
+ ShadowDebugContinue = false;
+ }
+
+ if (ShadowDebugContinue)
+ {
+ if ((256 - y) - 1 > 0)
+ {
+ Color Shade = mapbmp.GetPixel(x - 1, (256 - y) - 1);
+
+ int r = Shade.R;
+
+ int g = Shade.G;
+ int b = Shade.B;
+ Shade = Color.FromArgb((r - hfdiffi > 0) ? r - hfdiffi : 0, (g - hfdiffi > 0) ? g - hfdiffi : 0, (b - hfdiffi > 0) ? b - hfdiffi : 0);
+ //Console.WriteLine("d:" + hfdiff.ToString() + ", i:" + hfdiffi + ", pos: " + x + "," + y + " - R:" + Shade.R.ToString() + ", G:" + Shade.G.ToString() + ", B:" + Shade.G.ToString());
+ mapbmp.SetPixel(x - 1, (256 - y) - 1, Shade);
+ }
+ }
+ }
+ }
+ }
+ catch (System.ArgumentException)
+ {
+ if (!terraincorruptedwarningsaid)
+ {
+ m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", RegionInfo.RegionName);
+ terraincorruptedwarningsaid = true;
+ }
+ Color black = Color.Black;
+ mapbmp.SetPixel(x, (256 - y) - 1, black);
+ }
+ }
+ else
+ {
+ // Y flip the cordinates
+ heightvalue = (float)m_regInfo.RegionSettings.WaterHeight - heightvalue;
+ if (heightvalue > 19)
+ heightvalue = 19;
+ if (heightvalue < 0)
+ heightvalue = 0;
+
+ heightvalue = 100 - (heightvalue * 100) / 19;
+
+ if (heightvalue > 255)
+ heightvalue = 255;
+
+ if (heightvalue < 0)
+ heightvalue = 0;
+
+ if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
+ heightvalue = 0;
+
+ try
+ {
+ Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255);
+ mapbmp.SetPixel(x, (256 - y) - 1, water);
+ }
+ catch (System.ArgumentException)
+ {
+ if (!terraincorruptedwarningsaid)
+ {
+ m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", RegionInfo.RegionName);
+ terraincorruptedwarningsaid = true;
+ }
+ Color black = Color.Black;
+ mapbmp.SetPixel(x, (256 - y) - 1, black);
+ }
+ }
+ }
+ //}
+
+ //tc = System.Environment.TickCount - tc;
+ //m_log.Info("[MAPTILE]: Completed One row in " + tc + " ms");
+ }
+
+ m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (System.Environment.TickCount - tc) + " ms");
+
+ bool drawPrimVolume = true;
+
+ try
+ {
+ IConfig startupConfig = m_config.Configs["Startup"];
+ drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", true);
+ }
+ catch
+ {
+ m_log.Warn("[MAPTILE]: Failed to load StartupConfig");
+ }
+
+ if (drawPrimVolume)
+ {
+ tc = System.Environment.TickCount;
+ m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
+ List objs = GetEntities();
+
+ lock (objs)
+ {
+ foreach (EntityBase obj in objs)
+ {
+ // Only draw the contents of SceneObjectGroup
+ if (obj is SceneObjectGroup)
+ {
+ SceneObjectGroup mapdot = (SceneObjectGroup)obj;
+ Color mapdotspot = Color.Gray; // Default color when prim color is white
+ // Loop over prim in group
+ foreach (SceneObjectPart part in mapdot.Children.Values)
+ {
+ if (part == null)
+ continue;
+
+ // Draw if the object is at least 1 meter wide in any direction
+ if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
+ {
+ // Try to get the RGBA of the default texture entry..
+ //
+ try
+ {
+ if (part == null)
+ continue;
+
+ if (part.Shape == null)
+ continue;
+
+ if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree)
+ continue; // eliminates trees from this since we don't really have a good tree representation
+ // if you want tree blocks on the map comment the above line and uncomment the below line
+ //mapdotspot = Color.PaleGreen;
+
+ if (part.Shape.Textures == null)
+ continue;
+
+ if (part.Shape.Textures.DefaultTexture == null)
+ continue;
+
+ Color4 texcolor = part.Shape.Textures.DefaultTexture.RGBA;
+
+ // Not sure why some of these are null, oh well.
+
+ int colorr = 255 - (int)(texcolor.R * 255f);
+ int colorg = 255 - (int)(texcolor.G * 255f);
+ int colorb = 255 - (int)(texcolor.B * 255f);
+
+ if (!(colorr == 255 && colorg == 255 && colorb == 255))
+ {
+ //Try to set the map spot color
+ try
+ {
+ // If the color gets goofy somehow, skip it *shakes fist at Color4
+ mapdotspot = Color.FromArgb(colorr, colorg, colorb);
+ }
+ catch (ArgumentException)
+ {
+ }
+ }
+ }
+ catch (IndexOutOfRangeException)
+ {
+ // Windows Array
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ // Mono Array
+ }
+
+ Vector3 pos = part.GetWorldPosition();
+
+ // skip prim outside of retion
+ if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
+ continue;
+
+ // skip prim in non-finite position
+ if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || Single.IsInfinity(pos.X)
+ || Single.IsInfinity(pos.Y))
+ continue;
+
+ // Figure out if object is under 256m above the height of the terrain
+ bool isBelow256AboveTerrain = false;
+
+ try
+ {
+ isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
+ }
+ catch (Exception)
+ {
+ }
+
+ if (isBelow256AboveTerrain)
+ {
+ // Translate scale by rotation so scale is represented properly when object is rotated
+ Vector3 scale = part.Shape.Scale;
+ Quaternion rot = part.GetWorldRotation();
+ scale *= rot;
+
+ // negative scales don't work in this situation
+ scale.X = Math.Abs(scale.X);
+ scale.Y = Math.Abs(scale.Y);
+ scale.Z = Math.Abs(scale.Z);
+
+ // This scaling isn't very accurate and doesn't take into account the face rotation :P
+ int mapdrawstartX = (int)(pos.X - scale.X);
+ int mapdrawstartY = (int)(pos.Y - scale.Y);
+ int mapdrawendX = (int)(pos.X + scale.X);
+ int mapdrawendY = (int)(pos.Y + scale.Y);
+
+ // If object is beyond the edge of the map, don't draw it to avoid errors
+ if (mapdrawstartX < 0 || mapdrawstartX > 255 || mapdrawendX < 0 || mapdrawendX > 255
+ || mapdrawstartY < 0 || mapdrawstartY > 255 || mapdrawendY < 0
+ || mapdrawendY > 255)
+ continue;
+
+ int wy = 0;
+
+ bool breakYN = false; // If we run into an error drawing, break out of the
+ // loop so we don't lag to death on error handling
+ for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
+ {
+ for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
+ {
+ //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
+ try
+ {
+ // Remember, flip the y!
+ mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
+ }
+ catch (ArgumentException)
+ {
+ breakYN = true;
+ }
+
+ if (breakYN)
+ break;
+ }
+
+ if (breakYN)
+ break;
+ }
+ } // Object is within 256m Z of terrain
+ } // object is at least a meter wide
+ } // loop over group children
+ } // entitybase is sceneobject group
+ } // foreach loop over entities
+ } // lock entities objs
+
+ m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (System.Environment.TickCount - tc) + " ms");
+ } // end if drawPrimOnMaptle
+
+ byte[] data;
+ try
+ {
+ data = OpenJPEG.EncodeFromImage(mapbmp, false);
+ }
+ catch (Exception)
+ {
+ return;
+ }
+
+ LazySaveGeneratedMaptile(data,temporary);
+
+ #endregion
+ }
+ else
+ {
+ // Use the module to generate the maptile.
+ byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
+ if (data != null)
+ {
+ LazySaveGeneratedMaptile(data,temporary);
+ }
+ }
+ }
+
+ public void LazySaveGeneratedMaptile(byte[] data, bool temporary)
+ {
+ // Overwrites the local Asset cache with new maptile data
+ // Assets are single write, this causes the asset server to ignore this update,
+ // but the local asset cache does not
+
+ // this is on purpose! The net result of this is the region always has the most up to date
+ // map tile while protecting the (grid) asset database from bloat caused by a new asset each
+ // time a mapimage is generated!
+
+ UUID lastMapRegionUUID = m_regInfo.lastMapUUID;
+
+ int lastMapRefresh = 0;
+ int twoDays = 172800;
+ int RefreshSeconds = twoDays;
+
+ try
+ {
+ lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh);
+ }
+ catch (ArgumentException)
+ {
+ }
+ catch (FormatException)
+ {
+ }
+ catch (OverflowException)
+ {
+ }
+
+ UUID TerrainImageUUID = UUID.Random();
+
+ if (lastMapRegionUUID == UUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch())
+ {
+ m_regInfo.SaveLastMapUUID(TerrainImageUUID);
+
+ m_log.Warn("[MAPTILE]: STORING MAPTILE IMAGE");
+ }
+ else
+ {
+ TerrainImageUUID = lastMapRegionUUID;
+ m_log.Warn("[MAPTILE]: REUSING OLD MAPTILE IMAGE ID");
+ }
+
+ m_regInfo.RegionSettings.TerrainImageID = TerrainImageUUID;
+
+ AssetBase asset = new AssetBase();
+ asset.Metadata.FullID = m_regInfo.RegionSettings.TerrainImageID;
+ asset.Data = data;
+ asset.Metadata.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
+ asset.Metadata.Description = RegionInfo.RegionName;
+
+ asset.Metadata.Type = 0;
+ asset.Metadata.Temporary = temporary;
+ AssetCache.AddAsset(asset);
+ }
+
+ #endregion
+
+ #region Load Land
+
+ public void loadAllLandObjectsFromStorage(UUID regionID)
+ {
+ m_log.Info("[SCENE]: Loading land objects from storage");
+ List landData = m_storageManager.DataStore.LoadLandObjects(regionID);
+
+ if (LandChannel != null)
+ {
+ if (landData.Count == 0)
+ {
+ EventManager.TriggerNoticeNoLandDataFromStorage();
+ }
+ else
+ {
+ EventManager.TriggerIncomingLandDataFromStorage(landData);
+ }
+ }
+ else
+ {
+ m_log.Error("[SCENE]: Land Channel is not defined. Cannot load from storage!");
+ }
+ }
+
+ #endregion
+
+ #region Primitives Methods
+
+ ///
+ /// Loads the World's objects
+ ///
+ public virtual void LoadPrimsFromStorage(UUID regionID)
+ {
+ m_log.Info("[SCENE]: Loading objects from datastore");
+
+ List PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID);
+ foreach (SceneObjectGroup group in PrimsFromDB)
+ {
+ if (group.RootPart == null)
+ {
+ m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
+ group.Children == null ? 0 : group.Children.Count);
+ }
+
+ AddRestoredSceneObject(group, true, true);
+ SceneObjectPart rootPart = group.GetChildPart(group.UUID);
+ rootPart.ObjectFlags &= ~(uint)PrimFlags.Scripted;
+ rootPart.TrimPermissions();
+ group.CheckSculptAndLoad();
+ //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
+ }
+
+ m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
+ }
+
+ public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
+ {
+ Vector3 pos = Vector3.Zero;
+ if (RayEndIsIntersection == (byte)1)
+ {
+ pos = RayEnd;
+ return pos;
+ }
+
+ if (RayTargetID != UUID.Zero)
+ {
+ SceneObjectPart target = GetSceneObjectPart(RayTargetID);
+
+ Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
+ Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
+ Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
+
+ if (target != null)
+ {
+ pos = target.AbsolutePosition;
+ //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
+
+ // TODO: Raytrace better here
+
+ //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
+ Ray NewRay = new Ray(AXOrigin, AXdirection);
+
+ // Ray Trace against target here
+ EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
+
+ // Un-comment out the following line to Get Raytrace results printed to the console.
+ // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
+ float ScaleOffset = 0.5f;
+
+ // If we hit something
+ if (ei.HitTF)
+ {
+ Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
+ if (scaleComponent.X != 0) ScaleOffset = scale.X;
+ if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
+ if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
+ ScaleOffset = Math.Abs(ScaleOffset);
+ Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
+ Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
+ // Set the position to the intersection point
+ Vector3 offset = (normal * (ScaleOffset / 2f));
+ pos = (intersectionpoint + offset);
+
+ // Un-offset the prim (it gets offset later by the consumer method)
+ pos.Z -= 0.25F;
+ }
+
+ return pos;
+ }
+ else
+ {
+ // We don't have a target here, so we're going to raytrace all the objects in the scene.
+
+ EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
+
+ // Un-comment the following line to print the raytrace results to the console.
+ //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
+
+ if (ei.HitTF)
+ {
+ pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
+ } else
+ {
+ // fall back to our stupid functionality
+ pos = RayEnd;
+ }
+
+ return pos;
+ }
+ }
+ else
+ {
+ // fall back to our stupid functionality
+ pos = RayEnd;
+ return pos;
+ }
+ }
+
+ public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
+ byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
+ byte RayEndIsIntersection)
+ {
+ Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);
+
+ if (Permissions.CanRezObject(1, ownerID, pos))
+ {
+ // rez ON the ground, not IN the ground
+ pos.Z += 0.25F;
+
+ AddNewPrim(ownerID, groupID, pos, rot, shape);
+ }
+ }
+
+ public virtual SceneObjectGroup AddNewPrim(
+ UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
+ {
+ //m_log.DebugFormat(
+ // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
+
+ // If an entity creator has been registered for this prim type then use that
+ if (m_entityCreators.ContainsKey((PCode)shape.PCode))
+ return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
+
+ // Otherwise, use this default creation code;
+ SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
+ AddNewSceneObject(sceneObject, true);
+ sceneObject.SetGroup(groupID, null);
+
+ return sceneObject;
+ }
+
+ ///
+ /// Add an object into the scene that has come from storage
+ ///
+ ///
+ ///
+ ///
+ /// If true, changes to the object will be reflected in its persisted data
+ /// If false, the persisted data will not be changed even if the object in the scene is changed
+ ///
+ ///
+ /// If true, we won't persist this object until it changes
+ /// If false, we'll persist this object immediately
+ ///
+ ///
+ /// true if the object was added, false if an object with the same uuid was already in the scene
+ ///
+ public bool AddRestoredSceneObject(
+ SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
+ {
+ return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted);
+ }
+
+ ///
+ /// Add a newly created object to the scene
+ ///
+ ///
+ ///
+ /// If true, the object is made persistent into the scene.
+ /// If false, the object will not persist over server restarts
+ ///
+ public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
+ {
+ return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup);
+ }
+
+ ///
+ /// Delete every object from the scene
+ ///
+ public void DeleteAllSceneObjects()
+ {
+ lock (Entities)
+ {
+ ICollection entities = new List(Entities);
+
+ foreach (EntityBase e in entities)
+ {
+ if (e is SceneObjectGroup)
+ DeleteSceneObject((SceneObjectGroup)e, false);
+ }
+ }
+ }
+
+ ///
+ /// Synchronously delete the given object from the scene.
+ ///
+ /// Object Id
+ /// Suppress broadcasting changes to other clients.
+ public void DeleteSceneObject(SceneObjectGroup group, bool silent)
+ {
+ //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
+
+ // Serialise calls to RemoveScriptInstances to avoid
+ // deadlocking on m_parts inside SceneObjectGroup
+ lock (m_deleting_scene_object)
+ {
+ group.RemoveScriptInstances();
+ }
+
+ foreach (SceneObjectPart part in group.Children.Values)
+ {
+ if (part.IsJoint() && ((part.ObjectFlags&(uint)PrimFlags.Physics) != 0) )
+ {
+ PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
+ }
+ else if (part.PhysActor != null)
+ {
+ PhysicsScene.RemovePrim(part.PhysActor);
+ part.PhysActor = null;
+ }
+ }
+// if (rootPart.PhysActor != null)
+// {
+// PhysicsScene.RemovePrim(rootPart.PhysActor);
+// rootPart.PhysActor = null;
+// }
+
+ if (UnlinkSceneObject(group.UUID, false))
+ {
+ EventManager.TriggerObjectBeingRemovedFromScene(group);
+ EventManager.TriggerParcelPrimCountTainted();
+ }
+
+ group.DeleteGroup(silent);
+ }
+
+ ///
+ /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
+ /// object itself is not destroyed.
+ ///
+ /// Id of object.
+ /// true if the object was in the scene, false if it was not
+ /// If true, only deletes from scene, but keeps object in database.
+ public bool UnlinkSceneObject(UUID uuid, bool softDelete)
+ {
+ if (m_sceneGraph.DeleteSceneObject(uuid, softDelete))
+ {
+ if (!softDelete)
+ {
+ m_storageManager.DataStore.RemoveObject(uuid,
+ m_regInfo.RegionID);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Move the given scene object into a new region depending on which region its absolute position has moved
+ /// into.
+ ///
+ /// This method locates the new region handle and offsets the prim position for the new region
+ ///
+ /// the attempted out of region position of the scene object
+ /// the scene object that we're crossing
+ public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
+ {
+ if (grp == null)
+ return;
+ if (grp.IsDeleted)
+ return;
+
+ if (grp.RootPart.DIE_AT_EDGE)
+ {
+ // We remove the object here
+ try
+ {
+ DeleteSceneObject(grp, false);
+ }
+ catch (Exception)
+ {
+ m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
+ }
+ return;
+ }
+
+ int thisx = (int)RegionInfo.RegionLocX;
+ int thisy = (int)RegionInfo.RegionLocY;
+
+ ulong newRegionHandle = 0;
+ Vector3 pos = attemptedPosition;
+
+ if (attemptedPosition.X > Constants.RegionSize + 0.1f)
+ {
+ pos.X = ((pos.X - Constants.RegionSize));
+ newRegionHandle
+ = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
+ // x + 1
+ }
+ else if (attemptedPosition.X < -0.1f)
+ {
+ pos.X = ((pos.X + Constants.RegionSize));
+ newRegionHandle
+ = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
+ // x - 1
+ }
+
+ if (attemptedPosition.Y > Constants.RegionSize + 0.1f)
+ {
+ pos.Y = ((pos.Y - Constants.RegionSize));
+ newRegionHandle
+ = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize));
+ // y + 1
+ }
+ else if (attemptedPosition.Y < -0.1f)
+ {
+ pos.Y = ((pos.Y + Constants.RegionSize));
+ newRegionHandle
+ = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
+ // y - 1
+ }
+
+ // Offset the positions for the new region across the border
+ Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
+ grp.OffsetForNewRegion(pos);
+
+ // If we fail to cross the border, then reset the position of the scene object on that border.
+ if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent))
+ {
+ grp.OffsetForNewRegion(oldGroupPosition);
+ grp.ScheduleGroupForFullUpdate();
+ }
+ }
+
+ ///
+ /// Move the given scene object into a new region
+ ///
+ ///
+ /// Scene Object Group that we're crossing
+ ///
+ /// true if the crossing itself was successful, false on failure
+ /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
+ ///
+ public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent)
+ {
+ bool successYN = false;
+ grp.RootPart.UpdateFlag = 0;
+ int primcrossingXMLmethod = 0;
+
+ if (newRegionHandle != 0)
+ {
+ string objectState = grp.GetStateSnapshot();
+
+ successYN
+ = m_sceneGridService.PrimCrossToNeighboringRegion(
+ newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod);
+ if (successYN && (objectState != "") && m_allowScriptCrossings)
+ {
+ successYN = m_sceneGridService.PrimCrossToNeighboringRegion(
+ newRegionHandle, grp.UUID, objectState, 100);
+ }
+
+ if (successYN)
+ {
+ // We remove the object here
+ try
+ {
+ DeleteSceneObject(grp, silent);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat(
+ "[INTERREGION]: Exception deleting the old object left behind on a border crossing for {0}, {1}",
+ grp, e);
+ }
+ }
+ else
+ {
+ if (!grp.IsDeleted)
+ {
+ if (grp.RootPart.PhysActor != null)
+ {
+ grp.RootPart.PhysActor.CrossingFailure();
+ }
+ }
+
+ m_log.ErrorFormat("[INTERREGION]: Prim crossing failed for {0}", grp);
+ }
+ }
+ else
+ {
+ m_log.Error("[INTERREGION]: region handle was unexpectedly 0 in Scene.CrossPrimGroupIntoNewRegion()");
+ }
+
+ return successYN;
+ }
+
+ ///
+ /// Handle a scene object that is crossing into this region from another.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool IncomingInterRegionPrimGroup(UUID primID, string objXMLData, int XMLMethod)
+ {
+
+ if (XMLMethod == 0)
+ {
+ m_log.DebugFormat("[INTERREGION]: A new prim {0} arrived from a neighbor", primID);
+ SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData);
+
+ // If the user is banned, we won't let any of their objects
+ // enter. Period.
+ //
+ if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID))
+ {
+ m_log.Info("[INTERREGION]: Denied prim crossing for "+
+ "banned avatar");
+
+ return false;
+ }
+
+ // Force allocation of new LocalId
+ //
+ foreach (SceneObjectPart p in sceneObject.Children.Values)
+ p.LocalId = 0;
+
+ if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim)
+ {
+ if (sceneObject.RootPart.Shape.State != 0)
+ {
+ // Fix up attachment Parent Local ID
+ //
+ ScenePresence sp = GetScenePresence(sceneObject.OwnerID);
+
+ uint parentLocalID = 0;
+ if (sp != null)
+ parentLocalID = sp.LocalId;
+
+ sceneObject.RootPart.IsAttachment = true;
+ sceneObject.RootPart.SetParentLocalId(parentLocalID);
+
+ AddRestoredSceneObject(sceneObject, false, false);
+
+ // Handle attachment special case
+ //
+ SceneObjectPart RootPrim = GetSceneObjectPart(primID);
+
+ if (RootPrim != null)
+ {
+ SceneObjectGroup grp = RootPrim.ParentGroup;
+
+ RootPrim.SetParentLocalId(parentLocalID);
+
+ if (grp != null)
+ {
+ m_log.DebugFormat("[ATTACHMENT]: Received "+
+ "attachment {0}, inworld asset id {1}",
+ grp.RootPart.LastOwnerID.ToString(),
+ grp.UUID.ToString());
+
+ if (sp != null)
+ {
+ grp.SetFromAssetID(grp.RootPart.LastOwnerID);
+ m_log.DebugFormat("[ATTACHMENT]: Attach "+
+ "to avatar {0}",
+ sp.UUID.ToString());
+ AttachObject(sp.ControllingClient,
+ grp.LocalId, (uint)0,
+ grp.GroupRotation,
+ grp.AbsolutePosition, false);
+ grp.SendGroupFullUpdate();
+ }
+ else
+ {
+ RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
+ RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
+ }
+ }
+ }
+ }
+ else
+ {
+ AddRestoredSceneObject(sceneObject, true, false);
+
+ if (!Permissions.CanObjectEntry(sceneObject.UUID,
+ true, sceneObject.AbsolutePosition))
+ {
+ // Deny non attachments based on parcel settings
+ //
+ m_log.Info("[INTERREGION]: Denied prim crossing "+
+ "because of parcel settings");
+
+ DeleteSceneObject(sceneObject, false);
+
+ return false;
+ }
+ }
+ }
+ }
+ else if ((XMLMethod == 100) && m_allowScriptCrossings)
+ {
+ m_log.Warn("[INTERREGION]: Prim state data arrived from a neighbor");
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(objXMLData);
+
+ XmlNodeList rootL = doc.GetElementsByTagName("ScriptData");
+ if (rootL.Count == 1)
+ {
+ XmlNode rootNode = rootL[0];
+ if (rootNode != null)
+ {
+ XmlNodeList partL = rootNode.ChildNodes;
+
+ foreach (XmlNode part in partL)
+ {
+ XmlNodeList nodeL = part.ChildNodes;
+
+ switch (part.Name)
+ {
+ case "Assemblies":
+ foreach (XmlNode asm in nodeL)
+ {
+ string fn = asm.Attributes.GetNamedItem("Filename").Value;
+
+ Byte[] filedata = Convert.FromBase64String(asm.InnerText);
+ string path = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString());
+ path = Path.Combine(path, fn);
+
+ if (!File.Exists(path))
+ {
+ FileStream fs = File.Create(path);
+ fs.Write(filedata, 0, filedata.Length);
+ fs.Close();
+ }
+ }
+ break;
+ case "ScriptStates":
+ foreach (XmlNode st in nodeL)
+ {
+ string id = st.Attributes.GetNamedItem("UUID").Value;
+ UUID uuid = new UUID(id);
+ XmlNode state = st.ChildNodes[0];
+
+ XmlDocument sdoc = new XmlDocument();
+ XmlNode sxmlnode = sdoc.CreateNode(
+ XmlNodeType.XmlDeclaration,
+ "", "");
+ sdoc.AppendChild(sxmlnode);
+
+ XmlNode newnode = sdoc.ImportNode(state, true);
+ sdoc.AppendChild(newnode);
+
+ string spath = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString());
+ spath = Path.Combine(spath, uuid.ToString());
+ FileStream sfs = File.Create(spath + ".state");
+ System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
+ Byte[] buf = enc.GetBytes(sdoc.InnerXml);
+ sfs.Write(buf, 0, buf.Length);
+ sfs.Close();
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ SceneObjectPart RootPrim = GetSceneObjectPart(primID);
+ RootPrim.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1);
+
+ return true;
+ }
+
+ return true;
+ }
+
+ #endregion
+
+ #region Add/Remove Avatar Methods
+
+ public override void AddNewClient(IClientAPI client)
+ {
+ SubscribeToClientEvents(client);
+ ScenePresence presence;
+
+ if (m_restorePresences.ContainsKey(client.AgentId))
+ {
+ m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
+
+ presence = m_restorePresences[client.AgentId];
+ m_restorePresences.Remove(client.AgentId);
+
+ // This is one of two paths to create avatars that are
+ // used. This tends to get called more in standalone
+ // than grid, not really sure why, but as such needs
+ // an explicity appearance lookup here.
+ AvatarAppearance appearance = null;
+ GetAvatarAppearance(client, out appearance);
+ presence.Appearance = appearance;
+
+ presence.initializeScenePresence(client, RegionInfo, this);
+
+ m_sceneGraph.AddScenePresence(presence);
+
+ lock (m_restorePresences)
+ {
+ Monitor.PulseAll(m_restorePresences);
+ }
+ }
+ else
+ {
+ m_log.DebugFormat(
+ "[SCENE]: Adding new child agent for {0} in {1}",
+ client.Name, RegionInfo.RegionName);
+
+ CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
+
+ CreateAndAddScenePresence(client);
+ }
+
+ m_LastLogin = System.Environment.TickCount;
+ EventManager.TriggerOnNewClient(client);
+ }
+
+ protected virtual void SubscribeToClientEvents(IClientAPI client)
+ {
+ client.OnRegionHandShakeReply += SendLayerData;
+ client.OnAddPrim += AddNewPrim;
+ client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition;
+ client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
+ client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation;
+ client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation;
+ client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
+ client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
+ client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
+ client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
+ client.OnUpdatePrimShape += m_sceneGraph.UpdatePrimShape;
+ client.OnUpdatePrimTexture += m_sceneGraph.UpdatePrimTexture;
+ client.OnTeleportLocationRequest += RequestTeleportLocation;
+ client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
+ client.OnObjectSelect += SelectPrim;
+ client.OnObjectDeselect += DeselectPrim;
+ client.OnGrabUpdate += m_sceneGraph.MoveObject;
+ client.OnDeRezObject += DeRezObject;
+ client.OnRezObject += RezObject;
+ client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
+ client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
+ client.OnObjectAttach += m_sceneGraph.AttachObject;
+ client.OnObjectDetach += m_sceneGraph.DetachObject;
+ client.OnObjectDrop += m_sceneGraph.DropObject;
+ client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;
+ client.OnObjectDescription += m_sceneGraph.PrimDescription;
+ client.OnObjectName += m_sceneGraph.PrimName;
+ client.OnObjectClickAction += m_sceneGraph.PrimClickAction;
+ client.OnObjectMaterial += m_sceneGraph.PrimMaterial;
+ client.OnLinkObjects += m_sceneGraph.LinkObjects;
+ client.OnDelinkObjects += m_sceneGraph.DelinkObjects;
+ client.OnObjectDuplicate += m_sceneGraph.DuplicateObject;
+ client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay;
+ client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags;
+ client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
+ client.OnRequestGodlikePowers += handleRequestGodlikePowers;
+ client.OnGodKickUser += HandleGodlikeKickUser;
+ client.OnObjectPermissions += HandleObjectPermissionsUpdate;
+ client.OnCreateNewInventoryItem += CreateNewInventoryItem;
+ client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
+ client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
+ client.OnMoveInventoryFolder += HandleMoveInventoryFolder;
+ client.OnFetchInventoryDescendents += HandleFetchInventoryDescendents;
+ client.OnPurgeInventoryDescendents += HandlePurgeInventoryDescendents;
+ client.OnFetchInventory += HandleFetchInventory;
+ client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
+ client.OnCopyInventoryItem += CopyInventoryItem;
+ client.OnMoveInventoryItem += MoveInventoryItem;
+ client.OnRemoveInventoryItem += RemoveInventoryItem;
+ client.OnRemoveInventoryFolder += RemoveInventoryFolder;
+ client.OnRezScript += RezScript;
+ client.OnRequestTaskInventory += RequestTaskInventory;
+ client.OnRemoveTaskItem += RemoveTaskInventory;
+ client.OnUpdateTaskInventory += UpdateTaskInventory;
+ client.OnMoveTaskItem += ClientMoveTaskInventoryItem;
+ client.OnGrabObject += ProcessObjectGrab;
+ client.OnDeGrabObject += ProcessObjectDeGrab;
+ client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
+ client.OnParcelBuy += ProcessParcelBuy;
+ client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
+ client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
+ client.OnTeleportHomeRequest += TeleportClientHome;
+ client.OnSetStartLocationRequest += SetHomeRezPoint;
+ client.OnUndo += m_sceneGraph.HandleUndo;
+ client.OnObjectGroupRequest += m_sceneGraph.HandleObjectGroupUpdate;
+ client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
+ client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime;
+ client.OnObjectSaleInfo += ObjectSaleInfo;
+ client.OnScriptReset += ProcessScriptReset;
+ client.OnGetScriptRunning += GetScriptRunning;
+ client.OnSetScriptRunning += SetScriptRunning;
+ client.OnRegionHandleRequest += RegionHandleRequest;
+ client.OnUnackedTerrain += TerrainUnAcked;
+
+ client.OnObjectOwner += ObjectOwner;
+
+ if (StatsReporter != null)
+ client.OnNetworkStatsUpdate += StatsReporter.AddPacketsFromClientStats;
+
+ // EventManager.TriggerOnNewClient(client);
+ }
+
+ ///
+ /// Teleport an avatar to their home region
+ ///
+ ///
+ ///
+ public virtual void TeleportClientHome(UUID agentId, IClientAPI client)
+ {
+ UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(agentId);
+ if (UserProfile != null)
+ {
+ RegionInfo regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegionID);
+ if (regionInfo == null)
+ {
+ regionInfo = CommsManager.GridService.RequestNeighbourInfo(UserProfile.HomeRegion);
+ if (regionInfo != null) // home region can be away temporarily, too
+ {
+ UserProfile.HomeRegionID = regionInfo.RegionID;
+ CommsManager.UserService.UpdateUserProfile(UserProfile);
+ }
+ }
+ if (regionInfo == null)
+ {
+ // can't find the Home region: Tell viewer and abort
+ client.SendTeleportFailed("Your home-region could not be found.");
+ return;
+ }
+ RequestTeleportLocation(
+ client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
+ (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
+ }
+ }
+
+ public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
+ UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
+ bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
+ {
+ Vector3 pos;
+ const bool frontFacesOnly = true;
+ //m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
+ SceneObjectPart target = GetSceneObjectPart(localID);
+ SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj);
+
+ if (target != null && target2 != null)
+ {
+ Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
+ Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
+ Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
+
+ if (target2.ParentGroup != null)
+ {
+ pos = target2.AbsolutePosition;
+ //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
+
+ // TODO: Raytrace better here
+
+ //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
+ Ray NewRay = new Ray(AXOrigin, AXdirection);
+
+ // Ray Trace against target here
+ EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
+
+ // Un-comment out the following line to Get Raytrace results printed to the console.
+ //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
+ float ScaleOffset = 0.5f;
+
+ // If we hit something
+ if (ei.HitTF)
+ {
+ Vector3 scale = target.Scale;
+ Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
+ if (scaleComponent.X != 0) ScaleOffset = scale.X;
+ if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
+ if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
+ ScaleOffset = Math.Abs(ScaleOffset);
+ Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
+ Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
+ Vector3 offset = normal * (ScaleOffset / 2f);
+ pos = intersectionpoint + offset;
+
+ // stick in offset format from the original prim
+ pos = pos - target.ParentGroup.AbsolutePosition;
+ if (CopyRotates)
+ {
+ Quaternion worldRot = target2.GetWorldRotation();
+
+ // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
+ m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
+ //obj.Rotation = worldRot;
+ //obj.UpdateGroupRotation(worldRot);
+ }
+ else
+ {
+ m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
+ }
+ }
+
+ return;
+ }
+
+ return;
+ }
+ }
+
+ public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
+ {
+ UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(remoteClient.AgentId);
+ if (UserProfile != null)
+ {
+ // I know I'm ignoring the regionHandle provided by the teleport location request.
+ // reusing the TeleportLocationRequest delegate, so regionHandle isn't valid
+ UserProfile.HomeRegionID = RegionInfo.RegionID;
+ // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
+ // TODO: The HomeRegion property can be removed then, too
+ UserProfile.HomeRegion = RegionInfo.RegionHandle;
+ UserProfile.HomeLocation = position;
+ UserProfile.HomeLookAt = lookAt;
+ CommsManager.UserService.UpdateUserProfile(UserProfile);
+
+ // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
+ m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
+ }
+ else
+ {
+ m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
+ }
+ }
+
+ ///
+ /// Create a child agent scene presence and add it to this scene.
+ ///
+ ///
+ ///
+ protected virtual ScenePresence CreateAndAddScenePresence(IClientAPI client)
+ {
+ AvatarAppearance appearance = null;
+ GetAvatarAppearance(client, out appearance);
+
+ ScenePresence avatar = m_sceneGraph.CreateAndAddChildScenePresence(client, appearance);
+ //avatar.KnownRegions = GetChildrenSeeds(avatar.UUID);
+ return avatar;
+ }
+
+ ///
+ /// Get the avatar apperance for the given client.
+ ///
+ ///
+ ///
+ public void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
+ {
+ appearance = new AvatarAppearance();
+
+ try
+ {
+ if (m_AvatarFactory != null)
+ {
+ if (m_AvatarFactory.TryGetAvatarAppearance(client.AgentId, out appearance))
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("[APPEARANCE]: Problem fetching appearance for avatar {0}, {1}",
+ client.Name, e);
+ }
+
+ m_log.Warn("[APPEARANCE]: Appearance not found, returning default");
+ }
+
+ ///
+ /// Remove the given client from the scene.
+ ///
+ ///
+ public override void RemoveClient(UUID agentID)
+ {
+ bool childagentYN = false;
+ ScenePresence avatar = GetScenePresence(agentID);
+ if (avatar != null)
+ {
+ childagentYN = avatar.IsChildAgent;
+ }
+
+ try
+ {
+ m_log.DebugFormat(
+ "[SCENE]: Removing {0} agent {1} from region {2}",
+ (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
+
+ m_sceneGraph.removeUserCount(!childagentYN);
+ CapsModule.RemoveCapsHandler(agentID);
+
+ if (avatar.Scene.NeedSceneCacheClear(avatar.UUID))
+ {
+ CommsManager.UserProfileCacheService.RemoveUser(agentID);
+ }
+
+ if (!avatar.IsChildAgent)
+ {
+ m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition, avatar.Lookat);
+ //List childknownRegions = new List();
+ //List ckn = avatar.KnownChildRegionHandles;
+ //for (int i = 0; i < ckn.Count; i++)
+ //{
+ // childknownRegions.Add(ckn[i]);
+ //}
+ List regions = new List(avatar.KnownChildRegionHandles);
+ regions.Remove(RegionInfo.RegionHandle);
+ m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
+
+ }
+ m_eventManager.TriggerClientClosed(agentID);
+ }
+ catch (NullReferenceException)
+ {
+ // We don't know which count to remove it from
+ // Avatar is already disposed :/
+ }
+
+ m_eventManager.TriggerOnRemovePresence(agentID);
+ Broadcast(delegate(IClientAPI client)
+ {
+ try
+ {
+ client.SendKillObject(avatar.RegionHandle, avatar.LocalId);
+ }
+ catch (NullReferenceException)
+ {
+ //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
+ }
+ });
+
+ ForEachScenePresence(
+ delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
+
+ IAgentAssetTransactions agentTransactions = this.RequestModuleInterface();
+ if (agentTransactions != null)
+ {
+ agentTransactions.RemoveAgentAssetTransactions(agentID);
+ }
+
+ m_sceneGraph.RemoveScenePresence(agentID);
+
+ try
+ {
+ avatar.Close();
+ }
+ catch (NullReferenceException)
+ {
+ //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
+ }
+
+ // Remove client agent from profile, so new logins will work
+ if (!childagentYN)
+ {
+ m_sceneGridService.ClearUserAgent(agentID);
+ }
+
+ //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
+ //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
+ }
+
+ public void HandleRemoveKnownRegionsFromAvatar(UUID avatarID, List regionslst)
+ {
+ ScenePresence av = GetScenePresence(avatarID);
+ if (av != null)
+ {
+ lock (av)
+ {
+
+ for (int i = 0; i < regionslst.Count; i++)
+ {
+ av.KnownChildRegionHandles.Remove(regionslst[i]);
+ }
+ }
+ }
+ }
+
+ public override void CloseAllAgents(uint circuitcode)
+ {
+ // Called by ClientView to kill all circuit codes
+ ClientManager.CloseAllAgents(circuitcode);
+ }
+
+ public void NotifyMyCoarseLocationChange()
+ {
+ ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
+ }
+
+ #endregion
+
+ #region Entities
+
+ public void SendKillObject(uint localID)
+ {
+ SceneObjectPart part = GetSceneObjectPart(localID);
+ if (part != null) // It is a prim
+ {
+ if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
+ {
+ if (part.ParentGroup.RootPart != part) // Child part
+ return;
+ }
+ }
+ Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
+ }
+
+ #endregion
+
+ #region RegionComms
+
+ ///
+ /// Register the methods that should be invoked when this scene receives various incoming events
+ ///
+ public void RegisterCommsEvents()
+ {
+ m_sceneGridService.OnExpectUser += NewUserConnection;
+ m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
+ m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent;
+ m_sceneGridService.OnRegionUp += OtherRegionUp;
+ //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
+ m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup;
+ //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
+ m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
+ m_sceneGridService.KiPrimitive += SendKillObject;
+ m_sceneGridService.OnGetLandData += GetLandData;
+
+ if (m_interregionCommsIn != null)
+ {
+ m_log.Debug("[SCENE]: Registering with InterregionCommsIn");
+ m_interregionCommsIn.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
+ }
+ else
+ m_log.Debug("[SCENE]: Unable to register with InterregionCommsIn");
+
+ }
+
+ ///
+ /// Deregister this scene from receiving incoming region events
+ ///
+ public void UnRegisterRegionWithComms()
+ {
+ m_sceneGridService.KiPrimitive -= SendKillObject;
+ m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
+ //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
+ m_sceneGridService.OnExpectPrim -= IncomingInterRegionPrimGroup;
+ //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
+ m_sceneGridService.OnRegionUp -= OtherRegionUp;
+ m_sceneGridService.OnExpectUser -= NewUserConnection;
+ m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
+ m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
+ m_sceneGridService.OnGetLandData -= GetLandData;
+
+ if (m_interregionCommsIn != null)
+ m_interregionCommsIn.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
+
+ m_sceneGridService.Close();
+ }
+
+ ///
+ /// Do the work necessary to initiate a new user connection for a particular scene.
+ /// At the moment, this consists of setting up the caps infrastructure
+ ///
+ ///
+ ///
+ public void NewUserConnection(AgentCircuitData agent)
+ {
+ CapsModule.NewUserConnection(agent);
+
+ ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
+ if (sp != null)
+ {
+ m_log.DebugFormat(
+ "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
+ agent.AgentID, RegionInfo.RegionName);
+
+ sp.AdjustKnownSeeds();
+
+ return;
+ }
+
+ // Don't disable this log message - it's too helpful
+ m_log.DebugFormat(
+ "[CONNECTION BEGIN]: Region {0} told of incoming client {1} {2} {3} (circuit code {4})",
+ RegionInfo.RegionName, agent.firstname, agent.lastname, agent.AgentID, agent.circuitcode);
+
+ if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
+ {
+ m_log.WarnFormat(
+ "[CONNECTION BEGIN]: Denied access to: {0} at {1} because the user is on the region banlist",
+ agent.AgentID, RegionInfo.RegionName);
+ }
+
+ CapsModule.AddCapsHandler(agent.AgentID);
+
+ if (!agent.child)
+ {
+ // Honor parcel landing type and position.
+ ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
+ if (land != null)
+ {
+ if (land.landData.LandingType == (byte)1 && land.landData.UserLocation != Vector3.Zero)
+ {
+ agent.startpos = land.landData.UserLocation;
+ }
+ }
+ }
+
+ m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
+
+ // rewrite session_id
+ CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
+
+ if (userinfo != null)
+ {
+ userinfo.SessionID = agent.SessionID;
+ }
+ else
+ {
+ m_log.WarnFormat(
+ "[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid", agent.AgentID);
+ }
+ }
+
+ public void UpdateCircuitData(AgentCircuitData data)
+ {
+ m_authenticateHandler.UpdateAgentData(data);
+ }
+
+ public bool ChangeCircuitCode(uint oldcc, uint newcc)
+ {
+ return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
+ }
+
+ protected void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
+ {
+ ScenePresence loggingOffUser = null;
+ loggingOffUser = GetScenePresence(AvatarID);
+ if (loggingOffUser != null)
+ {
+ UUID localRegionSecret = UUID.Zero;
+ bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret);
+
+ // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
+ // Will update the user server in a few revisions to use it.
+
+ if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
+ {
+ m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List(loggingOffUser.KnownRegions.Keys));
+ loggingOffUser.ControllingClient.Kick(message);
+ // Give them a second to receive the message!
+ System.Threading.Thread.Sleep(1000);
+ loggingOffUser.ControllingClient.Close(true);
+ }
+ else
+ {
+ m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
+ }
+ }
+ else
+ {
+ m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString());
+ }
+ }
+
+ ///
+ /// Triggered when an agent crosses into this sim. Also happens on initial login.
+ ///
+ ///
+ ///
+ ///
+ public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
+ {
+ ScenePresence presence;
+
+ lock (m_scenePresences)
+ {
+ m_scenePresences.TryGetValue(agentID, out presence);
+ }
+
+ if (presence != null)
+ {
+ try
+ {
+ presence.MakeRootAgent(position, isFlying);
+ }
+ catch (Exception e)
+ {
+ m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}", e);
+ }
+ }
+ else
+ {
+ m_log.ErrorFormat(
+ "[SCENE]: Could not find presence for agent {0} crossing into scene {1}",
+ agentID, RegionInfo.RegionName);
+ }
+ }
+
+ public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData)
+ {
+// m_log.DebugFormat(
+// "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
+
+ // We have to wait until the viewer contacts this region after receiving EAC.
+ // That calls AddNewClient, which finally creates the ScenePresence
+ ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
+ if (childAgentUpdate != null)
+ {
+ childAgentUpdate.ChildAgentDataUpdate(cAgentData);
+ return true;
+ }
+
+ return false;
+ }
+
+ public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData)
+ {
+ //Console.WriteLine(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
+ ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
+ if (childAgentUpdate != null)
+ {
+ // I can't imagine *yet* why we would get an update if the agent is a root agent..
+ // however to avoid a race condition crossing borders..
+ if (childAgentUpdate.IsChildAgent)
+ {
+ uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
+ uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
+ uint tRegionX = RegionInfo.RegionLocX;
+ uint tRegionY = RegionInfo.RegionLocY;
+ //Send Data to ScenePresence
+ childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
+ // Not Implemented:
+ //TODO: Do we need to pass the message on to one of our neighbors?
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
+ {
+ int ntimes = 10;
+ ScenePresence childAgentUpdate = null;
+ while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0))
+ Thread.Sleep(1000);
+ return childAgentUpdate;
+
+ }
+
+ public virtual bool IncomingReleaseAgent(UUID id)
+ {
+ return m_sceneGridService.ReleaseAgent(id);
+ }
+
+ public void SendReleaseAgent(ulong regionHandle, UUID id, string uri)
+ {
+ m_interregionCommsOut.SendReleaseAgent(regionHandle, id, uri);
+ }
+
+ ///
+ /// Tell a single agent to disconnect from the region.
+ ///
+ ///
+ ///
+ public bool IncomingCloseAgent(UUID agentID)
+ {
+ //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
+
+ ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
+ if (presence != null)
+ {
+ // Nothing is removed here, so down count it as such
+ if (presence.IsChildAgent)
+ {
+ m_sceneGraph.removeUserCount(false);
+ }
+ else
+ {
+ m_sceneGraph.removeUserCount(true);
+ }
+
+ // Don't do this to root agents on logout, it's not nice for the viewer
+ if (presence.IsChildAgent)
+ {
+ // Tell a single agent to disconnect from the region.
+ IEventQueue eq = RequestModuleInterface();
+ if (eq != null)
+ {
+ eq.DisableSimulator(RegionInfo.RegionHandle, agentID);
+ }
+ else
+ presence.ControllingClient.SendShutdownConnectionNotice();
+ }
+
+ presence.ControllingClient.Close(true);
+ return true;
+ }
+
+ // Agent not here
+ return false;
+ }
+
+ ///
+ /// Tell neighboring regions about this agent
+ /// When the regions respond with a true value,
+ /// tell the agents about the region.
+ ///
+ /// We have to tell the regions about the agents first otherwise it'll deny them access
+ ///
+ ///
+ ///
+ public void InformClientOfNeighbours(ScenePresence presence)
+ {
+ m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
+ }
+
+ ///
+ /// Tell a neighboring region about this agent
+ ///
+ ///
+ ///
+ public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
+ {
+ m_sceneGridService.InformNeighborChildAgent(presence, region, m_neighbours);
+ }
+
+ ///
+ /// Requests information about this region from gridcomms
+ ///
+ ///
+ ///
+ public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle)
+ {
+ return m_sceneGridService.RequestNeighbouringRegionInfo(regionHandle);
+ }
+
+ ///
+ /// Requests textures for map from minimum region to maximum region in world cordinates
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY)
+ {
+ m_log.InfoFormat("[MAPBLOCK]: {0}-{1}, {2}-{3}", minX, minY, maxX, maxY);
+ m_sceneGridService.RequestMapBlocks(remoteClient, minX, minY, maxX, maxY);
+ }
+
+ ///
+ /// Tries to teleport agent to other region.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
+ Vector3 lookat, uint teleportFlags)
+ {
+ RegionInfo regionInfo = m_sceneGridService.RequestClosestRegion(regionName);
+ if (regionInfo == null)
+ {
+ // can't find the region: Tell viewer and abort
+ remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
+ return;
+ }
+
+ RequestTeleportLocation(remoteClient, regionInfo.RegionHandle, position, lookat, teleportFlags);
+ }
+
+ ///
+ /// Tries to teleport agent to other region.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
+ Vector3 lookAt, uint teleportFlags)
+ {
+ ScenePresence sp = null;
+ lock (m_scenePresences)
+ {
+ if (m_scenePresences.ContainsKey(remoteClient.AgentId))
+ sp = m_scenePresences[remoteClient.AgentId];
+ }
+
+ if (sp != null)
+ {
+ m_sceneGridService.RequestTeleportToLocation(sp, regionHandle,
+ position, lookAt, teleportFlags);
+ }
+ }
+
+ ///
+ /// Tries to teleport agent to landmark.
+ ///
+ ///
+ ///
+ ///
+ public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
+ {
+ RegionInfo info = CommsManager.GridService.RequestNeighbourInfo(regionID);
+
+ if (info == null)
+ {
+ // can't find the region: Tell viewer and abort
+ remoteClient.SendTeleportFailed("The teleport destination could not be found.");
+ return;
+ }
+
+ ScenePresence sp = null;
+ lock (m_scenePresences)
+ {
+ if (m_scenePresences.ContainsKey(remoteClient.AgentId))
+ sp = m_scenePresences[remoteClient.AgentId];
+ }
+ if (sp != null)
+ {
+ m_sceneGridService.RequestTeleportToLocation(sp, info.RegionHandle,
+ position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
+ }
+ }
+
+ ///
+ /// Agent is crossing the border into a neighbouring region. Tell the neighbour about it!
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool InformNeighbourOfCrossing(ulong regionHandle, UUID agentID, Vector3 position, bool isFlying)
+ {
+ return m_sceneGridService.CrossToNeighbouringRegion(regionHandle, agentID, position, isFlying);
+ }
+
+ public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)
+ {
+ m_sceneGridService.SendChildAgentDataUpdate(cadu, presence);
+ }
+
+ #endregion
+
+ #region Other Methods
+
+ public void SetObjectCapacity(int objects)
+ {
+ // Region specific config overrides global
+ //
+ if (RegionInfo.ObjectCapacity != 0)
+ objects = RegionInfo.ObjectCapacity;
+
+ if (StatsReporter != null)
+ {
+ StatsReporter.SetObjectCapacity(objects);
+ }
+ objectCapacity = objects;
+ }
+
+ public List GetFriendList(UUID avatarID)
+ {
+ return CommsManager.GetUserFriendList(avatarID);
+ }
+
+ public Dictionary