diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 37d7a88a63..04446ced4f 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -677,7 +677,8 @@ namespace OpenSim.Data.MySQL "MusicURL, PassHours, PassPrice, SnapshotUUID, " + "UserLocationX, UserLocationY, UserLocationZ, " + "UserLookAtX, UserLookAtY, UserLookAtZ, " + - "AuthbuyerID, OtherCleanTime, Dwell) values (" + + "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + + "MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" + "?UUID, ?RegionUUID, " + "?LocalLandID, ?Bitmap, ?Name, ?Description, " + "?OwnerUUID, ?IsGroupOwned, ?Area, ?AuctionID, " + @@ -687,7 +688,8 @@ namespace OpenSim.Data.MySQL "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + - "?AuthbuyerID, ?OtherCleanTime, ?Dwell)"; + "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ + "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)"; FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); @@ -1347,6 +1349,14 @@ namespace OpenSim.Data.MySQL m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); } + newData.MediaDescription = (string) row["MediaDescription"]; + newData.MediaType = (string) row["MediaType"]; + newData.MediaWidth = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[0]); + newData.MediaHeight = Convert.ToInt32((((string) row["MediaSize"]).Split(','))[1]); + newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); + newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); + newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); + newData.ParcelAccessList = new List(); return newData; @@ -1651,6 +1661,14 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); cmd.Parameters.AddWithValue("Dwell", land.Dwell); + cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription); + cmd.Parameters.AddWithValue("MediaType", land.MediaType); + cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth); + cmd.Parameters.AddWithValue("MediaHeight", land.MediaHeight); + cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop); + cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic); + cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia); + } /// diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index ce99ce4c9a..5c32209db6 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -801,9 +801,19 @@ ALTER TABLE `regionwindlight` CHANGE COLUMN `cloud_scroll_x` `cloud_scroll_x` F COMMIT; :VERSION 35 #--------------------- --- Added post 0.7 BEGIN; ALTER TABLE prims ADD COLUMN MediaURL varchar(255); ALTER TABLE primshapes ADD COLUMN Media TEXT; -COMMIT; \ No newline at end of file +COMMIT; + +:VERSION 36 #--------------------- + +BEGIN; +ALTER TABLE `land` ADD COLUMN `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none' ; +ALTER TABLE `land` ADD COLUMN `MediaDescription` VARCHAR(255) NOT NULL DEFAULT ''; +ALTER TABLE `land` ADD COLUMN `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0'; +ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE; +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index c461bf0727..0c421ec037 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -446,3 +446,13 @@ update land where AuthbuyerID not like '%-%'; COMMIT; + +:VERSION 19 +BEGIN ; +ALTER TABLE `land` ADD COLUMN `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none' ; +ALTER TABLE `land` ADD COLUMN `MediaDescription` VARCHAR(255) NOT NULL DEFAULT ''; +ALTER TABLE `land` ADD COLUMN `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0'; +ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE; +COMMIT ; \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 4208050ab9..8432e74592 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -1762,6 +1762,12 @@ namespace OpenSim.Data.SQLite row["AuthbuyerID"] = land.AuthBuyerID.ToString(); row["OtherCleanTime"] = land.OtherCleanTime; row["Dwell"] = land.Dwell; + row["MediaType"] = land.MediaType; + row["MediaDescription"] = land.MediaDescription; + row["MediaSize"] = land.MediaWidth.ToString() + "," + land.MediaHeight.ToString(); + row["MediaLoop"] = land.MediaLoop.ToString(); + row["ObscureMusic"] = land.ObscureMusic.ToString(); + row["ObscureMedia"] = land.ObscureMedia.ToString(); } /// diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index ef074386c2..4440c94163 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -90,6 +90,78 @@ namespace OpenSim.Framework private Vector3 _userLookAt = new Vector3(); private int _dwell = 0; private int _otherCleanTime = 0; + private string _mediaType = "none/none"; + private string _mediaDescription = ""; + private int _mediaHeight = 0; + private int _mediaWidth = 0; + private bool _mediaLoop = false; + private bool _obscureMusic = false; + private bool _obscureMedia = false; + + /// + /// Whether to obscure parcel media URL + /// + [XmlIgnore] + public bool ObscureMedia { + get { + return _obscureMedia; + } + set { + _obscureMedia = value; + } + } + + /// + /// Whether to obscure parcel music URL + /// + [XmlIgnore] + public bool ObscureMusic { + get { + return _obscureMusic; + } + set { + _obscureMusic = value; + } + } + + /// + /// Whether to loop parcel media + /// + [XmlIgnore] + public bool MediaLoop { + get { + return _mediaLoop; + } + set { + _mediaLoop = value; + } + } + + /// + /// Height of parcel media render + /// + [XmlIgnore] + public int MediaHeight { + get { + return _mediaHeight; + } + set { + _mediaHeight = value; + } + } + + /// + /// Width of parcel media render + /// + [XmlIgnore] + public int MediaWidth { + get { + return _mediaWidth; + } + set { + _mediaWidth = value; + } + } /// /// Upper corner of the AABB for the parcel @@ -358,20 +430,6 @@ namespace OpenSim.Framework } } - private int[] _mediaSize = new int[2]; - public int[] MediaSize - { - get - { - return _mediaSize; - } - set - { - _mediaSize = value; - } - } - - private string _mediaType = ""; public string MediaType { get @@ -586,6 +644,17 @@ namespace OpenSim.Framework } } + /// + /// parcel media description + /// + public string MediaDescription { + get { + return _mediaDescription; + } + set { + _mediaDescription = value; + } + } public LandData() { @@ -635,6 +704,13 @@ namespace OpenSim.Framework landData._userLookAt = _userLookAt; landData._otherCleanTime = _otherCleanTime; landData._dwell = _dwell; + landData._mediaType = _mediaType; + landData._mediaDescription = _mediaDescription; + landData._mediaWidth = _mediaWidth; + landData._mediaHeight = _mediaHeight; + landData._mediaLoop = _mediaLoop; + landData._obscureMusic = _obscureMusic; + landData._obscureMedia = _obscureMedia; landData._parcelAccessList.Clear(); foreach (ParcelManager.ParcelAccessEntry entry in _parcelAccessList) diff --git a/OpenSim/Framework/LandUpdateArgs.cs b/OpenSim/Framework/LandUpdateArgs.cs index 9760a1d328..ed496a1455 100644 --- a/OpenSim/Framework/LandUpdateArgs.cs +++ b/OpenSim/Framework/LandUpdateArgs.cs @@ -49,5 +49,12 @@ namespace OpenSim.Framework public UUID SnapshotID; public Vector3 UserLocation; public Vector3 UserLookAt; + public string MediaType; + public string MediaDescription; + public int MediaHeight; + public int MediaWidth; + public bool MediaLoop; + public bool ObscureMusic; + public bool ObscureMedia; } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 87ed90f8f4..105501fe59 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -37,6 +37,7 @@ using System.Xml; using log4net; using OpenMetaverse; using OpenMetaverse.Packets; +using OpenMetaverse.Messages.Linden; using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Client; @@ -328,7 +329,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an /// ownerless phantom. /// - /// All manipulation of this set has to occur under a m_primFullUpdate.SyncRoot lock + /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock /// /// protected HashSet m_killRecord; @@ -394,18 +395,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP public string ActiveGroupName { get { return m_activeGroupName; } } public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } + /// /// First name of the agent/avatar represented by the client /// public string FirstName { get { return m_firstName; } } + /// /// Last name of the agent/avatar represented by the client /// public string LastName { get { return m_lastName; } } + /// /// Full name of the client (first name and last name) /// public string Name { get { return FirstName + " " + LastName; } } + public uint CircuitCode { get { return m_circuitCode; } } public int MoneyBalance { get { return m_moneyBalance; } } public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } @@ -2743,6 +2748,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP DirPlacesReplyPacket.StatusDataBlock[] status = new DirPlacesReplyPacket.StatusDataBlock[0]; + packet.QueryReplies = replies; + packet.StatusData = status; + foreach (DirPlacesReplyData d in data) { int idx = replies.Length; @@ -2781,7 +2789,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - if (replies.Length > 0) + if (replies.Length > 0 || data.Length == 0) OutPacket(packet, ThrottleOutPacketType.Task); } @@ -4213,94 +4221,101 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, LandData landData, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags) { - ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ParcelProperties); - // TODO: don't create new blocks if recycling an old packet + ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage(); - updatePacket.ParcelData.AABBMax = landData.AABBMax; - updatePacket.ParcelData.AABBMin = landData.AABBMin; - updatePacket.ParcelData.Area = landData.Area; - updatePacket.ParcelData.AuctionID = landData.AuctionID; - updatePacket.ParcelData.AuthBuyerID = landData.AuthBuyerID; + updateMessage.AABBMax = landData.AABBMax; + updateMessage.AABBMin = landData.AABBMin; + updateMessage.Area = landData.Area; + updateMessage.AuctionID = landData.AuctionID; + updateMessage.AuthBuyerID = landData.AuthBuyerID; - updatePacket.ParcelData.Bitmap = landData.Bitmap; + updateMessage.Bitmap = landData.Bitmap; - updatePacket.ParcelData.Desc = Utils.StringToBytes(landData.Description); - updatePacket.ParcelData.Category = (byte)landData.Category; - updatePacket.ParcelData.ClaimDate = landData.ClaimDate; - updatePacket.ParcelData.ClaimPrice = landData.ClaimPrice; - updatePacket.ParcelData.GroupID = landData.GroupID; - updatePacket.ParcelData.GroupPrims = landData.GroupPrims; - updatePacket.ParcelData.IsGroupOwned = landData.IsGroupOwned; - updatePacket.ParcelData.LandingType = landData.LandingType; - updatePacket.ParcelData.LocalID = landData.LocalID; + updateMessage.Desc = landData.Description; + updateMessage.Category = landData.Category; + updateMessage.ClaimDate = Util.ToDateTime(landData.ClaimDate); + updateMessage.ClaimPrice = landData.ClaimPrice; + updateMessage.GroupID = landData.GroupID; + updateMessage.GroupPrims = landData.GroupPrims; + updateMessage.IsGroupOwned = landData.IsGroupOwned; + updateMessage.LandingType = (LandingType) landData.LandingType; + updateMessage.LocalID = landData.LocalID; if (landData.Area > 0) { - updatePacket.ParcelData.MaxPrims = parcelObjectCapacity; + updateMessage.MaxPrims = parcelObjectCapacity; } else { - updatePacket.ParcelData.MaxPrims = 0; + updateMessage.MaxPrims = 0; } - updatePacket.ParcelData.MediaAutoScale = landData.MediaAutoScale; - updatePacket.ParcelData.MediaID = landData.MediaID; - updatePacket.ParcelData.MediaURL = Util.StringToBytes256(landData.MediaURL); - updatePacket.ParcelData.MusicURL = Util.StringToBytes256(landData.MusicURL); - updatePacket.ParcelData.Name = Util.StringToBytes256(landData.Name); - updatePacket.ParcelData.OtherCleanTime = landData.OtherCleanTime; - updatePacket.ParcelData.OtherCount = 0; //TODO: Unimplemented - updatePacket.ParcelData.OtherPrims = landData.OtherPrims; - updatePacket.ParcelData.OwnerID = landData.OwnerID; - updatePacket.ParcelData.OwnerPrims = landData.OwnerPrims; - updatePacket.ParcelData.ParcelFlags = landData.Flags; - updatePacket.ParcelData.ParcelPrimBonus = simObjectBonusFactor; - updatePacket.ParcelData.PassHours = landData.PassHours; - updatePacket.ParcelData.PassPrice = landData.PassPrice; - updatePacket.ParcelData.PublicCount = 0; //TODO: Unimplemented + updateMessage.MediaAutoScale = Convert.ToBoolean(landData.MediaAutoScale); + updateMessage.MediaID = landData.MediaID; + updateMessage.MediaURL = landData.MediaURL; + updateMessage.MusicURL = landData.MusicURL; + updateMessage.Name = landData.Name; + updateMessage.OtherCleanTime = landData.OtherCleanTime; + updateMessage.OtherCount = 0; //TODO: Unimplemented + updateMessage.OtherPrims = landData.OtherPrims; + updateMessage.OwnerID = landData.OwnerID; + updateMessage.OwnerPrims = landData.OwnerPrims; + updateMessage.ParcelFlags = (ParcelFlags) landData.Flags; + updateMessage.ParcelPrimBonus = simObjectBonusFactor; + updateMessage.PassHours = landData.PassHours; + updateMessage.PassPrice = landData.PassPrice; + updateMessage.PublicCount = 0; //TODO: Unimplemented + + updateMessage.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; + updateMessage.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; - updatePacket.ParcelData.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; - updatePacket.ParcelData.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; - updatePacket.ParcelData.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; - updatePacket.ParcelData.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; + //updateMessage.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; + //updateMessage.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; - updatePacket.ParcelData.RentPrice = 0; - updatePacket.ParcelData.RequestResult = request_result; - updatePacket.ParcelData.SalePrice = landData.SalePrice; - updatePacket.ParcelData.SelectedPrims = landData.SelectedPrims; - updatePacket.ParcelData.SelfCount = 0; //TODO: Unimplemented - updatePacket.ParcelData.SequenceID = sequence_id; + updateMessage.RentPrice = 0; + updateMessage.RequestResult = (ParcelResult) request_result; + updateMessage.SalePrice = landData.SalePrice; + updateMessage.SelectedPrims = landData.SelectedPrims; + updateMessage.SelfCount = 0; //TODO: Unimplemented + updateMessage.SequenceID = sequence_id; if (landData.SimwideArea > 0) { - updatePacket.ParcelData.SimWideMaxPrims = parcelObjectCapacity; + updateMessage.SimWideMaxPrims = parcelObjectCapacity; } else { - updatePacket.ParcelData.SimWideMaxPrims = 0; + updateMessage.SimWideMaxPrims = 0; } - updatePacket.ParcelData.SimWideTotalPrims = landData.SimwidePrims; - updatePacket.ParcelData.SnapSelection = snap_selection; - updatePacket.ParcelData.SnapshotID = landData.SnapshotID; - updatePacket.ParcelData.Status = (byte)landData.Status; - updatePacket.ParcelData.TotalPrims = landData.OwnerPrims + landData.GroupPrims + landData.OtherPrims + + updateMessage.SimWideTotalPrims = landData.SimwidePrims; + updateMessage.SnapSelection = snap_selection; + updateMessage.SnapshotID = landData.SnapshotID; + updateMessage.Status = (ParcelStatus) landData.Status; + updateMessage.TotalPrims = landData.OwnerPrims + landData.GroupPrims + landData.OtherPrims + landData.SelectedPrims; - updatePacket.ParcelData.UserLocation = landData.UserLocation; - updatePacket.ParcelData.UserLookAt = landData.UserLookAt; - updatePacket.Header.Zerocoded = true; + updateMessage.UserLocation = landData.UserLocation; + updateMessage.UserLookAt = landData.UserLookAt; + + updateMessage.MediaType = landData.MediaType; + updateMessage.MediaDesc = landData.MediaDescription; + updateMessage.MediaWidth = landData.MediaWidth; + updateMessage.MediaHeight = landData.MediaHeight; + updateMessage.MediaLoop = landData.MediaLoop; + updateMessage.ObscureMusic = landData.ObscureMusic; + updateMessage.ObscureMedia = landData.ObscureMedia; try { IEventQueue eq = Scene.RequestModuleInterface(); if (eq != null) { - eq.ParcelProperties(updatePacket, this.AgentId); - } + eq.ParcelProperties(updateMessage, this.AgentId); + } else { + m_log.Warn("No EQ Interface when sending parcel data."); + } } catch (Exception ex) { m_log.Error("Unable to send parcel data via eventqueue - exception: " + ex.ToString()); - m_log.Warn("sending parcel data via UDP"); - OutPacket(updatePacket, ThrottleOutPacketType.Task); } } @@ -8993,7 +9008,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerGodKickUser != null) { handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, - gkupack.UserInfo.AgentID, (uint)0, gkupack.UserInfo.Reason); + gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason); } } else diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 74784ae63e..38152ccbb5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -471,12 +471,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments SceneObjectSerializer.ToOriginalXmlFormat(group); group.DetachToInventoryPrep(); m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); - m_scene.UpdateKnownItem(remoteClient, group,group.GetFromItemID(), group.OwnerID); + UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); m_scene.DeleteSceneObject(group, false); return; } } } } + + public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos) + { + // If this is an attachment, then we need to save the modified + // object back into the avatar's inventory. First we save the + // attachment point information, then we update the relative + // positioning (which caused this method to get driven in the + // first place. Then we have to mark the object as NOT an + // attachment. This is necessary in order to correctly save + // and retrieve GroupPosition information for the attachment. + // Then we save the asset back into the appropriate inventory + // entry. Finally, we restore the object's attachment status. + byte attachmentPoint = sog.GetAttachmentPoint(); + sog.UpdateGroupPosition(pos); + sog.RootPart.IsAttachment = false; + sog.AbsolutePosition = sog.RootPart.AttachedPos; + UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID); + sog.SetAttachmentPoint(attachmentPoint); + } + + /// + /// Update the attachment asset for the new sog details if they have changed. + /// + /// + /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, + /// these details are not stored on the region. + /// + /// + /// + /// + /// + protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) + { + if (grp != null) + { + if (!grp.HasGroupChanged) + { + m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); + return; + } + + m_log.DebugFormat( + "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", + grp.UUID, grp.GetAttachmentPoint()); + + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); + + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); + item = m_scene.InventoryService.GetItem(item); + + if (item != null) + { + AssetBase asset = m_scene.CreateAsset( + grp.GetPartName(grp.LocalId), + grp.GetPartDescription(grp.LocalId), + (sbyte)AssetType.Object, + Utils.StringToBytes(sceneObjectXml), + remoteClient.AgentId); + m_scene.AssetService.Store(asset); + + item.AssetID = asset.FullID; + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + item.InvType = (int)InventoryType.Object; + + m_scene.InventoryService.UpdateItem(item); + + // this gets called when the agent logs off! + if (remoteClient != null) + remoteClient.SendInventoryItemCreateUpdate(item, 0); + } + } + } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 7683288b62..22c84e947c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -261,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver while (archivePath.Length > 0) { - m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); +// m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); if (resolvedFolders.ContainsKey(archivePath)) { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index 84afb40b8c..8343091773 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -41,7 +41,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// public static class InventoryArchiveUtils { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings public static readonly char ESCAPE_CHARACTER = '\\'; @@ -120,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver foundFolders.Add(startFolder); return foundFolders; } + + // If the path isn't just / then trim any starting extraneous slashes + path = path.TrimStart(new char[] { PATH_DELIMITER }); + +// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Adjusted path in FindFolderByPath() is [{0}]", path); string[] components = SplitEscapedPath(path); components[0] = UnescapePath(components[0]); @@ -199,6 +204,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public static InventoryItemBase FindItemByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) { + // If the path isn't just / then trim any starting extraneous slashes + path = path.TrimStart(new char[] { PATH_DELIMITER }); + string[] components = SplitEscapedPath(path); components[0] = UnescapePath(components[0]); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 25a78ff618..9908018d25 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -221,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver InventoryItemBase inventoryItem = null; InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); - bool foundStar = false; + bool saveFolderContentsOnly = false; // Eliminate double slashes and any leading / on the path. string[] components @@ -234,7 +234,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // folder itself. This may get more sophisicated later on if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) { - foundStar = true; + saveFolderContentsOnly = true; maxComponentIndex--; } @@ -281,10 +281,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { m_log.DebugFormat( "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", - inventoryFolder.Name, inventoryFolder.ID, m_invPath); + inventoryFolder.Name, + inventoryFolder.ID, + m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath ); //recurse through all dirs getting dirs and files - SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); + SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly); } else if (inventoryItem != null) { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 3fb2c8cbac..0218f86178 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -55,12 +55,58 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { protected ManualResetEvent mre = new ManualResetEvent(false); + /// + /// Stream of data representing a common IAR that can be reused in load tests. + /// + protected MemoryStream m_iarStream; + + protected UserAccount m_ua1 + = new UserAccount { + PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"), + FirstName = "Mr", + LastName = "Tiddles" }; + protected UserAccount m_ua2 + = new UserAccount { + PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"), + FirstName = "Lord", + LastName = "Lucan" }; + string m_item1Name = "b.lsl"; + private void SaveCompleted( Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, Exception reportedException) { mre.Set(); } + + [SetUp] + public void Init() + { + ConstructDefaultIarForTestLoad(); + } + + protected void ConstructDefaultIarForTestLoad() + { + string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(m_item1Name, UUID.Random()); + + MemoryStream archiveWriteStream = new MemoryStream(); + TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); + + InventoryItemBase item1 = new InventoryItemBase(); + item1.Name = m_item1Name; + item1.AssetID = UUID.Random(); + item1.GroupID = UUID.Random(); + item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName); + //item1.CreatorId = userUuid.ToString(); + //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; + item1.Owner = UUID.Zero; + + string item1FileName + = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); + tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); + tar.Close(); + m_iarStream = new MemoryStream(archiveWriteStream.ToArray()); + } /// /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive @@ -122,6 +168,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests MemoryStream archiveWriteStream = new MemoryStream(); archiverModule.OnInventoryArchiveSaved += SaveCompleted; + // Test saving a particular path mre.Reset(); archiverModule.ArchiveInventory( Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); @@ -148,7 +195,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests while (tar.ReadEntry(out filePath, out tarEntryType) != null) { - Console.WriteLine("Got {0}", filePath); +// Console.WriteLine("Got {0}", filePath); // if (ArchiveConstants.CONTROL_FILE_PATH == filePath) // { @@ -296,6 +343,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // TODO: Test presence of more files and contents of files. } + /// + /// Test that things work when the load path specified starts with a slash + /// + [Test] + public void TestLoadIarPathStartsWithSlash() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + SerialiserModule serialiserModule = new SerialiserModule(); + InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); + Scene scene = SceneSetupHelpers.SetupScene("inventory"); + SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + + UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "password"); + archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/Objects", "password", m_iarStream); + + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath( + scene.InventoryService, m_ua1.PrincipalID, "/Objects/" + m_item1Name); + + Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()"); + } + /// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where /// an account exists with the creator name. @@ -308,34 +379,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); //log4net.Config.XmlConfigurator.Configure(); - string userFirstName = "Mr"; - string userLastName = "Tiddles"; - UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000555"); - string userItemCreatorFirstName = "Lord"; - string userItemCreatorLastName = "Lucan"; - UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); - - string item1Name = "b.lsl"; - string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random()); - - MemoryStream archiveWriteStream = new MemoryStream(); - TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); - - InventoryItemBase item1 = new InventoryItemBase(); - item1.Name = item1Name; - item1.AssetID = UUID.Random(); - item1.GroupID = UUID.Random(); - item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName); - //item1.CreatorId = userUuid.ToString(); - //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; - item1.Owner = UUID.Zero; - - string item1FileName - = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); - tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); - tar.Close(); - - MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); SerialiserModule serialiserModule = new SerialiserModule(); InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); @@ -344,15 +387,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - UserProfileTestUtils.CreateUserWithInventory( - scene, userFirstName, userLastName, userUuid, "meowfood"); - UserProfileTestUtils.CreateUserWithInventory( - scene, userItemCreatorFirstName, userItemCreatorLastName, userItemCreatorUuid, "hampshire"); + UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); + UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); - archiverModule.DearchiveInventory(userFirstName, userLastName, "/", "meowfood", archiveReadStream); + archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "meowfood", m_iarStream); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); @@ -362,31 +403,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // foundItem1.CreatorId, Is.EqualTo(item1.CreatorId), // "Loaded item non-uuid creator doesn't match original"); Assert.That( - foundItem1.CreatorId, Is.EqualTo(userItemCreatorUuid.ToString()), + foundItem1.CreatorId, Is.EqualTo(m_ua2.PrincipalID.ToString()), "Loaded item non-uuid creator doesn't match original"); Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid), + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_ua2.PrincipalID), "Loaded item uuid creator doesn't match original"); - Assert.That(foundItem1.Owner, Is.EqualTo(userUuid), + Assert.That(foundItem1.Owner, Is.EqualTo(m_ua1.PrincipalID), "Loaded item owner doesn't match inventory reciever"); // Now try loading to a root child folder - UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xA"); - archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); - archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream); + UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xA"); + MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); + archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xA", "meowfood", archiveReadStream); InventoryItemBase foundItem2 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xA/" + item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xA/" + m_item1Name); Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); // Now try loading to a more deeply nested folder - UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xB/xC"); + UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xB/xC"); archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); - archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream); + archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xB/xC", "meowfood", archiveReadStream); InventoryItemBase foundItem3 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xB/xC/" + item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xB/xC/" + m_item1Name); Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ee07f30178..314e1632a8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -200,6 +200,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID); + // Check that these are not the same coordinates + if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && + finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) + { + // Can't do. Viewer crashes + sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); + return; + } + // // This is it // diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs index 0c6cb1bdfa..35b70de8ab 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs @@ -34,6 +34,7 @@ using System.Threading; using log4net; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.Messages.Linden; using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; using OpenSim.Framework; @@ -137,10 +138,11 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { if (!queues.ContainsKey(agentId)) { + /* m_log.DebugFormat( "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName); - + */ queues[agentId] = new Queue(); } @@ -200,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue private void ClientClosed(UUID AgentID, Scene scene) { - m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); + //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); int count = 0; while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) @@ -284,7 +286,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue // Reuse open queues. The client does! if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) { - m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); + //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; } else @@ -365,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! array.Add(EventQueueHelper.KeepAliveEvent()); - m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName); + //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName); } else { @@ -394,8 +396,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue responsedata["keepalive"] = false; responsedata["reusecontext"] = false; responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); + //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); return responsedata; - //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); } public Hashtable NoEvents(UUID requestID, UUID agentID) @@ -461,7 +463,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! array.Add(EventQueueHelper.KeepAliveEvent()); - m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); + //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); } else { @@ -697,9 +699,9 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); } - public void ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket, UUID avatarID) + public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID) { - OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesPacket); + OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage); Enqueue(item, avatarID); } diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs index e9bcae30cd..6294935215 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs @@ -30,6 +30,7 @@ using System.Net; using OpenMetaverse; using OpenMetaverse.Packets; using OpenMetaverse.StructuredData; +using OpenMetaverse.Messages.Linden; namespace OpenSim.Region.CoreModules.Framework.EventQueue { @@ -309,116 +310,6 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue return chatterBoxSessionAgentListUpdates; } - public static OSD ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket) - { - OSDMap parcelProperties = new OSDMap(); - OSDMap body = new OSDMap(); - - OSDArray ageVerificationBlock = new OSDArray(); - OSDMap ageVerificationMap = new OSDMap(); - ageVerificationMap.Add("RegionDenyAgeUnverified", - OSD.FromBoolean(parcelPropertiesPacket.AgeVerificationBlock.RegionDenyAgeUnverified)); - ageVerificationBlock.Add(ageVerificationMap); - body.Add("AgeVerificationBlock", ageVerificationBlock); - - // LL sims send media info in this event queue message but it's not in the UDP - // packet we construct this event queue message from. This should be refactored in - // other areas of the code so it can all be send in the same message. Until then we will - // still send the media info via UDP - - //OSDArray mediaData = new OSDArray(); - //OSDMap mediaDataMap = new OSDMap(); - //mediaDataMap.Add("MediaDesc", OSD.FromString("")); - //mediaDataMap.Add("MediaHeight", OSD.FromInteger(0)); - //mediaDataMap.Add("MediaLoop", OSD.FromInteger(0)); - //mediaDataMap.Add("MediaType", OSD.FromString("type/type")); - //mediaDataMap.Add("MediaWidth", OSD.FromInteger(0)); - //mediaDataMap.Add("ObscureMedia", OSD.FromInteger(0)); - //mediaDataMap.Add("ObscureMusic", OSD.FromInteger(0)); - //mediaData.Add(mediaDataMap); - //body.Add("MediaData", mediaData); - - OSDArray parcelData = new OSDArray(); - OSDMap parcelDataMap = new OSDMap(); - OSDArray AABBMax = new OSDArray(3); - AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.X)); - AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.Y)); - AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.Z)); - parcelDataMap.Add("AABBMax", AABBMax); - - OSDArray AABBMin = new OSDArray(3); - AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.X)); - AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.Y)); - AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.Z)); - parcelDataMap.Add("AABBMin", AABBMin); - - parcelDataMap.Add("Area", OSD.FromInteger(parcelPropertiesPacket.ParcelData.Area)); - parcelDataMap.Add("AuctionID", OSD.FromBinary(uintToByteArray(parcelPropertiesPacket.ParcelData.AuctionID))); - parcelDataMap.Add("AuthBuyerID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.AuthBuyerID)); - parcelDataMap.Add("Bitmap", OSD.FromBinary(parcelPropertiesPacket.ParcelData.Bitmap)); - parcelDataMap.Add("Category", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.Category)); - parcelDataMap.Add("ClaimDate", OSD.FromInteger(parcelPropertiesPacket.ParcelData.ClaimDate)); - parcelDataMap.Add("ClaimPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.ClaimPrice)); - parcelDataMap.Add("Desc", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.Desc))); - parcelDataMap.Add("GroupID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.GroupID)); - parcelDataMap.Add("GroupPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.GroupPrims)); - parcelDataMap.Add("IsGroupOwned", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.IsGroupOwned)); - parcelDataMap.Add("LandingType", OSD.FromInteger(parcelPropertiesPacket.ParcelData.LandingType)); - parcelDataMap.Add("LocalID", OSD.FromInteger(parcelPropertiesPacket.ParcelData.LocalID)); - parcelDataMap.Add("MaxPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.MaxPrims)); - parcelDataMap.Add("MediaAutoScale", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.MediaAutoScale)); - parcelDataMap.Add("MediaID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.MediaID)); - parcelDataMap.Add("MediaURL", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.MediaURL))); - parcelDataMap.Add("MusicURL", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.MusicURL))); - parcelDataMap.Add("Name", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.Name))); - parcelDataMap.Add("OtherCleanTime", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherCleanTime)); - parcelDataMap.Add("OtherCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherCount)); - parcelDataMap.Add("OtherPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherPrims)); - parcelDataMap.Add("OwnerID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.OwnerID)); - parcelDataMap.Add("OwnerPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OwnerPrims)); - parcelDataMap.Add("ParcelFlags", OSD.FromBinary(uintToByteArray(parcelPropertiesPacket.ParcelData.ParcelFlags))); - parcelDataMap.Add("ParcelPrimBonus", OSD.FromReal(parcelPropertiesPacket.ParcelData.ParcelPrimBonus)); - parcelDataMap.Add("PassHours", OSD.FromReal(parcelPropertiesPacket.ParcelData.PassHours)); - parcelDataMap.Add("PassPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.PassPrice)); - parcelDataMap.Add("PublicCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.PublicCount)); - parcelDataMap.Add("RegionDenyAnonymous", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyAnonymous)); - parcelDataMap.Add("RegionDenyIdentified", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyIdentified)); - parcelDataMap.Add("RegionDenyTransacted", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyTransacted)); - - parcelDataMap.Add("RegionPushOverride", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionPushOverride)); - parcelDataMap.Add("RentPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.RentPrice)); - parcelDataMap.Add("RequestResult", OSD.FromInteger(parcelPropertiesPacket.ParcelData.RequestResult)); - parcelDataMap.Add("SalePrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SalePrice)); - parcelDataMap.Add("SelectedPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SelectedPrims)); - parcelDataMap.Add("SelfCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SelfCount)); - parcelDataMap.Add("SequenceID", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SequenceID)); - parcelDataMap.Add("SimWideMaxPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SimWideMaxPrims)); - parcelDataMap.Add("SimWideTotalPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SimWideTotalPrims)); - parcelDataMap.Add("SnapSelection", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.SnapSelection)); - parcelDataMap.Add("SnapshotID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.SnapshotID)); - parcelDataMap.Add("Status", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.Status)); - parcelDataMap.Add("TotalPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.TotalPrims)); - - OSDArray UserLocation = new OSDArray(3); - UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.X)); - UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.Y)); - UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.Z)); - parcelDataMap.Add("UserLocation", UserLocation); - - OSDArray UserLookAt = new OSDArray(3); - UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.X)); - UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.Y)); - UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.Z)); - parcelDataMap.Add("UserLookAt", UserLookAt); - - parcelData.Add(parcelDataMap); - body.Add("ParcelData", parcelData); - parcelProperties.Add("body", body); - parcelProperties.Add("message", OSD.FromString("ParcelProperties")); - - return parcelProperties; - } - public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket) { OSDMap groupUpdate = new OSDMap(); @@ -495,5 +386,14 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue return placesReply; } + public static OSD ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage) + { + OSDMap message = new OSDMap(); + message.Add("message", OSD.FromString("ParcelProperties")); + OSD message_body = parcelPropertiesMessage.Serialize(); + message.Add("body", message_body); + return message; + } + } } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index a402f4f48b..e51f118442 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -243,9 +243,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver // to the same scene (when this is possible). sceneObject.ResetIDs(); + List partList = null; lock (sceneObject.Children) + partList = new List(sceneObject.Children.Values); + + foreach (SceneObjectPart part in partList) { - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (!ResolveUserUuid(part.CreatorID)) + part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; + + if (!ResolveUserUuid(part.OwnerID)) + part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; + + if (!ResolveUserUuid(part.LastOwnerID)) + part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; + + // And zap any troublesome sit target information + part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); + part.SitTargetPosition = new Vector3(0, 0, 0); + + // Fix ownership/creator of inventory items + // Not doing so results in inventory items + // being no copy/no mod for everyone + lock (part.TaskInventory) { if (!ResolveUserUuid(part.CreatorID)) part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d00cb0774e..776fe302a5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -33,6 +33,8 @@ using System.Reflection; using log4net; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenMetaverse.Messages.Linden; using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Servers; @@ -1078,7 +1080,6 @@ namespace OpenSim.Region.CoreModules.World.Land { for (int y = 0; y < inc_y; y++) { - ILandObject currentParcel = GetLandObject(start_x + x, start_y + y); if (currentParcel != null) @@ -1378,8 +1379,68 @@ namespace OpenSim.Region.CoreModules.World.Land { return RemoteParcelRequest(request, path, param, agentID, caps); })); + UUID parcelCapID = UUID.Random(); + caps.RegisterHandler("ParcelPropertiesUpdate", + new RestStreamHandler("POST", "/CAPS/" + parcelCapID, + delegate(string request, string path, string param, + OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return ProcessPropertiesUpdate(request, path, param, agentID, caps); + })); } + private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) + { + IClientAPI client; + if ( ! m_scene.TryGetClient(agentID, out client) ) { + m_log.WarnFormat("[LAND] unable to retrieve IClientAPI for {0}", agentID.ToString() ); + return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); + } + + ParcelPropertiesUpdateMessage properties = new ParcelPropertiesUpdateMessage(); + OpenMetaverse.StructuredData.OSDMap args = (OpenMetaverse.StructuredData.OSDMap) OSDParser.DeserializeLLSDXml(request); + properties.Deserialize(args); + + LandUpdateArgs land_update = new LandUpdateArgs(); + int parcelID = properties.LocalID; + land_update.AuthBuyerID = properties.AuthBuyerID; + land_update.Category = properties.Category; + land_update.Desc = properties.Desc; + land_update.GroupID = properties.GroupID; + land_update.LandingType = (byte) properties.Landing; + land_update.MediaAutoScale = (byte) Convert.ToInt32(properties.MediaAutoScale); + land_update.MediaID = properties.MediaID; + land_update.MediaURL = properties.MediaURL; + land_update.MusicURL = properties.MusicURL; + land_update.Name = properties.Name; + land_update.ParcelFlags = (uint) properties.ParcelFlags; + land_update.PassHours = (int) properties.PassHours; + land_update.PassPrice = (int) properties.PassPrice; + land_update.SalePrice = (int) properties.SalePrice; + land_update.SnapshotID = properties.SnapshotID; + land_update.UserLocation = properties.UserLocation; + land_update.UserLookAt = properties.UserLookAt; + land_update.MediaDescription = properties.MediaDesc; + land_update.MediaType = properties.MediaType; + land_update.MediaWidth = properties.MediaWidth; + land_update.MediaHeight = properties.MediaHeight; + land_update.MediaLoop = properties.MediaLoop; + land_update.ObscureMusic = properties.ObscureMusic; + land_update.ObscureMedia = properties.ObscureMedia; + + ILandObject land; + lock (m_landList) + { + m_landList.TryGetValue(parcelID, out land); + } + + if (land != null) { + land.UpdateLandProperties(land_update, client); + } else { + m_log.WarnFormat("[LAND] unable to find parcelID {0}", parcelID); + } + return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); + } // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the // "real" parcelID, because we wouldn't be able to map that to the region the parcel belongs to. // So, we create a "fake" parcelID by using the regionHandle (64 bit), and the local (integer) x diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 9e9934e09e..1b2cabbbee 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -229,6 +229,13 @@ namespace OpenSim.Region.CoreModules.World.Land newData.SnapshotID = args.SnapshotID; newData.UserLocation = args.UserLocation; newData.UserLookAt = args.UserLookAt; + newData.MediaType = args.MediaType; + newData.MediaDescription = args.MediaDescription; + newData.MediaWidth = args.MediaWidth; + newData.MediaHeight = args.MediaHeight; + newData.MediaLoop = args.MediaLoop; + newData.ObscureMusic = args.ObscureMusic; + newData.ObscureMedia = args.ObscureMedia; m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index 2f70c0a267..57eff8a0b3 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs @@ -228,280 +228,281 @@ namespace OpenSim.Region.CoreModules.World.WorldMap SceneObjectGroup mapdot = (SceneObjectGroup)obj; Color mapdotspot = Color.Gray; // Default color when prim color is white - // Loop over prim in group + // Loop over prim in group + List partList = null; lock (mapdot.Children) + partList = new List(mapdot.Children.Values); + + foreach (SceneObjectPart part in partList) { - foreach (SceneObjectPart part in mapdot.Children.Values) + if (part == null) + continue; + + // Draw if the object is at least 1 meter wide in any direction + if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) { - if (part == null) - continue; - - // Draw if the object is at least 1 meter wide in any direction - if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) + // Try to get the RGBA of the default texture entry.. + // + try { - // Try to get the RGBA of the default texture entry.. - // - try + // get the null checks out of the way + // skip the ones that break + if (part == null) + continue; + + if (part.Shape == null) + continue; + + if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) + continue; // eliminates trees from this since we don't really have a good tree representation + // if you want tree blocks on the map comment the above line and uncomment the below line + //mapdotspot = Color.PaleGreen; + + Primitive.TextureEntry textureEntry = part.Shape.Textures; + + if (textureEntry == null || textureEntry.DefaultTexture == null) + continue; + + Color4 texcolor = textureEntry.DefaultTexture.RGBA; + + // Not sure why some of these are null, oh well. + + int colorr = 255 - (int)(texcolor.R * 255f); + int colorg = 255 - (int)(texcolor.G * 255f); + int colorb = 255 - (int)(texcolor.B * 255f); + + if (!(colorr == 255 && colorg == 255 && colorb == 255)) { - // get the null checks out of the way - // skip the ones that break - if (part == null) - continue; - - if (part.Shape == null) - continue; - - if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) - continue; // eliminates trees from this since we don't really have a good tree representation - // if you want tree blocks on the map comment the above line and uncomment the below line - //mapdotspot = Color.PaleGreen; - - Primitive.TextureEntry textureEntry = part.Shape.Textures; - - if (textureEntry == null || textureEntry.DefaultTexture == null) - continue; - - Color4 texcolor = textureEntry.DefaultTexture.RGBA; - - // Not sure why some of these are null, oh well. - - int colorr = 255 - (int)(texcolor.R * 255f); - int colorg = 255 - (int)(texcolor.G * 255f); - int colorb = 255 - (int)(texcolor.B * 255f); - - if (!(colorr == 255 && colorg == 255 && colorb == 255)) + //Try to set the map spot color + try + { + // If the color gets goofy somehow, skip it *shakes fist at Color4 + mapdotspot = Color.FromArgb(colorr, colorg, colorb); + } + catch (ArgumentException) { - //Try to set the map spot color - try - { - // If the color gets goofy somehow, skip it *shakes fist at Color4 - mapdotspot = Color.FromArgb(colorr, colorg, colorb); - } - catch (ArgumentException) - { - } } } - catch (IndexOutOfRangeException) - { - // Windows Array - } - catch (ArgumentOutOfRangeException) - { - // Mono Array - } - - Vector3 pos = part.GetWorldPosition(); - - // skip prim outside of retion - if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) + } + catch (IndexOutOfRangeException) + { + // Windows Array + } + catch (ArgumentOutOfRangeException) + { + // Mono Array + } + + Vector3 pos = part.GetWorldPosition(); + + // skip prim outside of retion + if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) + continue; + + // skip prim in non-finite position + if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || + Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) + continue; + + // Figure out if object is under 256m above the height of the terrain + bool isBelow256AboveTerrain = false; + + try + { + isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); + } + catch (Exception) + { + } + + if (isBelow256AboveTerrain) + { + // Translate scale by rotation so scale is represented properly when object is rotated + Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); + Vector3 scale = new Vector3(); + Vector3 tScale = new Vector3(); + Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); + + Quaternion llrot = part.GetWorldRotation(); + Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); + scale = lscale * rot; + + // negative scales don't work in this situation + scale.X = Math.Abs(scale.X); + scale.Y = Math.Abs(scale.Y); + scale.Z = Math.Abs(scale.Z); + + // This scaling isn't very accurate and doesn't take into account the face rotation :P + int mapdrawstartX = (int)(pos.X - scale.X); + int mapdrawstartY = (int)(pos.Y - scale.Y); + int mapdrawendX = (int)(pos.X + scale.X); + int mapdrawendY = (int)(pos.Y + scale.Y); + + // If object is beyond the edge of the map, don't draw it to avoid errors + if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) + || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 + || mapdrawendY > ((int)Constants.RegionSize - 1)) continue; - - // skip prim in non-finite position - if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || - Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) - continue; - - // Figure out if object is under 256m above the height of the terrain - bool isBelow256AboveTerrain = false; - - try + +#region obb face reconstruction part duex + Vector3[] vertexes = new Vector3[8]; + + // float[] distance = new float[6]; + Vector3[] FaceA = new Vector3[6]; // vertex A for Facei + Vector3[] FaceB = new Vector3[6]; // vertex B for Facei + Vector3[] FaceC = new Vector3[6]; // vertex C for Facei + Vector3[] FaceD = new Vector3[6]; // vertex D for Facei + + tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); + scale = ((tScale * rot)); + vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + // vertexes[0].x = pos.X + vertexes[0].x; + //vertexes[0].y = pos.Y + vertexes[0].y; + //vertexes[0].z = pos.Z + vertexes[0].z; + + FaceA[0] = vertexes[0]; + FaceB[3] = vertexes[0]; + FaceA[4] = vertexes[0]; + + tScale = lscale; + scale = ((tScale * rot)); + vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + // vertexes[1].x = pos.X + vertexes[1].x; + // vertexes[1].y = pos.Y + vertexes[1].y; + //vertexes[1].z = pos.Z + vertexes[1].z; + + FaceB[0] = vertexes[1]; + FaceA[1] = vertexes[1]; + FaceC[4] = vertexes[1]; + + tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); + scale = ((tScale * rot)); + + vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + //vertexes[2].x = pos.X + vertexes[2].x; + //vertexes[2].y = pos.Y + vertexes[2].y; + //vertexes[2].z = pos.Z + vertexes[2].z; + + FaceC[0] = vertexes[2]; + FaceD[3] = vertexes[2]; + FaceC[5] = vertexes[2]; + + tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); + scale = ((tScale * rot)); + vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + //vertexes[3].x = pos.X + vertexes[3].x; + // vertexes[3].y = pos.Y + vertexes[3].y; + // vertexes[3].z = pos.Z + vertexes[3].z; + + FaceD[0] = vertexes[3]; + FaceC[1] = vertexes[3]; + FaceA[5] = vertexes[3]; + + tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); + scale = ((tScale * rot)); + vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + // vertexes[4].x = pos.X + vertexes[4].x; + // vertexes[4].y = pos.Y + vertexes[4].y; + // vertexes[4].z = pos.Z + vertexes[4].z; + + FaceB[1] = vertexes[4]; + FaceA[2] = vertexes[4]; + FaceD[4] = vertexes[4]; + + tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); + scale = ((tScale * rot)); + vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + // vertexes[5].x = pos.X + vertexes[5].x; + // vertexes[5].y = pos.Y + vertexes[5].y; + // vertexes[5].z = pos.Z + vertexes[5].z; + + FaceD[1] = vertexes[5]; + FaceC[2] = vertexes[5]; + FaceB[5] = vertexes[5]; + + tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); + scale = ((tScale * rot)); + vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + // vertexes[6].x = pos.X + vertexes[6].x; + // vertexes[6].y = pos.Y + vertexes[6].y; + // vertexes[6].z = pos.Z + vertexes[6].z; + + FaceB[2] = vertexes[6]; + FaceA[3] = vertexes[6]; + FaceB[4] = vertexes[6]; + + tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); + scale = ((tScale * rot)); + vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); + + // vertexes[7].x = pos.X + vertexes[7].x; + // vertexes[7].y = pos.Y + vertexes[7].y; + // vertexes[7].z = pos.Z + vertexes[7].z; + + FaceD[2] = vertexes[7]; + FaceC[3] = vertexes[7]; + FaceD[5] = vertexes[7]; +#endregion + + //int wy = 0; + + //bool breakYN = false; // If we run into an error drawing, break out of the + // loop so we don't lag to death on error handling + DrawStruct ds = new DrawStruct(); + ds.brush = new SolidBrush(mapdotspot); + //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); + + ds.trns = new face[FaceA.Length]; + + for (int i = 0; i < FaceA.Length; i++) { - isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); + Point[] working = new Point[5]; + working[0] = project(FaceA[i], axPos); + working[1] = project(FaceB[i], axPos); + working[2] = project(FaceD[i], axPos); + working[3] = project(FaceC[i], axPos); + working[4] = project(FaceA[i], axPos); + + face workingface = new face(); + workingface.pts = working; + + ds.trns[i] = workingface; } - catch (Exception) - { - } - - if (isBelow256AboveTerrain) - { - // Translate scale by rotation so scale is represented properly when object is rotated - Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); - Vector3 scale = new Vector3(); - Vector3 tScale = new Vector3(); - Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); - - Quaternion llrot = part.GetWorldRotation(); - Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); - scale = lscale * rot; - - // negative scales don't work in this situation - scale.X = Math.Abs(scale.X); - scale.Y = Math.Abs(scale.Y); - scale.Z = Math.Abs(scale.Z); - - // This scaling isn't very accurate and doesn't take into account the face rotation :P - int mapdrawstartX = (int)(pos.X - scale.X); - int mapdrawstartY = (int)(pos.Y - scale.Y); - int mapdrawendX = (int)(pos.X + scale.X); - int mapdrawendY = (int)(pos.Y + scale.Y); - - // If object is beyond the edge of the map, don't draw it to avoid errors - if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) - || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 - || mapdrawendY > ((int)Constants.RegionSize - 1)) - continue; - - #region obb face reconstruction part duex - Vector3[] vertexes = new Vector3[8]; - - // float[] distance = new float[6]; - Vector3[] FaceA = new Vector3[6]; // vertex A for Facei - Vector3[] FaceB = new Vector3[6]; // vertex B for Facei - Vector3[] FaceC = new Vector3[6]; // vertex C for Facei - Vector3[] FaceD = new Vector3[6]; // vertex D for Facei - - tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); - scale = ((tScale * rot)); - vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - // vertexes[0].x = pos.X + vertexes[0].x; - //vertexes[0].y = pos.Y + vertexes[0].y; - //vertexes[0].z = pos.Z + vertexes[0].z; - - FaceA[0] = vertexes[0]; - FaceB[3] = vertexes[0]; - FaceA[4] = vertexes[0]; - - tScale = lscale; - scale = ((tScale * rot)); - vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - // vertexes[1].x = pos.X + vertexes[1].x; - // vertexes[1].y = pos.Y + vertexes[1].y; - //vertexes[1].z = pos.Z + vertexes[1].z; - - FaceB[0] = vertexes[1]; - FaceA[1] = vertexes[1]; - FaceC[4] = vertexes[1]; - - tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); - scale = ((tScale * rot)); - - vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - //vertexes[2].x = pos.X + vertexes[2].x; - //vertexes[2].y = pos.Y + vertexes[2].y; - //vertexes[2].z = pos.Z + vertexes[2].z; - - FaceC[0] = vertexes[2]; - FaceD[3] = vertexes[2]; - FaceC[5] = vertexes[2]; - - tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); - scale = ((tScale * rot)); - vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - //vertexes[3].x = pos.X + vertexes[3].x; - // vertexes[3].y = pos.Y + vertexes[3].y; - // vertexes[3].z = pos.Z + vertexes[3].z; - - FaceD[0] = vertexes[3]; - FaceC[1] = vertexes[3]; - FaceA[5] = vertexes[3]; - - tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); - scale = ((tScale * rot)); - vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - // vertexes[4].x = pos.X + vertexes[4].x; - // vertexes[4].y = pos.Y + vertexes[4].y; - // vertexes[4].z = pos.Z + vertexes[4].z; - - FaceB[1] = vertexes[4]; - FaceA[2] = vertexes[4]; - FaceD[4] = vertexes[4]; - - tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); - scale = ((tScale * rot)); - vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - // vertexes[5].x = pos.X + vertexes[5].x; - // vertexes[5].y = pos.Y + vertexes[5].y; - // vertexes[5].z = pos.Z + vertexes[5].z; - - FaceD[1] = vertexes[5]; - FaceC[2] = vertexes[5]; - FaceB[5] = vertexes[5]; - - tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); - scale = ((tScale * rot)); - vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - // vertexes[6].x = pos.X + vertexes[6].x; - // vertexes[6].y = pos.Y + vertexes[6].y; - // vertexes[6].z = pos.Z + vertexes[6].z; - - FaceB[2] = vertexes[6]; - FaceA[3] = vertexes[6]; - FaceB[4] = vertexes[6]; - - tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); - scale = ((tScale * rot)); - vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); - - // vertexes[7].x = pos.X + vertexes[7].x; - // vertexes[7].y = pos.Y + vertexes[7].y; - // vertexes[7].z = pos.Z + vertexes[7].z; - - FaceD[2] = vertexes[7]; - FaceC[3] = vertexes[7]; - FaceD[5] = vertexes[7]; - #endregion - - //int wy = 0; - - //bool breakYN = false; // If we run into an error drawing, break out of the - // loop so we don't lag to death on error handling - DrawStruct ds = new DrawStruct(); - ds.brush = new SolidBrush(mapdotspot); - //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); - - ds.trns = new face[FaceA.Length]; - - for (int i = 0; i < FaceA.Length; i++) - { - Point[] working = new Point[5]; - working[0] = project(FaceA[i], axPos); - working[1] = project(FaceB[i], axPos); - working[2] = project(FaceD[i], axPos); - working[3] = project(FaceC[i], axPos); - working[4] = project(FaceA[i], axPos); - - face workingface = new face(); - workingface.pts = working; - - ds.trns[i] = workingface; - } - - z_sort.Add(part.LocalId, ds); - z_localIDs.Add(part.LocalId); - z_sortheights.Add(pos.Z); - - //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) + + z_sort.Add(part.LocalId, ds); + z_localIDs.Add(part.LocalId); + z_sortheights.Add(pos.Z); + + //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) + //{ + //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) //{ - //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) + //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); + //try //{ - //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); - //try - //{ - // Remember, flip the y! - // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); - //} - //catch (ArgumentException) - //{ - // breakYN = true; - //} - - //if (breakYN) - // break; + // Remember, flip the y! + // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); //} - + //catch (ArgumentException) + //{ + // breakYN = true; + //} + //if (breakYN) // break; //} - } // Object is within 256m Z of terrain - } // object is at least a meter wide - } // mapdot.Children lock + + //if (breakYN) + // break; + //} + } // Object is within 256m Z of terrain + } // object is at least a meter wide } // loop over group children } // entitybase is sceneobject group } // foreach loop over entities diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index c489972e25..3c39f9e9cf 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -142,9 +142,18 @@ namespace OpenSim.Region.DataSnapshot.Providers node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString(); xmlobject.AppendChild(node); - node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); - node.InnerText = land.LandData.GlobalID.ToString(); - xmlobject.AppendChild(node); + if (land != null && land.LandData != null) + { + node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); + node.InnerText = land.LandData.GlobalID.ToString(); + xmlobject.AppendChild(node); + } + else + { + // Something is wrong with this object. Let's not list it. + m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName); + continue; + } node = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); Vector3 loc = obj.AbsolutePosition; diff --git a/OpenSim/Region/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/DataSnapshot/SnapshotStore.cs index 70cb2053c9..aa3d2ff34c 100644 --- a/OpenSim/Region/DataSnapshot/SnapshotStore.cs +++ b/OpenSim/Region/DataSnapshot/SnapshotStore.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using log4net; using OpenSim.Region.DataSnapshot.Interfaces; @@ -98,13 +99,21 @@ namespace OpenSim.Region.DataSnapshot { String path = DataFileNameFragment(provider.GetParentScene, provider.Name); - using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) + try { - snapXWriter.Formatting = Formatting.Indented; - snapXWriter.WriteStartDocument(); - data.WriteTo(snapXWriter); - snapXWriter.WriteEndDocument(); + using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) + { + snapXWriter.Formatting = Formatting.Indented; + snapXWriter.WriteStartDocument(); + data.WriteTo(snapXWriter); + snapXWriter.WriteEndDocument(); + } } + catch (Exception e) + { + m_log.WarnFormat("[DATASNAPSHOT]: Exception on writing to file {0}: {1}", path, e.Message); + } + } //mark provider as not stale, parent scene as stale @@ -185,12 +194,19 @@ namespace OpenSim.Region.DataSnapshot //save snapshot String path = DataFileNameScene(scene); - using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) + try { - snapXWriter.Formatting = Formatting.Indented; - snapXWriter.WriteStartDocument(); - regionElement.WriteTo(snapXWriter); - snapXWriter.WriteEndDocument(); + using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) + { + snapXWriter.Formatting = Formatting.Indented; + snapXWriter.WriteStartDocument(); + regionElement.WriteTo(snapXWriter); + snapXWriter.WriteEndDocument(); + } + } + catch (Exception e) + { + m_log.WarnFormat("[DATASNAPSHOT]: Exception on writing to file {0}: {1}", path, e.Message); } m_scenes[scene] = false; @@ -206,15 +222,23 @@ namespace OpenSim.Region.DataSnapshot #region Helpers private string DataFileNameFragment(Scene scene, String fragmentName) { - return Path.Combine(m_directory, Path.ChangeExtension(scene.RegionInfo.RegionName + "_" + fragmentName, "xml")); + return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName + "_" + fragmentName), "xml")); } private string DataFileNameScene(Scene scene) { - return Path.Combine(m_directory, Path.ChangeExtension(scene.RegionInfo.RegionName, "xml")); + return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName), "xml")); //return (m_snapsDir + Path.DirectorySeparatorChar + scene.RegionInfo.RegionName + ".xml"); } + private static string Sanitize(string name) + { + string invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars())); + string invalidReStr = string.Format(@"[{0}]", invalidChars); + string newname = Regex.Replace(name, invalidReStr, "_"); + return newname.Replace('.', '_'); + } + private XmlNode MakeRegionNode(Scene scene, XmlDocument basedoc) { XmlNode docElement = basedoc.CreateNode(XmlNodeType.Element, "region", ""); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 9fe6d96555..59c035ffd7 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -136,5 +136,13 @@ namespace OpenSim.Region.Framework.Interfaces /// A /// void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); + + /// + /// Update the position of an attachment + /// + /// + /// + /// + void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos); } } diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index e093f0aa40..81e4952afe 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -28,6 +28,7 @@ using System.Net; using OpenMetaverse; using OpenMetaverse.Packets; +using OpenMetaverse.Messages.Linden; using OpenMetaverse.StructuredData; namespace OpenSim.Region.Framework.Interfaces @@ -54,7 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, bool isModerator, bool textMute); - void ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket, UUID avatarID); + void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); } } diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 145f9ed086..3a3ec2b1dc 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -31,7 +31,7 @@ namespace OpenSim.Region.Framework.Scenes public class Prioritizer { - private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); /// /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the @@ -75,7 +75,6 @@ namespace OpenSim.Region.Framework.Scenes break; default: throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); - break; } // Adjust priority so that root prims are sent to the viewer first. This is especially important for @@ -122,9 +121,16 @@ namespace OpenSim.Region.Framework.Scenes // Use group position for child prims Vector3 entityPos; if (entity is SceneObjectPart) - entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + { + // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene + // before its scheduled update was triggered + //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition; + } else + { entityPos = entity.AbsolutePosition; + } return Vector3.DistanceSquared(presencePos, entityPos); } @@ -157,7 +163,9 @@ namespace OpenSim.Region.Framework.Scenes } } else + { entityPos = entity.AbsolutePosition; + } if (!presence.IsChildAgent) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 48508f80a8..8760c84d1b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1852,53 +1852,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) - { - SceneObjectGroup objectGroup = grp; - if (objectGroup != null) - { - if (!grp.HasGroupChanged) - { - m_log.InfoFormat("[ATTACHMENT]: Save request for {0} which is unchanged", grp.UUID); - return; - } - - m_log.InfoFormat( - "[ATTACHMENT]: Updating asset for attachment {0}, attachpoint {1}", - grp.UUID, grp.GetAttachmentPoint()); - - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); - - InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); - item = InventoryService.GetItem(item); - - if (item != null) - { - AssetBase asset = CreateAsset( - objectGroup.GetPartName(objectGroup.LocalId), - objectGroup.GetPartDescription(objectGroup.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - remoteClient.AgentId); - AssetService.Store(asset); - - item.AssetID = asset.FullID; - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; - item.InvType = (int)InventoryType.Object; - - InventoryService.UpdateItem(item); - - // this gets called when the agent loggs off! - if (remoteClient != null) - { - remoteClient.SendInventoryItemCreateUpdate(item, 0); - } - } - } - } - public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) { itemID = UUID.Zero; @@ -2104,11 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes sog.SetGroup(groupID, remoteClient); sog.ScheduleGroupForFullUpdate(); + List partList = null; lock (sog.Children) - { - foreach (SceneObjectPart child in sog.Children.Values) - child.Inventory.ChangeInventoryOwner(ownerID); - } + partList = new List(sog.Children.Values); + + foreach (SceneObjectPart child in partList) + child.Inventory.ChangeInventoryOwner(ownerID); } else { @@ -2117,14 +2071,15 @@ namespace OpenSim.Region.Framework.Scenes if (sog.GroupID != groupID) continue; - + + List partList = null; lock (sog.Children) + partList = new List(sog.Children.Values); + + foreach (SceneObjectPart child in partList) { - foreach (SceneObjectPart child in sog.Children.Values) - { - child.LastOwnerID = child.OwnerID; - child.Inventory.ChangeInventoryOwner(groupID); - } + child.LastOwnerID = child.OwnerID; + child.Inventory.ChangeInventoryOwner(groupID); } sog.SetOwnerId(groupID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 9f1575dad1..c511774d69 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -164,16 +164,17 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup sog = ent as SceneObjectGroup; + List partList = null; lock (sog.Children) + partList = new List(sog.Children.Values); + + foreach (SceneObjectPart part in partList) { - foreach (KeyValuePair child in (sog.Children)) + if (part.LocalId == primLocalID) { - if (child.Value.LocalId == primLocalID) - { - child.Value.GetProperties(remoteClient); - foundPrim = true; - break; - } + part.GetProperties(remoteClient); + foundPrim = true; + break; } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ec97d25c30..6a742c1674 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2131,19 +2131,20 @@ namespace OpenSim.Region.Framework.Scenes group.RemoveScriptInstances(true); } + List partList = null; lock (group.Children) + partList = new List(group.Children.Values); + + foreach (SceneObjectPart part in partList) { - foreach (SceneObjectPart part in group.Children.Values) + if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) { - if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) - { - PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? - } - else if (part.PhysActor != null) - { - PhysicsScene.RemovePrim(part.PhysActor); - part.PhysActor = null; - } + PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? + } + else if (part.PhysActor != null) + { + PhysicsScene.RemovePrim(part.PhysActor); + part.PhysActor = null; } } @@ -3720,18 +3721,6 @@ namespace OpenSim.Region.Framework.Scenes return true; } - private ILandObject GetParcelAtPoint(float x, float y) - { - foreach (var parcel in AllParcels()) - { - if (parcel.ContainsPoint((int)x,(int)y)) - { - return parcel; - } - } - return null; - } - /// /// Update an AgentCircuitData object with new information /// diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 59e4037f6e..1293d5d531 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// A user will arrive shortly, set up appropriate credentials so it can connect /// - public event ExpectUserDelegate OnExpectUser; +// public event ExpectUserDelegate OnExpectUser; /// /// A Prim will arrive shortly @@ -80,7 +80,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// A new prim has arrived /// - public event PrimCrossing OnPrimCrossingIntoRegion; +// public event PrimCrossing OnPrimCrossingIntoRegion; ///// ///// A New Region is up and available @@ -90,7 +90,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// We have a child agent for this avatar and we're getting a status update about it /// - public event ChildAgentUpdate OnChildAgentUpdate; +// public event ChildAgentUpdate OnChildAgentUpdate; //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 1d952c495c..b86a56450c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -402,23 +402,22 @@ namespace OpenSim.Region.Framework.Scenes part.Shape.Scale = scale; } } - - sceneObject.AttachToScene(m_parentScene); - - if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); - - Entities.Add(sceneObject); + m_numPrim += sceneObject.Children.Count; - - if (attachToBackup) - sceneObject.AttachToBackup(); } + + sceneObject.AttachToScene(m_parentScene); + + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + + Entities.Add(sceneObject); + + if (attachToBackup) + sceneObject.AttachToBackup(); if (OnObjectCreate != null) - { OnObjectCreate(sceneObject); - } lock (SceneObjectGroupsByFullID) { @@ -426,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in sceneObject.Children.Values) SceneObjectGroupsByFullID[part.UUID] = sceneObject; } + lock (SceneObjectGroupsByLocalID) { SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; @@ -1348,37 +1348,21 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - protected internal void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) + public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); + if (group != null) - { - - // Vector3 oldPos = group.AbsolutePosition; + { if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) { - - // If this is an attachment, then we need to save the modified - // object back into the avatar's inventory. First we save the - // attachment point information, then we update the relative - // positioning (which caused this method to get driven in the - // first place. Then we have to mark the object as NOT an - // attachment. This is necessary in order to correctly save - // and retrieve GroupPosition information for the attachment. - // Then we save the asset back into the appropriate inventory - // entry. Finally, we restore the object's attachment status. - - byte attachmentPoint = group.GetAttachmentPoint(); - group.UpdateGroupPosition(pos); - group.RootPart.IsAttachment = false; - group.AbsolutePosition = group.RootPart.AttachedPos; - m_parentScene.UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); - group.SetAttachmentPoint(attachmentPoint); - + if (m_parentScene.AttachmentsModule != null) + m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos); } else { - if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) + if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) + && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) { group.UpdateGroupPosition(pos); } @@ -1387,14 +1371,19 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Update the texture entry of the given prim. /// + /// + /// A texture entry is an object that contains details of all the textures of the prim's face. In this case, + /// the texture is given in its byte serialized form. + /// /// /// /// protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) { SceneObjectGroup group = GetGroupByPrim(localID); + if (group != null) { if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) @@ -1784,8 +1773,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart newRoot = newSet[0]; newSet.RemoveAt(0); - List linkIDs = new List(); - foreach (SceneObjectPart newChild in newSet) newChild.UpdateFlag = 0; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index e003cf86e0..5a586d401b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -398,6 +398,8 @@ namespace OpenSim.Region.Framework.Scenes /// /// The parts of this scene object group. You must lock this property before using it. + /// If you're doing anything other than reading values, please take a copy of the values rather than locking + /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock /// If you want to know the number of children, consider using the PrimCount property instead /// public Dictionary Children @@ -2306,29 +2308,29 @@ namespace OpenSim.Region.Framework.Scenes // return; lockPartsForRead(true); + + bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); + + if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) { - bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); + m_rootPart.UpdateFlag = 1; + lastPhysGroupPos = AbsolutePosition; + } - if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) - { - m_rootPart.UpdateFlag = 1; - lastPhysGroupPos = AbsolutePosition; - } + if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) + { + m_rootPart.UpdateFlag = 1; + lastPhysGroupRot = GroupRotation; + } - if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) - { - m_rootPart.UpdateFlag = 1; - lastPhysGroupRot = GroupRotation; - } - - foreach (SceneObjectPart part in m_parts.Values) - { - if (!IsSelected) - part.UpdateLookAt(); - - part.SendScheduledUpdates(); - - } + List partList = null; + partList = new List(m_parts.Values); + + foreach (SceneObjectPart part in partList) + { + if (!IsSelected) + part.UpdateLookAt(); + part.SendScheduledUpdates(); } lockPartsForRead(false); } @@ -3161,11 +3163,12 @@ namespace OpenSim.Region.Framework.Scenes public void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF) { + List partList = null; lock (m_parts) - { - foreach (SceneObjectPart part in m_parts.Values) - part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); - } + partList = new List(m_parts.Values); + + foreach (SceneObjectPart part in partList) + part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); HasGroupChanged = true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9e52b001b7..eefe8bb5f1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4756,20 +4756,8 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup == null || ParentGroup.IsDeleted) return; - Vector3 lPos = OffsetPosition; - - if (IsAttachment) - { - if (ParentGroup.RootPart != this) - return; - - lPos = ParentGroup.RootPart.AttachedPos; - } - else - { - if (ParentGroup.RootPart == this) - lPos = AbsolutePosition; - } + if (IsAttachment && ParentGroup.RootPart != this) + return; // Causes this thread to dig into the Client Thread Data. // Remember your locking here! diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 10931b76ed..c5994b2397 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -724,8 +724,7 @@ namespace OpenSim.Region.Framework.Scenes } public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) - { - UUID ownerID = item.OwnerID; + { AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == rezAsset) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 02e60f8820..cd80eb0ce7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2668,15 +2668,15 @@ namespace OpenSim.Region.Framework.Scenes { m_perfMonMS = Util.EnvironmentTickCount(); - PhysicsActor actor = m_physicsActor; - Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; - Vector3 pos = m_pos; pos.Z += m_appearance.HipOffset; //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); - remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + remoteClient.SendPrimUpdate( + this, + PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity + | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentUpdates(1); diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 34171b066c..c439e3ec20 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -186,18 +186,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule { SceneObjectPart my = GetSOP(); IObject[] rets = null; - + + int total = my.ParentGroup.PrimCount; + + rets = new IObject[total]; + + int i = 0; + + List partList = null; lock (my.ParentGroup.Children) + partList = new List(my.ParentGroup.Children.Values); + + foreach (SceneObjectPart part in partList) { - int total = my.ParentGroup.Children.Count; - - rets = new IObject[total]; - - int i = 0; - foreach (KeyValuePair pair in my.ParentGroup.Children) - { - rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); - } + rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security); } return rets; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8381efaec4..512957de8c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9611,8 +9611,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // we send to all landData.MediaID = new UUID(texture); landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; - landData.MediaSize[0] = width; - landData.MediaSize[1] = height; + landData.MediaWidth = width; + landData.MediaHeight = height; landData.MediaType = mediaType; // do that one last, it will cause a ParcelPropertiesUpdate @@ -9698,8 +9698,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); break; case ParcelMediaCommandEnum.Size: - list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[0])); - list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[1])); + list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth)); + list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight)); break; default: ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index ed0b1a6a9a..b70b47df54 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs @@ -86,7 +86,7 @@ namespace OpenSim.Tests.Common.Mock { InventoryFolderBase folder = m_folders[folderID]; - m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0} {1}", folder.Name, folder.ID); +// m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0} {1}", folder.Name, folder.ID); List items = new List(); @@ -94,7 +94,7 @@ namespace OpenSim.Tests.Common.Mock { if (item.Folder == folderID) { - m_log.DebugFormat("[MOCK INV DB]: getInventoryInFolder() adding item {0}", item.Name); +// m_log.DebugFormat("[MOCK INV DB]: getInventoryInFolder() adding item {0}", item.Name); items.Add(item); } } @@ -106,7 +106,7 @@ namespace OpenSim.Tests.Common.Mock public InventoryFolderBase getUserRootFolder(UUID user) { - m_log.DebugFormat("[MOCK INV DB]: Looking for root folder for {0}", user); +// m_log.DebugFormat("[MOCK INV DB]: Looking for root folder for {0}", user); InventoryFolderBase folder = null; m_rootFolders.TryGetValue(user, out folder); @@ -118,7 +118,7 @@ namespace OpenSim.Tests.Common.Mock { InventoryFolderBase parentFolder = m_folders[parentID]; - m_log.DebugFormat("[MOCK INV DB]: Getting folders in folder {0} {1}", parentFolder.Name, parentFolder.ID); +// m_log.DebugFormat("[MOCK INV DB]: Getting folders in folder {0} {1}", parentFolder.Name, parentFolder.ID); List folders = new List(); @@ -126,9 +126,9 @@ namespace OpenSim.Tests.Common.Mock { if (folder.ParentID == parentID) { - m_log.DebugFormat( - "[MOCK INV DB]: Found folder {0} {1} in {2} {3}", - folder.Name, folder.ID, parentFolder.Name, parentFolder.ID); +// m_log.DebugFormat( +// "[MOCK INV DB]: Found folder {0} {1} in {2} {3}", +// folder.Name, folder.ID, parentFolder.Name, parentFolder.ID); folders.Add(folder); } @@ -152,9 +152,9 @@ namespace OpenSim.Tests.Common.Mock public void addInventoryFolder(InventoryFolderBase folder) { - m_log.DebugFormat( - "[MOCK INV DB]: Adding inventory folder {0} {1} type {2}", - folder.Name, folder.ID, (AssetType)folder.Type); +// m_log.DebugFormat( +// "[MOCK INV DB]: Adding inventory folder {0} {1} type {2}", +// folder.Name, folder.ID, (AssetType)folder.Type); m_folders[folder.ID] = folder; @@ -187,8 +187,8 @@ namespace OpenSim.Tests.Common.Mock { InventoryFolderBase folder = m_folders[item.Folder]; - m_log.DebugFormat( - "[MOCK INV DB]: Adding inventory item {0} {1} in {2} {3}", item.Name, item.ID, folder.Name, folder.ID); +// m_log.DebugFormat( +// "[MOCK INV DB]: Adding inventory item {0} {1} in {2} {3}", item.Name, item.ID, folder.Name, folder.ID); m_items[item.ID] = item; } diff --git a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs index 380f258606..26156f396f 100644 --- a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs +++ b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs @@ -127,12 +127,19 @@ namespace OpenSim.Tests.Common.Setup { UserAccount ua = new UserAccount(userId) - { FirstName = firstName, LastName = lastName, ServiceURLs = new Dictionary() }; + { FirstName = firstName, LastName = lastName }; + CreateUserWithInventory(scene, ua, pw); + return ua; + } + + public static void CreateUserWithInventory(Scene scene, UserAccount ua, string pw) + { + // FIXME: This should really be set up by UserAccount itself + ua.ServiceURLs = new Dictionary(); + scene.UserAccountService.StoreUserAccount(ua); scene.InventoryService.CreateUserInventory(ua.PrincipalID); scene.AuthenticationService.SetPassword(ua.PrincipalID, pw); - - return ua; - } + } } } \ No newline at end of file diff --git a/bin/Newtonsoft.Json.dll b/bin/Newtonsoft.Json.Net20.dll similarity index 100% rename from bin/Newtonsoft.Json.dll rename to bin/Newtonsoft.Json.Net20.dll diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 0353eec65c..093ead81d2 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -57,8 +57,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" ; Realm = "regions" ; AllowDuplicateNames = "True" - ; Check4096 = "False" - + ;; Next, we can specify properties of regions, including default and fallback regions ;; The syntax is: Region_ = "" ;; or: Region_ = ""