diff --git a/OpenSim/ConsoleClient/ConsoleClient.cs b/OpenSim/ConsoleClient/ConsoleClient.cs
index d195d25296..8c616e0271 100644
--- a/OpenSim/ConsoleClient/ConsoleClient.cs
+++ b/OpenSim/ConsoleClient/ConsoleClient.cs
@@ -82,9 +82,11 @@ namespace OpenSim.ConsoleClient
private static void SendCommand(string module, string[] cmd)
{
- string sendCmd = cmd[0];
+ string sendCmd = "";
if (cmd.Length > 1)
{
+ sendCmd = cmd[0];
+
Array.Copy(cmd, 1, cmd, 0, cmd.Length-1);
Array.Resize(ref cmd, cmd.Length-1);
sendCmd += "\"" + String.Join("\" \"", cmd) + "\"";
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index adcf6bd4f0..9216e0b410 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -762,7 +762,7 @@ namespace Flotsam.RegionModules.AssetCache
case "expire":
- if (cmdparams.Length >= 3)
+ if (cmdparams.Length < 3)
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
break;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 1200105817..c3e57f0574 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -42,6 +42,7 @@ using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
+using OpenSim.Tests.Common.Mock;
using OpenSim.Tests.Common.Setup;
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
@@ -51,6 +52,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
{
private Guid m_lastRequestId;
private string m_lastErrorMessage;
+
+ protected TestScene m_scene;
+ protected ArchiverModule m_archiverModule;
+
+ [SetUp]
+ public void SetUp()
+ {
+ m_archiverModule = new ArchiverModule();
+ SerialiserModule serialiserModule = new SerialiserModule();
+ TerrainModule terrainModule = new TerrainModule();
+
+ m_scene = SceneSetupHelpers.SetupScene("scene1");
+ SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
+ }
private void LoadCompleted(Guid requestId, string errorMessage)
{
@@ -75,6 +90,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
}
+ protected SceneObjectPart CreateSceneObjectPart1()
+ {
+ string partName = "My Little Pony";
+ UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
+ PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
+ Vector3 groupPosition = new Vector3(10, 20, 30);
+ Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
+ Vector3 offsetPosition = new Vector3(5, 10, 15);
+
+ return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
+ }
+
+ protected SceneObjectPart CreateSceneObjectPart2()
+ {
+ string partName = "Action Man";
+ UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
+ PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
+ Vector3 groupPosition = new Vector3(90, 80, 70);
+ Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
+ Vector3 offsetPosition = new Vector3(20, 25, 30);
+
+ return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
+ }
+
///
/// Test saving a V0.2 OpenSim Region Archive.
///
@@ -84,59 +123,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
- ArchiverModule archiverModule = new ArchiverModule();
- SerialiserModule serialiserModule = new SerialiserModule();
- TerrainModule terrainModule = new TerrainModule();
+ SceneObjectPart part1 = CreateSceneObjectPart1();
+ m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
- Scene scene = SceneSetupHelpers.SetupScene("asset");
- SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
-
- SceneObjectPart part1;
-
- // Create and add prim 1
- {
- string partName = "My Little Pony";
- UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
- PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
- Vector3 groupPosition = new Vector3(10, 20, 30);
- Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
- Vector3 offsetPosition = new Vector3(5, 10, 15);
-
- part1
- = new SceneObjectPart(
- ownerId, shape, groupPosition, rotationOffset, offsetPosition);
- part1.Name = partName;
-
- scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
- }
-
- SceneObjectPart part2;
-
- // Create and add prim 2
- {
- string partName = "Action Man";
- UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
- PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
- Vector3 groupPosition = new Vector3(90, 80, 70);
- Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
- Vector3 offsetPosition = new Vector3(20, 25, 30);
-
- part2
- = new SceneObjectPart(
- ownerId, shape, groupPosition, rotationOffset, offsetPosition);
- part2.Name = partName;
-
- scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
- }
+ SceneObjectPart part2 = CreateSceneObjectPart2();
+ m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
MemoryStream archiveWriteStream = new MemoryStream();
- scene.EventManager.OnOarFileSaved += SaveCompleted;
+ m_scene.EventManager.OnOarFileSaved += SaveCompleted;
Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
lock (this)
{
- archiverModule.ArchiveRegion(archiveWriteStream, requestId);
+ m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
//AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
//while (assetServer.HasWaitingRequests())
// assetServer.ProcessNextRequest();
@@ -218,25 +218,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
- string part1Name = "object1";
- PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
- Vector3 groupPosition = new Vector3(90, 80, 70);
- Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
- Vector3 offsetPosition = new Vector3(20, 25, 30);
-
- SerialiserModule serialiserModule = new SerialiserModule();
- ArchiverModule archiverModule = new ArchiverModule();
-
- Scene scene = SceneSetupHelpers.SetupScene();
- SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
-
- SceneObjectPart part1
- = new SceneObjectPart(
- UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition);
- part1.Name = part1Name;
+ SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup object1 = new SceneObjectGroup(part1);
// Let's put some inventory items into our object
+ string soundItemName = "sound-item1";
UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
Type type = GetType();
Assembly assembly = type.Assembly;
@@ -269,17 +255,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
*/
- TaskInventoryItem item1 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid };
+ TaskInventoryItem item1
+ = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
part1.Inventory.AddInventoryItem(item1, true);
}
}
- scene.AddNewSceneObject(object1, false);
+ m_scene.AddNewSceneObject(object1, false);
string object1FileName = string.Format(
"{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
- part1Name,
- Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z),
+ part1.Name,
+ Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
part1.UUID);
tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
@@ -289,30 +276,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
lock (this)
{
- scene.EventManager.OnOarFileLoaded += LoadCompleted;
- archiverModule.DearchiveRegion(archiveReadStream);
+ m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
+ m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
- SceneObjectPart object1PartLoaded = scene.GetSceneObjectPart(part1Name);
+ SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
- Assert.That(object1PartLoaded.Name, Is.EqualTo(part1Name), "object1 names not identical");
- Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(groupPosition), "object1 group position not equal");
+ Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
+ Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
Assert.That(
- object1PartLoaded.RotationOffset, Is.EqualTo(rotationOffset), "object1 rotation offset not equal");
+ object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
Assert.That(
- object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
+ object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
- // Need to implement a method to get the task inventory item by name (since the uuid will have changed on load)
- /*
- TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItem(soundItemUuid);
+ TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
- AssetBase loadedSoundAsset = scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
+ AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
- */
// Temporary
Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
@@ -325,12 +309,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
public void TestLoadOarV0_2RegionSettings()
{
TestHelper.InMethod();
- //log4net.Config.XmlConfigurator.Configure();
-
- SerialiserModule serialiserModule = new SerialiserModule();
- ArchiverModule archiverModule = new ArchiverModule();
- Scene scene = SceneSetupHelpers.SetupScene();
- SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
+ //log4net.Config.XmlConfigurator.Configure();
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
@@ -377,12 +356,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
lock (this)
{
- scene.EventManager.OnOarFileLoaded += LoadCompleted;
- archiverModule.DearchiveRegion(archiveReadStream);
+ m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
+ m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
- RegionSettings loadedRs = scene.RegionInfo.RegionSettings;
+ RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
Assert.That(loadedRs.AgentLimit, Is.EqualTo(17));
Assert.That(loadedRs.AllowDamage, Is.True);
@@ -426,11 +405,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
MemoryStream archiveWriteStream = new MemoryStream();
- string part2Name = "objectMerge";
- PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
- Vector3 part2GroupPosition = new Vector3(90, 80, 70);
- Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
- Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
+// string part2Name = "objectMerge";
+// PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
+// Vector3 part2GroupPosition = new Vector3(90, 80, 70);
+// Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
+// Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
+
+ SceneObjectPart part2 = CreateSceneObjectPart2();
// Create an oar file that we can use for the merge
{
@@ -439,63 +420,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TerrainModule terrainModule = new TerrainModule();
Scene scene = SceneSetupHelpers.SetupScene();
- SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
+ SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
- SceneObjectPart part2
- = new SceneObjectPart(
- UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
- part2.Name = part2Name;
- SceneObjectGroup object2 = new SceneObjectGroup(part2);
-
- scene.AddNewSceneObject(object2, false);
+ m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
// Write out this scene
scene.EventManager.OnOarFileSaved += SaveCompleted;
lock (this)
{
- archiverModule.ArchiveRegion(archiveWriteStream);
+ m_archiverModule.ArchiveRegion(archiveWriteStream);
Monitor.Wait(this, 60000);
}
}
{
- ArchiverModule archiverModule = new ArchiverModule();
- SerialiserModule serialiserModule = new SerialiserModule();
- TerrainModule terrainModule = new TerrainModule();
-
- Scene scene = SceneSetupHelpers.SetupScene();
- SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
-
- string part1Name = "objectExisting";
- PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
- Vector3 part1GroupPosition = new Vector3(80, 70, 60);
- Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
- Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
-
- SceneObjectPart part1
- = new SceneObjectPart(
- UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
- part1.Name = part1Name;
- SceneObjectGroup object1 = new SceneObjectGroup(part1);
-
- scene.AddNewSceneObject(object1, false);
+ SceneObjectPart part1 = CreateSceneObjectPart1();
+ m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
// Merge in the archive we created earlier
byte[] archive = archiveWriteStream.ToArray();
MemoryStream archiveReadStream = new MemoryStream(archive);
- archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
+ m_archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
- SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name);
+ SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
- Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge");
- Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge");
+ Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
+ Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal after merge");
- SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name);
+ SceneObjectPart object2PartMerged = m_scene.GetSceneObjectPart(part2.Name);
Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
- Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge");
- Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge");
+ Assert.That(object2PartMerged.Name, Is.EqualTo(part2.Name), "object2 names not identical after merge");
+ Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
}
}
}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index eeb51024e9..fa9bf19dee 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -71,7 +71,8 @@ namespace OpenSim.Region.Framework.Interfaces
///
/// Start all the scripts contained in this entity's inventory
///
- void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
+ void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
+
ArrayList GetScriptErrors(UUID itemID);
///
@@ -142,6 +143,16 @@ namespace OpenSim.Region.Framework.Interfaces
/// null if the item does not exist
TaskInventoryItem GetInventoryItem(UUID itemId);
+ ///
+ /// Get inventory items by name.
+ ///
+ ///
+ ///
+ /// A list of inventory items with that name.
+ /// If no inventory item has that name then an empty list is returned.
+ ///
+ IList GetInventoryItems(string name);
+
///
/// Update an existing inventory item.
///
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
index 74526c452f..948b9dc522 100644
--- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs
@@ -49,10 +49,49 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IWorldComm
{
+ ///
+ /// Create a listen event callback with the specified filters.
+ /// The parameters localID,itemID are needed to uniquely identify
+ /// the script during 'peek' time. Parameter hostID is needed to
+ /// determine the position of the script.
+ ///
+ /// localID of the script engine
+ /// UUID of the script engine
+ /// UUID of the SceneObjectPart
+ /// channel to listen on
+ /// name to filter on
+ /// key to filter on (user given, could be totally faked)
+ /// msg to filter on
+ /// number of the scripts handle
int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
+
+ ///
+ /// This method scans over the objects which registered an interest in listen callbacks.
+ /// For everyone it finds, it checks if it fits the given filter. If it does, then
+ /// enqueue the message for delivery to the objects listen event handler.
+ /// The enqueued ListenerInfo no longer has filter values, but the actually trigged values.
+ /// Objects that do an llSay have their messages delivered here and for nearby avatars,
+ /// the OnChatFromClient event is used.
+ ///
+ /// type of delvery (whisper,say,shout or regionwide)
+ /// channel to sent on
+ /// name of sender (object or avatar)
+ /// key of sender (object or avatar)
+ /// msg to sent
void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
+
+ ///
+ /// Are there any listen events ready to be dispatched?
+ ///
+ /// boolean indication
bool HasMessages();
+
+ ///
+ /// Pop the first availlable listen event from the queue
+ ///
+ /// ListenerInfo with filter filled in
IWorldCommListenerInfo GetNextMessage();
+
void ListenControl(UUID itemID, int handle, int active);
void ListenRemove(UUID itemID, int handle);
void DeleteListener(UUID itemID);
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 8f0b866eda..fe40f524ad 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -92,8 +92,7 @@ namespace OpenSim.Region.Framework.Scenes
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, SurfaceTouchEventArgs surfaceArgs);
public delegate void ScriptResetDelegate(uint localID, UUID itemID);
@@ -103,62 +102,57 @@ namespace OpenSim.Region.Framework.Scenes
public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
+ ///
+ /// Called when an object is touched/grabbed.
+ ///
+ /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of
+ /// the root part.
+ public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
public event ObjectGrabDelegate OnObjectGrab;
+
+ public event ObjectGrabDelegate OnObjectGrabbing;
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 bool SceneGroupSpinStarted(UUID groupID);
-
public event SceneGroupSpinStarted OnSceneGroupSpinStart;
public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation);
-
public event SceneGroupSpun OnSceneGroupSpin;
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;
@@ -316,9 +310,10 @@ namespace OpenSim.Region.Framework.Scenes
public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue;
///
- /// Called whenever an object is attached, or detached
- /// from an in-world presence.
+ /// Called whenever an object is attached, or detached from an in-world presence.
///
+ /// If the object is being attached, then the avatarID will be present. If the object is being detached then
+ /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
public event Attach OnAttach;
@@ -412,6 +407,7 @@ namespace OpenSim.Region.Framework.Scenes
private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd;
private OnShutdownDelegate handlerShutdown = null; //OnShutdown;
private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab;
+ private ObjectGrabDelegate handlerObjectGrabbing = null; //OnObjectGrabbing;
private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab;
private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset
private NewRezScript handlerRezScript = null; //OnRezScript;
@@ -626,6 +622,15 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
+ {
+ handlerObjectGrabbing = OnObjectGrabbing;
+ if (handlerObjectGrabbing != null)
+ {
+ handlerObjectGrabbing(localID, originalID, offsetPos, remoteClient, surfaceArgs);
+ }
+ }
+
public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
handlerObjectDeGrab = OnObjectDeGrab;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index a18bf76b93..7b852a27c0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2385,9 +2385,19 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
+ ///
+ /// Attach an object.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// true if the object was successfully attached, false otherwise
+ public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
{
- m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
+ return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
}
public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 47fbeb45db..ac04dc795b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -292,6 +292,46 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, 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(objectID))
+ {
+ SceneObjectPart part = obj.GetChildPart(objectID);
+
+ // If the touched prim handles touches, deliver it
+ // If not, deliver to root prim
+ if ((part.ScriptEvents & scriptEvents.touch) != 0)
+ EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
+ // Deliver to the root prim if the touched prim doesn't handle touches
+ // or if we're meant to pass on touches anyway. Don't send to root prim
+ // if prim touched is the root prim as we just did it
+ if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
+ (part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
+ {
+ EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
+ }
+
+ return;
+ }
+ }
+ }
+ }
+ }
+
public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List surfaceArgs)
{
List EntityList = GetEntities();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 23db482cc7..d2f33b03a1 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2702,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes
client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
client.OnObjectPermissions += HandleObjectPermissionsUpdate;
client.OnGrabObject += ProcessObjectGrab;
+ client.OnGrabUpdate += ProcessObjectGrabUpdate;
client.OnDeGrabObject += ProcessObjectDeGrab;
client.OnUndo += m_sceneGraph.HandleUndo;
client.OnObjectDescription += m_sceneGraph.PrimDescription;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 34a92fead7..2c667192f8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -502,46 +502,62 @@ namespace OpenSim.Region.Framework.Scenes
if (part == null)
return;
- if (!m_parentScene.Permissions.CanTakeObject(
- part.UUID, remoteClient.AgentId))
+ if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
return;
// Calls attach with a Zero position
- AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
- m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
-
- // Save avatar attachment information
- ScenePresence presence;
- if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
+ if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
{
- m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt);
- m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
+
+ // Save avatar attachment information
+ ScenePresence presence;
+ if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
+ {
+ m_log.Info(
+ "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ + ", AttachmentPoint: " + AttachmentPt);
+
+ m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
+ }
}
}
- public SceneObjectGroup RezSingleAttachment(
- IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
+ ///
+ /// Rez an attachment
+ ///
+ ///
+ ///
+ ///
+ /// The scene object that was attached. Null if the scene object could not be found
+ public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient,
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, remoteClient.AgentId, true);
-
if (objatt != null)
{
bool tainted = false;
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true;
- AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
- objatt.ScheduleGroupForFullUpdate();
- if (tainted)
- objatt.HasGroupChanged = true;
+ if (AttachObject(
+ remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false))
+ {
+ objatt.ScheduleGroupForFullUpdate();
+ if (tainted)
+ objatt.HasGroupChanged = true;
+
+ // Fire after attach, so we don't get messy perms dialogs
+ // 3 == AttachedRez
+ objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
- // Fire after attach, so we don't get messy perms dialogs
- // 3 == AttachedRez
- objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
+ // Do this last so that event listeners have access to all the effects of the attachment
+ m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
+ }
}
+
return objatt;
}
@@ -590,7 +606,17 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- protected internal void AttachObject(
+ ///
+ /// Attach a scene object to an avatar.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// true if the attachment was successful, false otherwise
+ protected internal bool AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
{
SceneObjectGroup group = GetGroupByPrim(objectLocalID);
@@ -619,10 +645,8 @@ namespace OpenSim.Region.Framework.Scenes
// Stick it on left hand with Zero Offset from the attachment point.
AttachmentPt = (uint)AttachmentPoint.LeftHand;
attachPos = Vector3.Zero;
-
}
-
group.SetAttachmentPoint((byte)AttachmentPt);
group.AbsolutePosition = attachPos;
@@ -645,15 +669,21 @@ namespace OpenSim.Region.Framework.Scenes
// it get cleaned up
//
group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
- group.HasGroupChanged = false;
+ group.HasGroupChanged = false;
}
else
{
remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
+ return false;
}
}
else
+ {
m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
+ return false;
+ }
+
+ return true;
}
protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 768ceb5f3f..9cb13989e3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -301,6 +301,9 @@ namespace OpenSim.Region.Framework.Scenes
set { m_rootPart.GroupID = value; }
}
+ ///
+ /// The parts of this scene object group. You must lock this property before using it.
+ ///
public Dictionary Children
{
get { return m_parts; }
@@ -2239,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Get a child part with a given UUID
+ /// Get a part with a given UUID
///
///
/// null if a child part with the primID was not found
@@ -2254,7 +2257,7 @@ namespace OpenSim.Region.Framework.Scenes
}
///
- /// Get a child part with a given local ID
+ /// Get a part with a given local ID
///
///
/// null if a child part with the local ID was not found
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index da7ec44629..fe1e218c73 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -90,10 +90,27 @@ namespace OpenSim.Region.Framework.Scenes
SCALE = 0x40
}
+ public enum PrimType : int
+ {
+ BOX = 0,
+ CYLINDER = 1,
+ PRISM = 2,
+ SPHERE = 3,
+ TORUS = 4,
+ TUBE = 5,
+ RING = 6,
+ SCULPT = 7
+ }
+
#endregion Enumerations
public class SceneObjectPart : IScriptHost
{
+ ///
+ /// Denote all sides of the prim
+ ///
+ public const int ALL_SIDES = -1;
+
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// use only one serializer to give the runtime a chance to optimize it (it won't do that if you
@@ -741,6 +758,9 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ ///
+ /// Text color.
+ ///
public Color Color
{
get { return m_color; }
@@ -1910,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (uint localId in startedColliders)
{
if (localId == 0)
- return;
+ continue;
// always running this check because if the user deletes the object it would return a null reference.
if (m_parentGroup == null)
return;
@@ -2046,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
{
// always running this check because if the user deletes the object it would return a null reference.
if (localId == 0)
- return;
+ continue;
if (m_parentGroup == null)
return;
@@ -2178,7 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (uint localId in endedColliders)
{
if (localId == 0)
- return;
+ continue;
// always running this check because if the user deletes the object it would return a null reference.
if (m_parentGroup == null)
@@ -2981,6 +3001,178 @@ namespace OpenSim.Region.Framework.Scenes
PhysActor.VehicleFlagsRemove(flags);
}
}
+
+ ///
+ /// Set the color of prim faces
+ ///
+ ///
+ ///
+ public void SetFaceColor(Vector3 color, int face)
+ {
+ Primitive.TextureEntry tex = Shape.Textures;
+ Color4 texcolor;
+ if (face >= 0 && face < GetNumberOfSides())
+ {
+ texcolor = tex.CreateFace((uint)face).RGBA;
+ texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
+ texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
+ texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ tex.FaceTextures[face].RGBA = texcolor;
+ UpdateTexture(tex);
+ return;
+ }
+ else if (face == ALL_SIDES)
+ {
+ for (uint i = 0; i < GetNumberOfSides(); i++)
+ {
+ if (tex.FaceTextures[i] != null)
+ {
+ texcolor = tex.FaceTextures[i].RGBA;
+ texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
+ texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
+ texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ tex.FaceTextures[i].RGBA = texcolor;
+ }
+ texcolor = tex.DefaultTexture.RGBA;
+ texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
+ texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
+ texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
+ tex.DefaultTexture.RGBA = texcolor;
+ }
+ UpdateTexture(tex);
+ return;
+ }
+ }
+
+ ///
+ /// Get the number of sides that this part has.
+ ///
+ ///
+ public int GetNumberOfSides()
+ {
+ int ret = 0;
+ bool hasCut;
+ bool hasHollow;
+ bool hasDimple;
+ bool hasProfileCut;
+
+ PrimType primType = GetPrimType();
+ HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
+
+ switch (primType)
+ {
+ case PrimType.BOX:
+ ret = 6;
+ if (hasCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.CYLINDER:
+ ret = 3;
+ if (hasCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.PRISM:
+ ret = 5;
+ if (hasCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.SPHERE:
+ ret = 1;
+ if (hasCut) ret += 2;
+ if (hasDimple) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.TORUS:
+ ret = 1;
+ if (hasCut) ret += 2;
+ if (hasProfileCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.TUBE:
+ ret = 4;
+ if (hasCut) ret += 2;
+ if (hasProfileCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.RING:
+ ret = 3;
+ if (hasCut) ret += 2;
+ if (hasProfileCut) ret += 2;
+ if (hasHollow) ret += 1;
+ break;
+ case PrimType.SCULPT:
+ ret = 1;
+ break;
+ }
+ return ret;
+ }
+
+ ///
+ /// Tell us what type this prim is
+ ///
+ ///
+ ///
+ public PrimType GetPrimType()
+ {
+ if (Shape.SculptEntry)
+ return PrimType.SCULPT;
+ if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
+ {
+ if (Shape.PathCurve == (byte)Extrusion.Straight)
+ return PrimType.BOX;
+ else if (Shape.PathCurve == (byte)Extrusion.Curve1)
+ return PrimType.TUBE;
+ }
+ else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
+ {
+ if (Shape.PathCurve == (byte)Extrusion.Straight)
+ return PrimType.CYLINDER;
+ // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
+ else if (Shape.PathCurve == (byte)Extrusion.Curve1)
+ return PrimType.TORUS;
+ }
+ else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
+ {
+ if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2)
+ return PrimType.SPHERE;
+ }
+ else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
+ {
+ if (Shape.PathCurve == (byte)Extrusion.Straight)
+ return PrimType.PRISM;
+ else if (Shape.PathCurve == (byte)Extrusion.Curve1)
+ return PrimType.RING;
+ }
+
+ return PrimType.BOX;
+ }
+
+ ///
+ /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
+ out bool hasDimple, out bool hasProfileCut)
+ {
+ if (primType == PrimType.BOX
+ ||
+ primType == PrimType.CYLINDER
+ ||
+ primType == PrimType.PRISM)
+
+ hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
+ else
+ hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
+
+ hasHollow = shape.ProfileHollow > 0;
+ hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
+ hasProfileCut = hasDimple; // is it the same thing?
+ }
public void SetGroup(UUID groupID, IClientAPI client)
{
@@ -3013,6 +3205,11 @@ namespace OpenSim.Region.Framework.Scenes
}
}
+ ///
+ /// Set the events that this part will pass on to listeners.
+ ///
+ ///
+ ///
public void SetScriptEvents(UUID scriptid, int events)
{
// scriptEvents oldparts;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 9661775649..3317dd3d9c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -585,8 +585,32 @@ namespace OpenSim.Region.Framework.Scenes
m_items.TryGetValue(itemId, out item);
m_items.LockItemsForRead(false);
return item;
- }
+ }
+ ///
+ /// Get inventory items by name.
+ ///
+ ///
+ ///
+ /// A list of inventory items with that name.
+ /// If no inventory item has that name then an empty list is returned.
+ ///
+ public IList GetInventoryItems(string name)
+ {
+ IList items = new List();
+
+ lock (m_items)
+ {
+ foreach (TaskInventoryItem item in m_items.Values)
+ {
+ if (item.Name == name)
+ items.Add(item);
+ }
+ }
+
+ return items;
+ }
+
///
/// Update an existing inventory item.
///
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
index 4521f8ef6a..f2adcb74c2 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs
@@ -116,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
static string ConvertMRMKeywords(string script)
{
- script = script.Replace("microthreaded void ", "IEnumerable");
+ script = script.Replace("microthreaded void", "IEnumerable");
script = script.Replace("relax;", "yield return null;");
return script;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 33218aab59..e4ccce87ca 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -54,8 +54,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
using OpenSim.Services.Interfaces;
+using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
-
using AssetLandmark = OpenSim.Framework.AssetLandmark;
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
@@ -1442,6 +1442,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.UpdateTexture(tex);
return;
}
+
+ if (face == ScriptBaseClass.ALL_SIDES)
+ face = SceneObjectPart.ALL_SIDES;
+
+ m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -1599,7 +1604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
int i;
double sum = 0.0;
- for (i = 0 ; i < GetNumberOfSides(part) ; i++)
+ for (i = 0 ; i < GetNumberOfSides(part); i++)
sum += (double)tex.GetFace((uint)i).RGBA.A;
return sum;
}
@@ -1749,7 +1754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
int i;
- for (i = 0 ; i < GetNumberOfSides(part) ; i++)
+ for (i = 0 ; i < GetNumberOfSides(part); i++)
{
texcolor = tex.GetFace((uint)i).RGBA;
rgb.x += texcolor.R;
@@ -3568,7 +3573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
- SetColor(part, color, face);
+ part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
public void llCreateLink(string target, int parent)
@@ -4423,63 +4428,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return result;
}
- // this function to understand which shape it is (taken from meshmerizer)
- // quite useful can be used by meshmerizer to have a centralized point of understanding the shape
- // except that it refers to scripting constants
- public int getScriptPrimType(PrimitiveBaseShape primShape)
- {
- if (primShape.SculptEntry)
- return ScriptBaseClass.PRIM_TYPE_SCULPT;
- if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- return ScriptBaseClass.PRIM_TYPE_BOX;
- else if (primShape.PathCurve == (byte)Extrusion.Curve1)
- return ScriptBaseClass.PRIM_TYPE_TUBE;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- return ScriptBaseClass.PRIM_TYPE_CYLINDER;
- // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
- else if (primShape.PathCurve == (byte)Extrusion.Curve1)
- return ScriptBaseClass.PRIM_TYPE_TORUS;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte)Extrusion.Curve2)
- return ScriptBaseClass.PRIM_TYPE_SPHERE;
- }
- else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
- {
- if (primShape.PathCurve == (byte)Extrusion.Straight)
- return ScriptBaseClass.PRIM_TYPE_PRISM;
- else if (primShape.PathCurve == (byte)Extrusion.Curve1)
- return ScriptBaseClass.PRIM_TYPE_RING;
- }
- return ScriptBaseClass.PRIM_TYPE_BOX;
- }
-
- // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
- protected void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
- out bool hasDimple, out bool hasProfileCut)
- {
- if (primType == ScriptBaseClass.PRIM_TYPE_BOX
- ||
- primType == ScriptBaseClass.PRIM_TYPE_CYLINDER
- ||
- primType == ScriptBaseClass.PRIM_TYPE_PRISM)
-
- hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
- else
- hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
-
- hasHollow = shape.ProfileHollow > 0;
- hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
- hasProfileCut = hasDimple; // is it the same thing?
-
- }
-
public LSL_Integer llGetNumberOfSides()
{
m_host.AddScriptLPS(1);
@@ -4489,63 +4437,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected int GetNumberOfSides(SceneObjectPart part)
{
- int ret = 0;
- bool hasCut;
- bool hasHollow;
- bool hasDimple;
- bool hasProfileCut;
+ int sides = part.GetNumberOfSides();
- int primType = getScriptPrimType(part.Shape);
- hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
-
- switch (primType)
+ if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
{
- case ScriptBaseClass.PRIM_TYPE_BOX:
- ret = 6;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_CYLINDER:
- ret = 3;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_PRISM:
- ret = 5;
- if (hasCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_SPHERE:
- ret = 1;
- if (hasCut) ret += 2;
- if (hasDimple) ret += 2;
- if (hasHollow) ret += 3; // Emulate lsl on secondlife (according to documentation it should have added only +1)
- break;
- case ScriptBaseClass.PRIM_TYPE_TORUS:
- ret = 1;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_TUBE:
- ret = 4;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_RING:
- ret = 3;
- if (hasCut) ret += 2;
- if (hasProfileCut) ret += 2;
- if (hasHollow) ret += 1;
- break;
- case ScriptBaseClass.PRIM_TYPE_SCULPT:
- ret = 1;
- break;
+ // Make up for a bug where LSL shows 4 sides rather than 2
+ sides += 2;
}
- return ret;
- }
+ return sides;
+ }
+
/* The new / changed functions were tested with the following LSL script:
@@ -4570,8 +4472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
*/
-
-
// Xantor 29/apr/2008
// Returns rotation described by rotating angle radians about axis.
// q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
@@ -7203,10 +7103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Vector color=rules.GetVector3Item(idx++);
double alpha=(double)rules.GetLSLFloatItem(idx++);
- SetColor(part, color, face);
+ part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
SetAlpha(part, alpha, face);
break;
+
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
if (remain < 7)
return;
@@ -7222,6 +7123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
break;
+
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
if (remain < 5)
return;
@@ -7234,6 +7136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetPointLight(part, light, lightcolor, intensity, radius, falloff);
break;
+
case (int)ScriptBaseClass.PRIM_GLOW:
if (remain < 2)
return;
@@ -7243,6 +7146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetGlow(part, face, glow);
break;
+
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
if (remain < 3)
return;
@@ -7253,6 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SetShiny(part, face, shiny, bump);
break;
+
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
if (remain < 2)
return;
@@ -7260,6 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool st = rules.GetLSLIntegerItem(idx++);
SetFullBright(part, face , st);
break;
+
case (int)ScriptBaseClass.PRIM_MATERIAL:
if (remain < 1)
return;
@@ -7269,6 +7175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.Material = Convert.ToByte(mat);
break;
+
case (int)ScriptBaseClass.PRIM_PHANTOM:
if (remain < 1)
return;
@@ -7283,6 +7190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.ScriptSetPhantomStatus(phantom);
break;
+
case (int)ScriptBaseClass.PRIM_PHYSICS:
if (remain < 1)
return;
@@ -7296,6 +7204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
part.ScriptSetPhysicsStatus(physics);
break;
+
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
if (remain < 1)
return;
@@ -7563,7 +7472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
{
-
LSL_List res = new LSL_List();
int idx=0;
while (idx < rules.Length)
@@ -7625,7 +7533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE:
// implementing box
PrimitiveBaseShape Shape = part.Shape;
- int primType = getScriptPrimType(part.Shape);
+ int primType = (int)part.GetPrimType();
res.Add(new LSL_Integer(primType));
double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
@@ -7705,7 +7613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Primitive.TextureEntry tex = part.Shape.Textures;
if (face == ScriptBaseClass.ALL_SIDES)
{
- for (face = 0 ; face < GetNumberOfSides(part) ; face++)
+ for (face = 0 ; face < GetNumberOfSides(part); face++)
{
Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
@@ -7747,7 +7655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
Color4 texcolor;
if (face == ScriptBaseClass.ALL_SIDES)
{
- for (face = 0 ; face < GetNumberOfSides(part) ; face++)
+ for (face = 0 ; face < GetNumberOfSides(part); face++)
{
texcolor = tex.GetFace((uint)face).RGBA;
res.Add(new LSL_Vector(texcolor.R,
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 16309efca4..09b79d07f2 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -55,6 +55,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
m_log.Info("[XEngine] Hooking up to server events");
myScriptEngine.World.EventManager.OnAttach += attach;
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
+ myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
@@ -148,7 +149,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
}
public void touch(uint localID, uint originalID, Vector3 offsetPos,
- IClientAPI remoteClient)
+ IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
{
// Add to queue for all scripts in ObjectID object
DetectParams[] det = new DetectParams[1];
@@ -172,6 +173,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID);
det[0].LinkNum = originalPart.LinkNum;
}
+ if (surfaceArgs != null)
+ {
+ det[0].SurfaceTouchArgs = surfaceArgs;
+ }
myScriptEngine.PostObjectEvent(localID, new EventParams(
"touch", new Object[] { new LSL_Types.LSLInteger(1) },