From f76cc6036ebf446553ee5201321879538dafe3b2 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 7 Oct 2013 21:35:55 -0500 Subject: * Added a Basic DOS protection container/base object for the most common HTTP Server handlers. XMLRPC Handler, GenericHttpHandler and StreamHandler * Applied the XmlRpcBasicDOSProtector.cs to the login service as both an example, and good practice. * Applied the BaseStreamHandlerBasicDOSProtector.cs to the friends service as an example of the DOS Protector on StreamHandlers * Added CircularBuffer, used for CPU and Memory friendly rate monitoring. * DosProtector has 2 states, 1. Just Check for blocked users and check general velocity, 2. Track velocity per user, It only jumps to 2 if it's getting a lot of requests, and state 1 is about as resource friendly as if it wasn't even there. --- .../Avatar/Friends/FriendsRequestHandler.cs | 12 ++++++++++-- .../CoreModules/World/WorldMap/WorldMapModule.cs | 21 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index 2116605..ed4b205 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs @@ -42,14 +42,22 @@ using log4net; namespace OpenSim.Region.CoreModules.Avatar.Friends { - public class FriendsRequestHandler : BaseStreamHandler + public class FriendsRequestHandler : BaseStreamHandlerBasicDOSProtector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private FriendsModule m_FriendsModule; public FriendsRequestHandler(FriendsModule fmodule) - : base("POST", "/friends") + : base("POST", "/friends", new BasicDosProtectorOptions() + { + AllowXForwardedFor = true, + ForgetTimeSpan = TimeSpan.FromMinutes(2), + MaxRequestsInTimeframe = 5, + ReportingName = "FRIENDSDOSPROTECTOR", + RequestTimeSpan = TimeSpan.FromSeconds(5), + ThrottledAction = ThrottleAction.DoThrottledMethod + }) { m_FriendsModule = fmodule; } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index a26a5f0..0f05e07 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -165,7 +165,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap regionimage = regionimage.Replace("-", ""); m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); - MainServer.Instance.AddHTTPHandler(regionimage, OnHTTPGetMapImage); + MainServer.Instance.AddHTTPHandler(regionimage, + new GenericHTTPDOSProtector(OnHTTPGetMapImage, OnHTTPThrottled, new BasicDosProtectorOptions() + { + AllowXForwardedFor = false, + ForgetTimeSpan = TimeSpan.FromMinutes(2), + MaxRequestsInTimeframe = 4, + ReportingName = "MAPDOSPROTECTOR", + RequestTimeSpan = TimeSpan.FromSeconds(10), + ThrottledAction = ThrottleAction.DoThrottledMethod + }).Process); MainServer.Instance.AddLLSDHandler( "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); @@ -1081,6 +1090,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); } + public Hashtable OnHTTPThrottled(Hashtable keysvals) + { + Hashtable reply = new Hashtable(); + int statuscode = 500; + reply["str_response_string"] = "I blocked you! HAHAHAHAHAHAHHAHAH"; + reply["int_response_code"] = statuscode; + reply["content_type"] = "text/plain"; + return reply; + } + public Hashtable OnHTTPGetMapImage(Hashtable keysvals) { m_log.Debug("[WORLD MAP]: Sending map image jpeg"); -- cgit v1.1 From 75fdd6054d6605877acb511b1bd794de963a15f3 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 7 Oct 2013 23:19:50 -0500 Subject: * Refactor * Break out common BasicDOSProtector code into separate class. --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs | 4 ++-- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index ed4b205..ff87ece 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs @@ -53,10 +53,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { AllowXForwardedFor = true, ForgetTimeSpan = TimeSpan.FromMinutes(2), - MaxRequestsInTimeframe = 5, + MaxRequestsInTimeframe = 20, ReportingName = "FRIENDSDOSPROTECTOR", RequestTimeSpan = TimeSpan.FromSeconds(5), - ThrottledAction = ThrottleAction.DoThrottledMethod + ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod }) { m_FriendsModule = fmodule; diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 0f05e07..cdf1467 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap MaxRequestsInTimeframe = 4, ReportingName = "MAPDOSPROTECTOR", RequestTimeSpan = TimeSpan.FromSeconds(10), - ThrottledAction = ThrottleAction.DoThrottledMethod + ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod }).Process); MainServer.Instance.AddLLSDHandler( "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); @@ -1094,7 +1094,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { Hashtable reply = new Hashtable(); int statuscode = 500; - reply["str_response_string"] = "I blocked you! HAHAHAHAHAHAHHAHAH"; + reply["str_response_string"] = ""; reply["int_response_code"] = statuscode; reply["content_type"] = "text/plain"; return reply; -- cgit v1.1 From 8b5e2f2cd28510fc249bade0ca0d71e02b6b5f34 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 11 Oct 2013 13:29:43 -0700 Subject: BulletSim: Fix snap back from edge of region problem. Mantis 6794. --- OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c4807c4..c016eed 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs @@ -354,6 +354,8 @@ public sealed class BSTerrainManager : IDisposable // Return a new position that is over known terrain if the position is outside our terrain. public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos) { + float edgeEpsilon = 0.1f; + Vector3 ret = pPos; // First, base addresses are never negative so correct for that possible problem. @@ -378,10 +380,19 @@ public sealed class BSTerrainManager : IDisposable // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. // Must be off the top of a region. Find an adjacent region to move into. + // The returned terrain is always 'lower'. That is, closer to <0,0>. Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); - ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X)); - ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y)); + if (adjacentTerrainBase.X < terrainBaseXYZ.X) + { + // moving down into a new region in the X dimension. New position will be the max in the new base. + ret.X = adjacentTerrainBase.X + DefaultRegionSize.X - edgeEpsilon; + } + if (adjacentTerrainBase.Y < terrainBaseXYZ.Y) + { + // moving down into a new region in the X dimension. New position will be the max in the new base. + ret.Y = adjacentTerrainBase.Y + DefaultRegionSize.Y - edgeEpsilon; + } DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); -- cgit v1.1 From f106ba87ca92b477b32a84aa246e4b4481b0980b Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Wed, 18 Sep 2013 15:55:42 +0300 Subject: Made terrain uploads thread-safe --- .../AssetTransaction/AgentAssetsTransactions.cs | 9 +++++ .../World/Estate/EstateManagementModule.cs | 47 +++++++++++++--------- .../World/Estate/EstateTerrainXferHandler.cs | 6 ++- .../Region/Framework/Interfaces/IEstateModule.cs | 5 +++ 4 files changed, 45 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 0271738..f56d17d 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs @@ -33,6 +33,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { @@ -119,6 +120,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } else { + // Check if the xfer is a terrain xfer + IEstateModule estateModule = m_Scene.RequestModuleInterface(); + if (estateModule != null) + { + if (estateModule.IsTerrainXfer(xferID)) + return; + } + m_log.ErrorFormat( "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", xferID, packetID, data.Length); diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 42db1cf..17387da 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -829,26 +829,23 @@ namespace OpenSim.Region.CoreModules.World.Estate private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) { - if (TerrainUploader != null) + lock (this) { - lock (TerrainUploader) + if ((TerrainUploader != null) && (XferID == TerrainUploader.XferID)) { - if (XferID == TerrainUploader.XferID) - { - remoteClient.OnXferReceive -= TerrainUploader.XferReceive; - remoteClient.OnAbortXfer -= AbortTerrainXferHandler; - TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; + remoteClient.OnXferReceive -= TerrainUploader.XferReceive; + remoteClient.OnAbortXfer -= AbortTerrainXferHandler; + TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; - TerrainUploader = null; - remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); - } + TerrainUploader = null; + remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); } } - } + private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) { - lock (TerrainUploader) + lock (this) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; @@ -907,22 +904,32 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) { - if (TerrainUploader == null) + lock (this) { - - TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); - lock (TerrainUploader) + if (TerrainUploader == null) { + m_log.DebugFormat("Starting to receive uploaded terrain"); + TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); remote_client.OnXferReceive += TerrainUploader.XferReceive; remote_client.OnAbortXfer += AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone += HandleTerrainApplication; + TerrainUploader.RequestStartXfer(remote_client); + } + else + { + remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); } - TerrainUploader.RequestStartXfer(remote_client); - } - else + } + + public bool IsTerrainXfer(ulong xferID) + { + lock (this) { - remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); + if (TerrainUploader == null) + return false; + else + return TerrainUploader.XferID == xferID; } } diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs index b8d8b10..2d74eaf 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs @@ -78,7 +78,10 @@ namespace OpenSim.Region.CoreModules.World.Estate /// public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) { - if (mXferID == xferID) + if (mXferID != xferID) + return; + + lock (this) { if (m_asset.Data.Length > 1) { @@ -99,7 +102,6 @@ namespace OpenSim.Region.CoreModules.World.Estate if ((packetID & 0x80000000) != 0) { SendCompleteMessage(remoteClient); - } } } diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index d49b24e..944c66b 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces void setEstateTerrainBaseTexture(int level, UUID texture); void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue); + + /// + /// Returns whether the transfer ID is being used for a terrain transfer. + /// + bool IsTerrainXfer(ulong xferID); } } -- cgit v1.1 From 5ca7395e175b476fd20fcf97383c8eb09b64ae3a Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Fri, 2 Aug 2013 15:26:28 -0400 Subject: Added support for attachments to group notices when using Flotsam groups. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 172 +++++++++++++++------ 1 file changed, 122 insertions(+), 50 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d744a14..d09d3ad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -39,6 +39,7 @@ using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using System.Text; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups @@ -421,44 +422,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string Subject = im.message.Substring(0, im.message.IndexOf('|')); string Message = im.message.Substring(Subject.Length + 1); + InventoryItemBase item = null; + bool hasAttachment = false; + UUID itemID = UUID.Zero; //Assignment to quiet compiler + UUID ownerID = UUID.Zero; //Assignment to quiet compiler byte[] bucket; - if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) - { - bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno - GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno - } - else + if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) { string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); binBucket = binBucket.Remove(0, 14).Trim(); - if (m_debugEnabled) + + OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + if (binBucketOSD is OSD) { - m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); + OSDMap binBucketMap = (OSDMap)binBucketOSD; + + itemID = binBucketMap["item_id"].AsUUID(); + ownerID = binBucketMap["owner_id"].AsUUID(); - OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); - - foreach (string key in binBucketOSD.Keys) + //Attempt to get the details of the attached item. + //If sender doesn't own the attachment, the item + //variable will be set to null and attachment will + //not be included with the group notice. + Scene scene = (Scene)remoteClient.Scene; + item = new InventoryItemBase(itemID, ownerID); + item = scene.InventoryService.GetItem(item); + + if (item != null) { - if (binBucketOSD.ContainsKey(key)) - { - m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); - } + //Got item details so include the attachment. + hasAttachment = true; } } - - // treat as if no attachment + else + { + m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); + } + } + + if (hasAttachment) + { + //Bucket contains information about attachment. + // + //Byte offset and description of bucket data: + //0: 1 byte indicating if attachment is present + //1: 1 byte indicating the type of attachment + //2: 16 bytes - Group UUID + //18: 16 bytes - UUID of the attachment owner + //34: 16 bytes - UUID of the attachment + //50: variable - Name of the attachment + //??: NUL byte to terminate the attachment name + byte[] name = Encoding.UTF8.GetBytes(item.Name); + bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name + bucket[0] = 1; //Has attachment flag + bucket[1] = (byte)item.InvType; //Type of Attachment + GroupID.ToBytes(bucket, 2); + ownerID.ToBytes(bucket, 18); + itemID.ToBytes(bucket, 34); + name.CopyTo(bucket, 50); + } + else + { bucket = new byte[19]; - bucket[0] = 0; //dunno - bucket[1] = 0; //dunno + bucket[0] = 0; //Has attachment flag + bucket[1] = 0; //Type of attachment GroupID.ToBytes(bucket, 2); - bucket[18] = 0; //dunno + bucket[18] = 0; //NUL terminate name of attachment } - m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { @@ -483,7 +515,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (member.AcceptNotices) { - // Build notice IIM + // Build notice IM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); msg.toAgentID = member.AgentID.Guid; @@ -492,10 +524,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - + + if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) + { + //Is bucket large enough to hold UUID of the attachment? + if (im.binaryBucket.Length < 16) + return; + + UUID noticeID = new UUID(im.imSessionID); + + GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); + if (notice != null) + { + UUID giver = new UUID(notice.BinaryBucket, 18); + UUID attachmentUUID = new UUID(notice.BinaryBucket, 34); + + if (m_debugEnabled) + m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); + + InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, + giver, attachmentUUID); + + if (itemCopy == null) + { + remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); + return; + } + + remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); + } + } + // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the + // TODO:FIXME: Use a presence server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue if ((im.dialog == 210)) @@ -873,26 +935,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); - - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; - msg.message = data.noticeData.Subject + "|" + data.Message; - msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; - msg.fromGroup = true; - msg.offline = (byte)0; - msg.ParentEstateID = 0; - msg.Position = Vector3.Zero; - msg.RegionID = UUID.Zero.Guid; - msg.binaryBucket = data.BinaryBucket; + GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } - } public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) @@ -900,10 +946,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = UUID.Zero.Guid; + byte[] bucket; + + msg.imSessionID = groupNoticeID.Guid; msg.toAgentID = agentID.Guid; msg.dialog = dialog; - // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; msg.fromGroup = true; msg.offline = (byte)0; msg.ParentEstateID = 0; @@ -917,13 +964,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.timestamp = info.noticeData.Timestamp; msg.fromAgentName = info.noticeData.FromName; msg.message = info.noticeData.Subject + "|" + info.Message; - msg.binaryBucket = info.BinaryBucket; + + if (info.BinaryBucket[0] > 0) + { + //32 is due to not needing space for two of the UUIDs. + //(Don't need UUID of attachment or its owner in IM) + //50 offset gets us to start of attachment name. + //We are skipping the attachment flag, type, and + //the three UUID fields at the start of the bucket. + bucket = new byte[info.BinaryBucket.Length-32]; + bucket[0] = 1; //Has attachment + bucket[1] = info.BinaryBucket[1]; + Array.Copy(info.BinaryBucket, 50, + bucket, 18, info.BinaryBucket.Length-50); + } + else + { + bucket = new byte[19]; + bucket[0] = 0; //No attachment + bucket[1] = 0; //Attachment type + bucket[18] = 0; //NUL terminate name + } + + info.GroupID.ToBytes(bucket, 2); + msg.binaryBucket = bucket; } else { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); + msg.fromAgentID = UUID.Zero.Guid; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = string.Empty; msg.message = string.Empty; msg.binaryBucket = new byte[0]; @@ -1047,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Message to ejector // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid - // TODO:FIXME: Use a presense server of some kind to find out where the + // TODO:FIXME: Use a presence server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue -- cgit v1.1 From d0c17808391e93964dcaf0ffcf06899c5669f4ff Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Wed, 25 Sep 2013 10:56:05 +0300 Subject: Fixed rezzing coalesced objects from a prim's inventory Previously only the first object in the Coalesced Object was rezzed. Now all the objects are rezzed. --- .../InventoryAccess/InventoryAccessModule.cs | 51 ++------- .../Framework/Interfaces/IEntityInventory.cs | 10 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 119 +++++++++++++++++---- .../Framework/Scenes/SceneObjectPartInventory.cs | 101 +++++++++-------- .../Shared/Api/Implementation/LSL_Api.cs | 41 +++---- 5 files changed, 188 insertions(+), 134 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0ec9575..831922e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -757,64 +757,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess SceneObjectGroup group = null; - string xmlData = Utils.BytesToString(rezAsset.Data); - List objlist = new List(); - List veclist = new List(); + List objlist; + List veclist; + Vector3 bbox; + float offsetHeight; byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 pos; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xmlData); - XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); - if (e == null || attachment) // Single - { - SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - objlist.Add(g); - veclist.Add(Vector3.Zero); + bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); - float offsetHeight = 0; + if (single) + { pos = m_Scene.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); + BypassRayCast, bRayEndIsIntersection, true, bbox, false); pos.Z += offsetHeight; } else { - XmlElement coll = (XmlElement)e; - float bx = Convert.ToSingle(coll.GetAttribute("x")); - float by = Convert.ToSingle(coll.GetAttribute("y")); - float bz = Convert.ToSingle(coll.GetAttribute("z")); - Vector3 bbox = new Vector3(bx, by, bz); - pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, bbox, false); - pos -= bbox / 2; - - XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); - foreach (XmlNode n in groups) - { - SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); - - objlist.Add(g); - XmlElement el = (XmlElement)n; - - string rawX = el.GetAttribute("offsetx"); - string rawY = el.GetAttribute("offsety"); - string rawZ = el.GetAttribute("offsetz"); -// -// m_log.DebugFormat( -// "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", -// g.Name, rawX, rawY, rawZ); - - float x = Convert.ToSingle(rawX); - float y = Convert.ToSingle(rawY); - float z = Convert.ToSingle(rawZ); - veclist.Add(new Vector3(x, y, z)); - } } if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 150193d..9ffda51 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -234,15 +234,17 @@ namespace OpenSim.Region.Framework.Interfaces List GetInventoryItems(InventoryType type); /// - /// Get the scene object referenced by an inventory item. + /// Get the scene object(s) referenced by an inventory item. /// /// /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have /// been adjusted to reflect the part and item from which it originates. /// - /// - /// The scene object. Null if the scene object asset couldn't be found - SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item); + /// Inventory item + /// The scene objects + /// Relative offsets for each object + /// true = success, false = the scene object asset couldn't be found + bool GetRezReadySceneObjects(TaskInventoryItem item, out List objlist, out List veclist); /// /// Update an existing inventory item. diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4bebbe8..65536db 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -31,6 +31,7 @@ using System.Collections; using System.Reflection; using System.Text; using System.Timers; +using System.Xml; using OpenMetaverse; using OpenMetaverse.Packets; using log4net; @@ -2135,6 +2136,69 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Returns the list of Scene Objects in an asset. + /// + /// + /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. + /// + /// Asset data + /// Whether the item is an attachment + /// The objects included in the asset + /// Relative positions of the objects + /// Bounding box of all the objects + /// Offset in the Z axis from the centre of the bounding box + /// to the centre of the root prim (relevant only when returning a single object) + /// true = returning a single object; false = multiple objects + public bool GetObjectsToRez(byte[] assetData, bool attachment, out List objlist, out List veclist, + out Vector3 bbox, out float offsetHeight) + { + objlist = new List(); + veclist = new List(); + + XmlDocument doc = new XmlDocument(); + string xmlData = Utils.BytesToString(assetData); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + + if (e == null || attachment) // Single + { + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + objlist.Add(g); + veclist.Add(new Vector3(0, 0, 0)); + bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); + return true; + } + else + { + XmlElement coll = (XmlElement)e; + float bx = Convert.ToSingle(coll.GetAttribute("x")); + float by = Convert.ToSingle(coll.GetAttribute("y")); + float bz = Convert.ToSingle(coll.GetAttribute("z")); + bbox = new Vector3(bx, by, bz); + offsetHeight = 0; + + XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); + foreach (XmlNode n in groups) + { + SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); + objlist.Add(g); + + XmlElement el = (XmlElement)n; + string rawX = el.GetAttribute("offsetx"); + string rawY = el.GetAttribute("offsety"); + string rawZ = el.GetAttribute("offsetz"); + + float x = Convert.ToSingle(rawX); + float y = Convert.ToSingle(rawY); + float z = Convert.ToSingle(rawZ); + veclist.Add(new Vector3(x, y, z)); + } + } + + return false; + } + + /// /// Event Handler Rez an object into a scene /// Calls the non-void event handler /// @@ -2209,19 +2273,25 @@ namespace OpenSim.Region.Framework.Scenes /// will be used if it exists. /// The velocity of the rezzed object. /// - /// The SceneObjectGroup rezzed or null if rez was unsuccessful - public virtual SceneObjectGroup RezObject( + /// The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful + public virtual List RezObject( SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) { if (null == item) return null; + + List objlist; + List veclist; - SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); - - if (null == group) + bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); + if (!success) return null; - - if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) + + int totalPrims = 0; + foreach (SceneObjectGroup group in objlist) + totalPrims += group.PrimCount; + + if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos)) return null; if (!Permissions.BypassPermissions()) @@ -2230,23 +2300,28 @@ namespace OpenSim.Region.Framework.Scenes sourcePart.Inventory.RemoveInventoryItem(item.ItemID); } - - if (group.IsAttachment == false && group.RootPart.Shape.State != 0) + for (int i = 0; i < objlist.Count; i++) { - group.RootPart.AttachedPos = group.AbsolutePosition; - group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; + SceneObjectGroup group = objlist[i]; + Vector3 curpos = pos + veclist[i]; + + if (group.IsAttachment == false && group.RootPart.Shape.State != 0) + { + group.RootPart.AttachedPos = group.AbsolutePosition; + group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; + } + + group.FromPartID = sourcePart.UUID; + AddNewSceneObject(group, true, curpos, rot, vel); + + // We can only call this after adding the scene object, since the scene object references the scene + // to find out if scripts should be activated at all. + group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); + + group.ScheduleGroupForFullUpdate(); } - - group.FromPartID = sourcePart.UUID; - AddNewSceneObject(group, true, pos, rot, vel); - - // We can only call this after adding the scene object, since the scene object references the scene - // to find out if scripts should be activated at all. - group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); - - group.ScheduleGroupForFullUpdate(); - - return group; + + return objlist; } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3f223a3..380e402 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -733,8 +733,8 @@ namespace OpenSim.Region.Framework.Scenes return items; } - - public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) + + public bool GetRezReadySceneObjects(TaskInventoryItem item, out List objlist, out List veclist) { AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); @@ -743,66 +743,75 @@ namespace OpenSim.Region.Framework.Scenes m_log.WarnFormat( "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", item.AssetID, item.Name, m_part.Name); - return null; + objlist = null; + veclist = null; + return false; } - string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + Vector3 bbox; + float offsetHeight; - group.ResetIDs(); + bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight); - SceneObjectPart rootPart = group.GetPart(group.UUID); + for (int i = 0; i < objlist.Count; i++) + { + SceneObjectGroup group = objlist[i]; - // 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; + group.ResetIDs(); - SceneObjectPart[] partList = group.Parts; + SceneObjectPart rootPart = group.GetPart(group.UUID); - group.SetGroup(m_part.GroupID, null); + // 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; - // TODO: Remove magic number badness - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number - { - if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) + SceneObjectPart[] partList = group.Parts; + + group.SetGroup(m_part.GroupID, null); + + // TODO: Remove magic number badness + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number { - foreach (SceneObjectPart part in partList) + if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) { - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) - part.EveryoneMask = item.EveryonePermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) - part.NextOwnerMask = item.NextPermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) - part.GroupMask = item.GroupPermissions; + foreach (SceneObjectPart part in partList) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryonePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; + } + + group.ApplyNextOwnerPermissions(); } - - group.ApplyNextOwnerPermissions(); } - } - foreach (SceneObjectPart part in partList) - { - // TODO: Remove magic number badness - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + foreach (SceneObjectPart part in partList) { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.OwnerID; - part.Inventory.ChangeInventoryOwner(item.OwnerID); + // TODO: Remove magic number badness + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.Inventory.ChangeInventoryOwner(item.OwnerID); + } + + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryonePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; } - - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) - part.EveryoneMask = item.EveryonePermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) - part.NextOwnerMask = item.NextPermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) - part.GroupMask = item.GroupPermissions; + + rootPart.TrimPermissions(); } - - rootPart.TrimPermissions(); - - return group; + + return true; } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 975bf2d..b19ed0a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2970,37 +2970,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // need the magnitude later // float velmag = (float)Util.GetMagnitude(llvel); - SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param); + List new_groups = World.RezObject(m_host, item, pos, rot, vel, param); // If either of these are null, then there was an unknown error. - if (new_group == null) + if (new_groups == null) return; - // objects rezzed with this method are die_at_edge by default. - new_group.RootPart.SetDieAtEdge(true); + foreach (SceneObjectGroup group in new_groups) + { + // objects rezzed with this method are die_at_edge by default. + group.RootPart.SetDieAtEdge(true); - new_group.ResumeScripts(); + group.ResumeScripts(); - m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( - "object_rez", new Object[] { - new LSL_String( - new_group.RootPart.UUID.ToString()) }, - new DetectParams[0])); + m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( + "object_rez", new Object[] { + new LSL_String( + group.RootPart.UUID.ToString()) }, + new DetectParams[0])); - float groupmass = new_group.GetMass(); + float groupmass = group.GetMass(); - PhysicsActor pa = new_group.RootPart.PhysActor; + PhysicsActor pa = group.RootPart.PhysActor; - //Recoil. - if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) - { - Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; - if (recoil != Vector3.Zero) + //Recoil. + if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) { - llApplyImpulse(recoil, 0); + Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; + if (recoil != Vector3.Zero) + { + llApplyImpulse(recoil, 0); + } } + // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) } - // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) }); //ScriptSleep((int)((groupmass * velmag) / 10)); -- cgit v1.1 From 766a31431e41033b9cddf5759e9b6e1b4c77682a Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 15 Oct 2013 17:02:22 -0700 Subject: BulletSim: implement the SL bug where VEHICLE_HOVER_UP_ONLY disables the vehicle buoyancy if the vehicle is above its hover height. This is a known misfeature of this vehicle flag which has been accepted since it would break too many implementations. The problem is noticed when creating a jetski-like vehicle that jumps over sand bars. A boat normally is configured with neutral buoyancy and hovering at water height. When it jumps the sandbar, it needs to have gravity applied to get back to water level. --- OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f0d17d3..7b98f9d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -1125,7 +1125,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // If body is already heigher, use its height as target height if (VehiclePosition.Z > m_VhoverTargetHeight) + { m_VhoverTargetHeight = VehiclePosition.Z; + + // A 'misfeature' of this flag is that if the vehicle is above it's hover height, + // the vehicle's buoyancy goes away. This is an SL bug that got used by so many + // scripts that it could not be changed. + // So, if above the height, reapply gravity if buoyancy had it turned off. + if (m_VehicleBuoyancy != 0) + { + Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass; + VehicleAddForce(appliedGravity); + } + } } if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) -- cgit v1.1 From 0094971186b7ba96df454acdf221f702bc214be5 Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Mon, 16 Sep 2013 13:31:48 +0300 Subject: After finishing to edit an attachment, let other avatars see the changes. (The changes weren't visible before because updates to attachments aren't sent while the attachment is selected.) --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 9 ++------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 998c19e..cddf818 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -244,25 +244,20 @@ namespace OpenSim.Region.Framework.Scenes 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(); + 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 (!part.ParentGroup.IsAttachment) { if (Permissions.CanEditObject( part.UUID, remoteClient.AgentId) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b3e6b67..9e6c25d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2700,7 +2700,8 @@ namespace OpenSim.Region.Framework.Scenes return; // This was pulled from SceneViewer. Attachments always receive full updates. - // I could not verify if this is a requirement but this maintains existing behavior + // This is needed because otherwise if only the root prim changes position, then + // it looks as if the entire object has moved (including the other prims). if (ParentGroup.IsAttachment) { ScheduleFullUpdate(); -- cgit v1.1 From 84a149ecbff485400a4d1032677c8f15946ccb29 Mon Sep 17 00:00:00 2001 From: Kevin Cozens Date: Tue, 15 Oct 2013 21:15:48 -0400 Subject: Call ScriptSleep() instead of llSleep() in routine for llEmail. Signed-off-by: teravus --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b19ed0a..8650b91 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3325,7 +3325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } emailModule.SendEmail(m_host.UUID, address, subject, message); - llSleep(EMAIL_PAUSE_TIME); + ScriptSleep(EMAIL_PAUSE_TIME * 1000); } public void llGetNextEmail(string address, string subject) -- cgit v1.1