From 954329ec85a1c793a8050b28821f4349781ff445 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 21 Aug 2010 17:48:49 +0200 Subject: [PATCH 01/60] Don't allow oversized search reply packets --- .../ClientStack/LindenUDP/LLClientView.cs | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 1d3bdf3ff7..4add1cae49 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2715,32 +2715,57 @@ namespace OpenSim.Region.ClientStack.LindenUDP packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); - packet.QueryReplies = - new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; - - packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ - data.Length]; - packet.AgentData.AgentID = AgentId; packet.QueryData[0].QueryID = queryID; + DirPlacesReplyPacket.QueryRepliesBlock[] replies = + new DirPlacesReplyPacket.QueryRepliesBlock[0]; + DirPlacesReplyPacket.StatusDataBlock[] status = + new DirPlacesReplyPacket.StatusDataBlock[0]; + int i = 0; foreach (DirPlacesReplyData d in data) { - packet.QueryReplies[i] = - new DirPlacesReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].Dwell = d.dwell; - packet.StatusData[i].Status = d.Status; - i++; + int idx = replies.Length; + Array.Resize(ref replies, idx + 1); + Array.Resize(ref status, idx + 1); + + replies[idx] = new DirPlacesReplyPacket.QueryRepliesBlock(); + status[idx] = new DirPlacesReplyPacket.StatusDataBlock(); + replies[idx].ParcelID = d.parcelID; + replies[idx].Name = Utils.StringToBytes(d.name); + replies[idx].ForSale = d.forSale; + replies[idx].Auction = d.auction; + replies[idx].Dwell = d.dwell; + status[idx].Status = d.Status; + + packet.QueryReplies = replies; + packet.StatusData = status; + + if (packet.Length >= 1000) + { + OutPacket(packet, ThrottleOutPacketType.Task); + + packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); + + packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); + + packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; + packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); + + packet.AgentData.AgentID = AgentId; + + packet.QueryData[0].QueryID = queryID; + + replies = new DirPlacesReplyPacket.QueryRepliesBlock[0]; + status = new DirPlacesReplyPacket.StatusDataBlock[0]; + + } } - OutPacket(packet, ThrottleOutPacketType.Task); + if (replies.Length > 0) + OutPacket(packet, ThrottleOutPacketType.Task); } public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) From f445659dd3a0f4f5998a44b93991159a8beacbf1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 21 Aug 2010 17:38:47 +0100 Subject: [PATCH 02/60] Finally putting estate_settings.xml to rest. There will be no more attempts to read or write this file. --- OpenSim/Framework/RegionSettings.cs | 198 ---------------------------- 1 file changed, 198 deletions(-) diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index 8d1212bbbc..673cf203f8 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -33,8 +33,6 @@ namespace OpenSim.Framework { public class RegionSettings { - private ConfigurationMember configMember; - public delegate void SaveDelegate(RegionSettings rs); public event SaveDelegate OnSave; @@ -47,202 +45,6 @@ namespace OpenSim.Framework public static readonly UUID DEFAULT_TERRAIN_TEXTURE_3 = new UUID("179cdabd-398a-9b6b-1391-4dc333ba321f"); public static readonly UUID DEFAULT_TERRAIN_TEXTURE_4 = new UUID("beb169c7-11ea-fff2-efe5-0f24dc881df2"); - public RegionSettings() - { - if (configMember == null) - { - try - { - configMember = new ConfigurationMember(Path.Combine(Util.configDir(), "estate_settings.xml"), "ESTATE SETTINGS", LoadConfigurationOptions, HandleIncomingConfiguration, true); - configMember.performConfigurationRetrieve(); - } - catch (Exception) - { - } - } - } - - public void LoadConfigurationOptions() - { - configMember.addConfigurationOption("region_flags", - ConfigurationOption.ConfigurationTypes.TYPE_UINT32, - String.Empty, "336723974", true); - - configMember.addConfigurationOption("max_agents", - ConfigurationOption.ConfigurationTypes.TYPE_INT32, - String.Empty, "40", true); - - configMember.addConfigurationOption("object_bonus_factor", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "1.0", true); - - configMember.addConfigurationOption("sim_access", - ConfigurationOption.ConfigurationTypes.TYPE_INT32, - String.Empty, "21", true); - - configMember.addConfigurationOption("terrain_base_0", - ConfigurationOption.ConfigurationTypes.TYPE_UUID, - String.Empty, DEFAULT_TERRAIN_TEXTURE_1.ToString(), true); - - configMember.addConfigurationOption("terrain_base_1", - ConfigurationOption.ConfigurationTypes.TYPE_UUID, - String.Empty, DEFAULT_TERRAIN_TEXTURE_2.ToString(), true); - - configMember.addConfigurationOption("terrain_base_2", - ConfigurationOption.ConfigurationTypes.TYPE_UUID, - String.Empty, DEFAULT_TERRAIN_TEXTURE_3.ToString(), true); - - configMember.addConfigurationOption("terrain_base_3", - ConfigurationOption.ConfigurationTypes.TYPE_UUID, - String.Empty, DEFAULT_TERRAIN_TEXTURE_4.ToString(), true); - - configMember.addConfigurationOption("terrain_start_height_0", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "10.0", true); - - configMember.addConfigurationOption("terrain_start_height_1", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "10.0", true); - - configMember.addConfigurationOption("terrain_start_height_2", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "10.0", true); - - configMember.addConfigurationOption("terrain_start_height_3", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "10.0", true); - - configMember.addConfigurationOption("terrain_height_range_0", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "60.0", true); - - configMember.addConfigurationOption("terrain_height_range_1", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "60.0", true); - - configMember.addConfigurationOption("terrain_height_range_2", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "60.0", true); - - configMember.addConfigurationOption("terrain_height_range_3", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "60.0", true); - - configMember.addConfigurationOption("region_water_height", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "20.0", true); - - configMember.addConfigurationOption("terrain_raise_limit", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "100.0", true); - - configMember.addConfigurationOption("terrain_lower_limit", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "-100.0", true); - - configMember.addConfigurationOption("sun_hour", - ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, - String.Empty, "0.0", true); - } - - public bool HandleIncomingConfiguration(string key, object value) - { - switch (key) - { - case "region_flags": - RegionFlags flags = (RegionFlags)(uint)value; - - m_BlockTerraform = - (flags & RegionFlags.BlockTerraform) != 0; - m_BlockFly = - (flags & RegionFlags.NoFly) != 0; - m_AllowDamage = - (flags & RegionFlags.AllowDamage) != 0; - m_RestrictPushing = - (flags & RegionFlags.RestrictPushObject) != 0; - m_AllowLandResell = - (flags & RegionFlags.BlockLandResell) == 0; - m_AllowLandJoinDivide = - (flags & RegionFlags.AllowParcelChanges) != 0; - m_BlockShowInSearch = - ((uint)flags & (1 << 29)) != 0; - m_DisableScripts = - (flags & RegionFlags.SkipScripts) != 0; - m_DisableCollisions = - (flags & RegionFlags.SkipCollisions) != 0; - m_DisablePhysics = - (flags & RegionFlags.SkipPhysics) != 0; - m_FixedSun = - (flags & RegionFlags.SunFixed) != 0; - m_Sandbox = - (flags & RegionFlags.Sandbox) != 0; - break; - case "max_agents": - m_AgentLimit = (int)value; - break; - case "object_bonus_factor": - m_ObjectBonus = (double)value; - break; - case "sim_access": - int access = (int)value; - if (access <= 13) - m_Maturity = 0; - else - m_Maturity = 1; - break; - case "terrain_base_0": - m_TerrainTexture1 = (UUID)value; - break; - case "terrain_base_1": - m_TerrainTexture2 = (UUID)value; - break; - case "terrain_base_2": - m_TerrainTexture3 = (UUID)value; - break; - case "terrain_base_3": - m_TerrainTexture4 = (UUID)value; - break; - case "terrain_start_height_0": - m_Elevation1SW = (double)value; - break; - case "terrain_start_height_1": - m_Elevation1NW = (double)value; - break; - case "terrain_start_height_2": - m_Elevation1SE = (double)value; - break; - case "terrain_start_height_3": - m_Elevation1NE = (double)value; - break; - case "terrain_height_range_0": - m_Elevation2SW = (double)value; - break; - case "terrain_height_range_1": - m_Elevation2NW = (double)value; - break; - case "terrain_height_range_2": - m_Elevation2SE = (double)value; - break; - case "terrain_height_range_3": - m_Elevation2NE = (double)value; - break; - case "region_water_height": - m_WaterHeight = (double)value; - break; - case "terrain_raise_limit": - m_TerrainRaiseLimit = (double)value; - break; - case "terrain_lower_limit": - m_TerrainLowerLimit = (double)value; - break; - case "sun_hour": - m_SunPosition = (double)value; - break; - } - - return true; - } - public void Save() { if (OnSave != null) From 8d8436e0cadfdfc03808e8ba4a4ebcad97414f68 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 21 Aug 2010 20:59:25 +0100 Subject: [PATCH 03/60] Correct a minor typo --- bin/OpenSim.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 1ae9f9af7f..dac6477623 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -224,7 +224,7 @@ ;MapImageModule = "MapImageModule" ; Set to false to not generate any maptiles ;GenerateMaptiles = "true" - ; Refreah (in seconds) the map tile periodically + ; Refresh (in seconds) the map tile periodically ;MaptileRefresh = 0 ; If not generating maptiles, use this static texture asset ID ;MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" From 74e5fe5aa94aa338c0e574553ccabd42a93b0bbd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 23 Aug 2010 22:24:23 +0100 Subject: [PATCH 04/60] Remove various warnings and improve logging messages. No functional changes. --- .../ClientStack/LindenUDP/LLClientView.cs | 2 - .../InstantMessage/InstantMessageModule.cs | 2 +- .../InstantMessage/MessageTransferModule.cs | 16 ++++---- .../Transfer/InventoryTransferModule.cs | 17 ++++----- .../Inventory/BaseInventoryConnector.cs | 3 -- .../Inventory/InventoryCache.cs | 7 ++++ .../LocalInventoryServiceConnector.cs | 5 ++- .../RemoteInventoryServiceConnector.cs | 1 - .../Framework/Scenes/Scene.Inventory.cs | 6 ++- .../Region/ScriptEngine/XEngine/XEngine.cs | 2 +- .../Friends/FriendsServiceConnector.cs | 8 +--- .../Hypergrid/GatekeeperServiceConnector.cs | 4 +- .../Hypergrid/UserAgentServiceConnector.cs | 7 +--- .../SimianAvatarServiceConnector.cs | 4 +- .../SimianInventoryServiceConnector.cs | 28 +++++++------- .../SimianPresenceServiceConnector.cs | 38 +++++++++---------- .../InventoryService/XInventoryService.cs | 7 +++- 17 files changed, 78 insertions(+), 79 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 4add1cae49..db81fb9358 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2724,7 +2724,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP DirPlacesReplyPacket.StatusDataBlock[] status = new DirPlacesReplyPacket.StatusDataBlock[0]; - int i = 0; foreach (DirPlacesReplyData d in data) { int idx = replies.Length; @@ -2760,7 +2759,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP replies = new DirPlacesReplyPacket.QueryRepliesBlock[0]; status = new DirPlacesReplyPacket.StatusDataBlock[0]; - } } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index a3c40e0725..420e3ca402 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -198,4 +198,4 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage OnInstantMessage(null, msg); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index d025f0c0e3..730cc77896 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -132,20 +132,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { UUID toAgentID = new UUID(im.toAgentID); - m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString()); - // Try root avatar only first foreach (Scene scene in m_Scenes) { if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) - { - m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName); - // Local message + { +// m_log.DebugFormat( +// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", +// toAgentID.ToString(), scene.RegionInfo.RegionName); + ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; if (!user.IsChildAgent) { - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); + // Local message + m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); user.ControllingClient.SendInstantMessage(im); // Message sent @@ -167,7 +168,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Local message ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); + m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); user.ControllingClient.SendInstantMessage(im); // Message sent @@ -176,6 +177,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } + m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); SendGridInstantMessageViaXMLRPC(im, result); return; diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 8b77a5f4ee..4117e86f18 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -32,7 +32,6 @@ using log4net; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; - using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; @@ -92,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer m_TransferModule = m_Scenelist[0].RequestModuleInterface(); if (m_TransferModule == null) { - m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); + m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only"); m_Enabled = false; m_Scenelist.Clear(); @@ -160,8 +159,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { - m_log.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog); - + m_log.InfoFormat( + "[INVENTORY TRANSFER]: {0} IM type received from {1}", + (InstantMessageDialog)im.dialog, client.Name); + Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. @@ -185,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer { UUID folderID = new UUID(im.binaryBucket, 1); - m_log.DebugFormat("[AGENT INVENTORY]: Inserting original folder {0} "+ + m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} "+ "into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); @@ -221,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer UUID itemID = new UUID(im.binaryBucket, 1); - m_log.DebugFormat("[AGENT INVENTORY]: (giving) Inserting item {0} "+ + m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} "+ "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); @@ -286,10 +287,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // - - //CachedUserInfo userInfo = - // scene.CommsManager.UserProfileCacheService. - // GetUserDetails(client.AgentId); IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs index 1e51187900..dcf08e3d80 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs @@ -27,15 +27,12 @@ using System; using System.Collections.Generic; - using OpenMetaverse; using Nini.Config; using log4net; - using OpenSim.Framework; using OpenSim.Services.Interfaces; - namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { public abstract class BaseInventoryConnector : IInventoryService diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index c97ab9e8da..4e2f6024cc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -161,6 +161,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory /// public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) { + m_log.DebugFormat("[INVENTORY CACHE]: Getting folder for asset type {0} for user {1}", type, userID); + Dictionary folders = null; lock (m_InventoryCache) @@ -177,8 +179,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if ((folders != null) && folders.ContainsKey(type)) { + m_log.DebugFormat( + "[INVENTORY CACHE]: Returning folder {0} as type {1} for {2}", folders[type], type, userID); + return folders[type]; } + + m_log.WarnFormat("[INVENTORY CACHE]: Could not find folder for system type {0} for {1}", type, userID); return null; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 22bd04cd65..3de6e5cb49 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -223,6 +223,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory /// true if the item was successfully added public bool AddItem(InventoryItemBase item) { + m_log.DebugFormat( + "[LOCAL INVENTORY SERVICES CONNECTOR]: Adding inventory item {0} to user {1} folder {2}", + item.Name, item.Owner, item.Folder); + return m_InventoryService.AddItem(item); } @@ -236,7 +240,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_InventoryService.UpdateItem(item); } - public bool MoveItems(UUID ownerID, List items) { return m_InventoryService.MoveItems(ownerID, items); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs index 153aeec1a4..17d80c7953 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs @@ -75,7 +75,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory base.Init(source); } - #region ISharedRegionModule public void Initialise(IConfigSource source) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4d84018942..4e0ddcbbed 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -945,7 +945,6 @@ namespace OpenSim.Region.Framework.Scenes private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) { - Console.WriteLine("CreateAgentInventoryItemFromTask"); TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId); if (null == taskItem) @@ -1016,7 +1015,10 @@ namespace OpenSim.Region.Framework.Scenes /// public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId) { - m_log.Info("Adding task inventory"); + m_log.DebugFormat( + "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}", + itemId, part.Name, folderId, remoteClient.Name); + InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId); if (agentItem == null) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b0503499f2..8102acd457 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1294,7 +1294,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { sdoc.LoadXml(xml); } - catch (System.Xml.XmlException e) + catch (System.Xml.XmlException) { loadedState = false; } diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index d7a5731daa..36b5083860 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -156,8 +156,6 @@ namespace OpenSim.Services.Connectors sendData["METHOD"] = "storefriend"; - string reqString = ServerUtils.BuildQueryString(sendData); - string reply = string.Empty; try { @@ -199,8 +197,6 @@ namespace OpenSim.Services.Connectors sendData["FRIEND"] = Friend; sendData["METHOD"] = "deletefriend"; - string reqString = ServerUtils.BuildQueryString(sendData); - string reply = string.Empty; try { @@ -232,10 +228,8 @@ namespace OpenSim.Services.Connectors m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend received null reply"); return false; - } #endregion - } -} +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index 291dd730de..024b42d433 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -31,11 +31,9 @@ using System.Collections.Generic; using System.Drawing; using System.Net; using System.Reflection; - using OpenSim.Framework; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; - using OpenMetaverse; using OpenMetaverse.Imaging; using OpenMetaverse.StructuredData; @@ -50,7 +48,7 @@ namespace OpenSim.Services.Connectors.Hypergrid { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013"); +// private static UUID m_HGMapImage = new UUID("00000000-0000-1111-9999-000000000013"); private IAssetService m_AssetService; diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index c1e594947e..45019373cf 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -32,12 +32,10 @@ using System.IO; using System.Net; using System.Reflection; using System.Text; - using OpenSim.Framework; using OpenSim.Services.Interfaces; using OpenSim.Services.Connectors.Simulation; using GridRegion = OpenSim.Services.Interfaces.GridRegion; - using OpenMetaverse; using OpenMetaverse.StructuredData; using log4net; @@ -243,7 +241,7 @@ namespace OpenSim.Services.Connectors.Hypergrid { response = request.Send(m_ServerURL, 10000); } - catch (Exception e) + catch (Exception) { return null; } @@ -308,13 +306,12 @@ namespace OpenSim.Services.Connectors.Hypergrid } } - catch (Exception e) + catch (Exception) { return null; } return null; - } public bool AgentIsComingHome(UUID sessionID, string thisGridExternalName) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index a47f32cf7d..734bdd2e48 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -53,7 +53,7 @@ namespace OpenSim.Services.Connectors.SimianGrid private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private static string ZeroID = UUID.Zero.ToString(); +// private static string ZeroID = UUID.Zero.ToString(); private string m_serverUrl = String.Empty; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index 2b6d29c44d..89c1a5a445 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors.SimianGrid private string m_serverUrl = String.Empty; private string m_userServerUrl = String.Empty; - private object m_gestureSyncRoot = new object(); +// private object m_gestureSyncRoot = new object(); #region ISharedRegionModule @@ -687,12 +687,12 @@ namespace OpenSim.Services.Connectors.SimianGrid for (int i = 0; i < items.Count; i++) itemIDs[i] = items[i].AsUUID().ToString(); - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetInventoryNodes" }, - { "OwnerID", userID.ToString() }, - { "Items", String.Join(",", itemIDs) } - }; +// NameValueCollection requestArgs = new NameValueCollection +// { +// { "RequestMethod", "GetInventoryNodes" }, +// { "OwnerID", userID.ToString() }, +// { "Items", String.Join(",", itemIDs) } +// }; // FIXME: Implement this in SimianGrid return new List(0); @@ -708,12 +708,12 @@ namespace OpenSim.Services.Connectors.SimianGrid /// the user's inventory public int GetAssetPermissions(UUID userID, UUID assetID) { - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetInventoryNodes" }, - { "OwnerID", userID.ToString() }, - { "AssetID", assetID.ToString() } - }; +// NameValueCollection requestArgs = new NameValueCollection +// { +// { "RequestMethod", "GetInventoryNodes" }, +// { "OwnerID", userID.ToString() }, +// { "AssetID", assetID.ToString() } +// }; // FIXME: Implement this in SimianGrid return (int)PermissionMask.All; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 6f179317d2..ca23e27347 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -349,24 +349,24 @@ namespace OpenSim.Services.Connectors.SimianGrid return null; } - private OSDMap GetSessionData(UUID sessionID) - { - m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for session " + sessionID); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetSession" }, - { "SessionID", sessionID.ToString() } - }; - - OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); - if (response["Success"].AsBoolean()) - return response; - else - m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID); - - return null; - } +// private OSDMap GetSessionData(UUID sessionID) +// { +// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for session " + sessionID); +// +// NameValueCollection requestArgs = new NameValueCollection +// { +// { "RequestMethod", "GetSession" }, +// { "SessionID", sessionID.ToString() } +// }; +// +// OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); +// if (response["Success"].AsBoolean()) +// return response; +// else +// m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID); +// +// return null; +// } private List GetSessions(UUID userID) { diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index f63ab1613e..90a5c225a0 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -157,6 +157,8 @@ namespace OpenSim.Services.InventoryService protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID) { +// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting system folders for {0}", principalID); + XInventoryFolder[] allFolders = m_Database.GetFolders( new string[] { "agentID" }, new string[] { principalID.ToString() }); @@ -170,6 +172,9 @@ namespace OpenSim.Services.InventoryService return false; }); +// m_log.DebugFormat( +// "[XINVENTORY SERVICE]: Found {0} system folders for {1}", sysFolders.Length, principalID); + return sysFolders; } @@ -186,7 +191,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in allFolders) { - //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to skeleton", x.folderName); + //m_log.DebugFormat("[XINVENTORY SERVICE]: Adding folder {0} to skeleton", x.folderName); folders.Add(ConvertToOpenSim(x)); } From 704a53fb9bfeb945fa25f7367c631698dea5ae89 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 23 Aug 2010 23:16:48 +0100 Subject: [PATCH 05/60] Fix bug in llGiveInventory() where items were disappearing on relog This was a regression - the code to look up the correct type folder was no longer being called if items were added without a parent folder set This may have been broken since commit bd49985a on 2010-05-02 --- .../LocalInventoryServiceConnector.cs | 22 ++++++++++++++----- .../RemoteXInventoryServiceConnector.cs | 5 +---- .../Shared/Api/Implementation/LSL_Api.cs | 6 ++--- .../Services/Interfaces/IInventoryService.cs | 7 ++++-- .../InventoryService/XInventoryService.cs | 14 +++++++++++- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 3de6e5cb49..350ad66457 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -216,16 +216,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_InventoryService.PurgeFolder(folder); } - /// - /// Add a new item to the user's inventory - /// - /// - /// true if the item was successfully added public bool AddItem(InventoryItemBase item) { m_log.DebugFormat( "[LOCAL INVENTORY SERVICES CONNECTOR]: Adding inventory item {0} to user {1} folder {2}", item.Name, item.Owner, item.Folder); + + if (UUID.Zero == item.Folder) + { + InventoryFolderBase f = m_InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); + if (f != null) + { + item.Folder = f.ID; + } + else + { + f = m_InventoryService.GetRootFolder(item.Owner); + if (f != null) + item.Folder = f.ID; + else + return false; + } + } return m_InventoryService.AddItem(item); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index ada26cc359..34205e3df8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -294,9 +294,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.GetAssetPermissions(userID, assetID); } - #endregion - - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b6eddb1255..dc43e453b8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3844,18 +3844,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (World.GetScenePresence(destId) != null) { // destination is an avatar - InventoryItemBase agentItem = - World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); + InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); if (agentItem == null) return; byte[] bucket = new byte[17]; bucket[0] = (byte)assetType; - byte[] objBytes = objId.GetBytes(); + byte[] objBytes = agentItem.ID.GetBytes(); Array.Copy(objBytes, 0, bucket, 1, 16); - Console.WriteLine("Giving inventory"); GridInstantMessage msg = new GridInstantMessage(World, m_host.UUID, m_host.Name+", an object owned by "+ resolveName(m_host.OwnerID)+",", destId, diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs index 1b78fb3912..d19faeddf7 100644 --- a/OpenSim/Services/Interfaces/IInventoryService.cs +++ b/OpenSim/Services/Interfaces/IInventoryService.cs @@ -141,8 +141,11 @@ namespace OpenSim.Services.Interfaces /// /// Add a new item to the user's inventory /// - /// - /// true if the item was successfully added + /// + /// The item to be added. If item.FolderID == UUID.Zero then the item is added to the most suitable system + /// folder. If there is no suitable folder then the item is added to the user's root inventory folder. + /// + /// true if the item was successfully added, false if it was not bool AddItem(InventoryItemBase item); /// diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 90a5c225a0..84306e7296 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -219,12 +219,21 @@ namespace OpenSim.Services.InventoryService public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) { +// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID); + XInventoryFolder[] folders = m_Database.GetFolders( new string[] { "agentID", "type"}, new string[] { principalID.ToString(), ((int)type).ToString() }); if (folders.Length == 0) + { +// m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID); return null; + } + +// m_log.DebugFormat( +// "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}", +// folders[0].folderName, folders[0].folderID, type, principalID); return ConvertToOpenSim(folders[0]); } @@ -235,7 +244,7 @@ namespace OpenSim.Services.InventoryService // connector. So we disregard the principal and look // by ID. // - m_log.DebugFormat("[XINVENTORY]: Fetch contents for folder {0}", folderID.ToString()); + m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString()); InventoryCollection inventory = new InventoryCollection(); inventory.UserID = principalID; inventory.Folders = new List(); @@ -354,6 +363,9 @@ namespace OpenSim.Services.InventoryService public virtual bool AddItem(InventoryItemBase item) { +// m_log.DebugFormat( +// "[XINVENTORY SERVICE]: Adding item {0} to folder {1} for {2}", item.ID, item.Folder, item.Owner); + return m_Database.StoreItem(ConvertFromOpenSim(item)); } From 1d01c910951c09aa348e4fb407226fb3fcf35288 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 23 Aug 2010 23:21:44 +0100 Subject: [PATCH 06/60] minor: some doc for the MoveTaskInventoryItem method in Scene.Inventory.cs --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4e0ddcbbed..241e100d00 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1084,7 +1084,11 @@ namespace OpenSim.Region.Framework.Scenes /// MoveTaskInventoryItem /// /// - /// + /// + /// The user inventory folder to move (or copy) the item to. If null, then the most + /// suitable system folder is used (e.g. the Objects folder for objects). If there is no suitable folder, then + /// the item is placed in the user's root inventory folder + /// /// /// public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId) From c72d298202699931fd67c981fa10b9280d02686f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 23 Aug 2010 23:25:36 +0100 Subject: [PATCH 07/60] Add system lookup folder fix to the RemoveXInventoryServiceConnector as well since this presumably suffers from the same problem. --- .../RemoteXInventoryServiceConnector.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 34205e3df8..7ac3bb9f4e 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -228,6 +228,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { if (item == null) return false; + + if (UUID.Zero == item.Folder) + { + InventoryFolderBase f = m_RemoteConnector.GetFolderForType(item.Owner, (AssetType)item.AssetType); + if (f != null) + { + item.Folder = f.ID; + } + else + { + f = m_RemoteConnector.GetRootFolder(item.Owner); + if (f != null) + item.Folder = f.ID; + else + return false; + } + } return m_RemoteConnector.AddItem(item); } From de85aabcbe51472a34b83943d0993e25b63ca074 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 24 Aug 2010 12:41:21 +0100 Subject: [PATCH 08/60] Plumb the region type through to the ProductName field in estate messages --- OpenSim/Framework/RegionInfoForEstateMenuArgs.cs | 3 ++- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 ++-- .../Region/CoreModules/World/Estate/EstateManagementModule.cs | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/RegionInfoForEstateMenuArgs.cs b/OpenSim/Framework/RegionInfoForEstateMenuArgs.cs index fee3126978..f274da2e7a 100644 --- a/OpenSim/Framework/RegionInfoForEstateMenuArgs.cs +++ b/OpenSim/Framework/RegionInfoForEstateMenuArgs.cs @@ -47,5 +47,6 @@ namespace OpenSim.Framework public bool useEstateSun; public float waterHeight; public string simName; + public string regionType; } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index db81fb9358..320a2fa94a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -717,7 +717,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handshake.RegionInfo3.CPURatio = 1; handshake.RegionInfo3.ColoName = Utils.EmptyBytes; - handshake.RegionInfo3.ProductName = Utils.EmptyBytes; + handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; OutPacket(handshake, ThrottleOutPacketType.Task); @@ -4106,7 +4106,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue; rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue; rinfopack.RegionInfo2.MaxAgents32 = uint.MaxValue; - rinfopack.RegionInfo2.ProductName = Utils.EmptyBytes; + rinfopack.RegionInfo2.ProductName = Util.StringToBytes256(args.regionType); rinfopack.RegionInfo2.ProductSKU = Utils.EmptyBytes; rinfopack.HasVariableBlocks = true; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 51f2c41f8e..5025c88255 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -670,6 +670,7 @@ namespace OpenSim.Region.CoreModules.World.Estate args.useEstateSun = m_scene.RegionInfo.RegionSettings.UseEstateSun; args.waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; args.simName = m_scene.RegionInfo.RegionName; + args.regionType = m_scene.RegionInfo.RegionType; remote_client.SendRegionInfoToEstateMenu(args); } From 289c21099cf3ce0a2e3392436541b67d0961d8e8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 16:50:31 +0100 Subject: [PATCH 09/60] Add automated test at the opensim 'api' level to check that a given item goes to the correct directory Also removes some mono compiler warnings --- OpenSim/Data/Tests/EstateTests.cs | 6 - OpenSim/Data/Tests/InventoryTests.cs | 4 - OpenSim/Data/Tests/RegionTests.cs | 4 - .../LocalInventoryServiceConnector.cs | 17 ++- .../RemoteXInventoryServiceConnector.cs | 7 ++ .../Framework/Scenes/Scene.Inventory.cs | 2 +- .../Scenes/Tests/TaskInventoryTests.cs | 104 ++++++++++++++++++ .../InventoryService/InventoryService.cs | 9 +- .../Tests/Common/Mock/MockInventoryService.cs | 12 +- .../Common/Mock/TestInventoryDataPlugin.cs | 31 +++++- .../Tests/Common/Setup/SceneSetupHelpers.cs | 6 + 11 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs diff --git a/OpenSim/Data/Tests/EstateTests.cs b/OpenSim/Data/Tests/EstateTests.cs index d6eed3dadd..fbf8ba658e 100644 --- a/OpenSim/Data/Tests/EstateTests.cs +++ b/OpenSim/Data/Tests/EstateTests.cs @@ -37,11 +37,6 @@ using log4net; using System.Reflection; using System.Data.Common; -#if !NUNIT25 -using NUnit.Framework.SyntaxHelpers; -#endif - - // DBMS-specific: using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; @@ -52,7 +47,6 @@ using OpenSim.Data.MSSQL; using Mono.Data.Sqlite; using OpenSim.Data.SQLite; - namespace OpenSim.Data.Tests { diff --git a/OpenSim/Data/Tests/InventoryTests.cs b/OpenSim/Data/Tests/InventoryTests.cs index c22e26c3c9..3205bfa7f3 100644 --- a/OpenSim/Data/Tests/InventoryTests.cs +++ b/OpenSim/Data/Tests/InventoryTests.cs @@ -37,10 +37,6 @@ using log4net; using System.Reflection; using System.Data.Common; -#if !NUNIT25 -using NUnit.Framework.SyntaxHelpers; -#endif - // DBMS-specific: using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 3cd9e0be1e..29bf5a3418 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -40,10 +40,6 @@ using log4net; using System.Reflection; using System.Data.Common; -#if !NUNIT25 -using NUnit.Framework.SyntaxHelpers; -#endif - // DBMS-specific: using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 350ad66457..915b59ec29 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -218,24 +218,35 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public bool AddItem(InventoryItemBase item) { - m_log.DebugFormat( - "[LOCAL INVENTORY SERVICES CONNECTOR]: Adding inventory item {0} to user {1} folder {2}", - item.Name, item.Owner, item.Folder); +// m_log.DebugFormat( +// "[LOCAL INVENTORY SERVICES CONNECTOR]: Adding inventory item {0} to user {1} folder {2}", +// item.Name, item.Owner, item.Folder); if (UUID.Zero == item.Folder) { InventoryFolderBase f = m_InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); if (f != null) { +// m_log.DebugFormat( +// "[LOCAL INVENTORY SERVICES CONNECTOR]: Found folder {0} type {1} for item {2}", +// f.Name, (AssetType)f.Type, item.Name); + item.Folder = f.ID; } else { f = m_InventoryService.GetRootFolder(item.Owner); if (f != null) + { item.Folder = f.ID; + } else + { +// m_log.WarnFormat( +// "[LOCAL INVENTORY SERVICES CONNECTOR]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified", +// item.Owner, item.Name); return false; + } } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 7ac3bb9f4e..4211fa9b07 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -240,9 +240,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { f = m_RemoteConnector.GetRootFolder(item.Owner); if (f != null) + { item.Folder = f.ID; + } else + { + m_log.WarnFormat( + "[LOCAL INVENTORY SERVICES CONNECTOR]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified", + item.Owner, item.Name); return false; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 241e100d00..fa9653f7af 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.Framework.Scenes else { m_log.WarnFormat( - "[AGENT INVENTORY]: Agent {1} could not add item {2} {3}", + "[AGENT INVENTORY]: Agent {0} could not add item {1} {2}", AgentID, item.Name, item.ID); return; diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs new file mode 100644 index 0000000000..f848e80816 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -0,0 +1,104 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using Timer=System.Timers.Timer; +using Nini.Config; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; +using OpenSim.Tests.Common.Setup; + +namespace OpenSim.Region.Framework.Tests +{ + [TestFixture] + public class TaskInventoryTests + { + /// + /// Test MoveTaskInventoryItem where the item has no parent folder assigned. + /// + /// This should place it in the most suitable user folder. + [Test] + public void TestMoveTaskInventoryItemNoParent() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene("inventory"); + + // Create user + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); + + // Create scene object + string part1Name = "part1"; + UUID part1Id = UUID.Parse("10000000-0000-0000-0000-000000000000"); + SceneObjectPart part1 + = new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) + { Name = part1Name, UUID = part1Id }; + SceneObjectGroup so = new SceneObjectGroup(part1); + + // Create scene object inventory item + AssetNotecard nc = new AssetNotecard("Hello World!"); + UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); + UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); + AssetBase ncAsset + = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); + scene.AssetService.Store(ncAsset); + TaskInventoryItem ncItem + = new TaskInventoryItem + { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid, + Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard }; + part1.Inventory.AddInventoryItem(ncItem, true); + + // Perform test + scene.MoveTaskInventoryItem(userId, UUID.Zero, part1, ncItemUuid); + + InventoryItemBase ncUserItem + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userId, "Notecards/ncItem"); + Assert.That(ncUserItem, Is.Not.Null, "Notecards/ncItem was not found"); + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs index fbcd6634e7..86bca79d6b 100644 --- a/OpenSim/Services/InventoryService/InventoryService.cs +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -268,15 +268,22 @@ namespace OpenSim.Services.InventoryService public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) { +// m_log.DebugFormat("[INVENTORY SERVICE]: Looking for folder type {0} for user {1}", type, userID); + InventoryFolderBase root = m_Database.getUserRootFolder(userID); if (root != null) { List folders = RequestSubFolders(root.ID); foreach (InventoryFolderBase folder in folders) - { + { if (folder.Type == (short)type) + { +// m_log.DebugFormat( +// "[INVENTORY SERVICE]: Found folder {0} type {1}", folder.Name, (AssetType)folder.Type); + return folder; + } } } diff --git a/OpenSim/Tests/Common/Mock/MockInventoryService.cs b/OpenSim/Tests/Common/Mock/MockInventoryService.cs index 1ea4bc1059..4ac1078795 100644 --- a/OpenSim/Tests/Common/Mock/MockInventoryService.cs +++ b/OpenSim/Tests/Common/Mock/MockInventoryService.cs @@ -37,13 +37,9 @@ namespace OpenSim.Tests.Common.Mock { public class MockInventoryService : IInventoryService { - public MockInventoryService() - { - } + public MockInventoryService() {} - public MockInventoryService(IConfigSource config) - { - } + public MockInventoryService(IConfigSource config) {} /// /// @@ -140,7 +136,7 @@ namespace OpenSim.Tests.Common.Mock public bool AddItem(InventoryItemBase item) { - return false; + return true; } public bool UpdateItem(InventoryItemBase item) @@ -187,4 +183,4 @@ namespace OpenSim.Tests.Common.Mock return 1; } } -} +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index 7c4f689502..ed0b1a6a9a 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs @@ -42,7 +42,7 @@ namespace OpenSim.Tests.Common.Mock /// public class TestInventoryDataPlugin : IInventoryDataPlugin { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Inventory folders @@ -84,14 +84,19 @@ namespace OpenSim.Tests.Common.Mock public List getInventoryInFolder(UUID folderID) { -// m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0}", folderID); + InventoryFolderBase folder = m_folders[folderID]; + + m_log.DebugFormat("[MOCK INV DB]: Getting items in folder {0} {1}", folder.Name, folder.ID); List items = new List(); foreach (InventoryItemBase item in m_items.Values) { if (item.Folder == folderID) + { + m_log.DebugFormat("[MOCK INV DB]: getInventoryInFolder() adding item {0}", item.Name); items.Add(item); + } } return items; @@ -101,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); @@ -111,12 +116,22 @@ namespace OpenSim.Tests.Common.Mock public List getInventoryFolders(UUID parentID) { + InventoryFolderBase parentFolder = m_folders[parentID]; + + m_log.DebugFormat("[MOCK INV DB]: Getting folders in folder {0} {1}", parentFolder.Name, parentFolder.ID); + List folders = new List(); foreach (InventoryFolderBase folder in m_folders.Values) { 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); + folders.Add(folder); + } } return folders; @@ -137,6 +152,10 @@ 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_folders[folder.ID] = folder; if (folder.ParentID == UUID.Zero) @@ -166,8 +185,10 @@ namespace OpenSim.Tests.Common.Mock public void addInventoryItem(InventoryItemBase item) { -// m_log.DebugFormat( -// "[MOCK INV DB]: Adding inventory item {0} {1} in {2}", item.Name, item.ID, item.Folder); + 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_items[item.ID] = item; } diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index eaa0d33b4b..d9ded2d0c4 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -285,10 +285,16 @@ namespace OpenSim.Tests.Common.Setup config.AddConfig("Modules"); config.AddConfig("InventoryService"); config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); + if (real) + { config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); + } else + { config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockInventoryService"); + } + config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); inventoryService.Initialise(config); inventoryService.AddRegion(testScene); From 35f719ae2f9e58cfd46a6c0082238c500a3454f3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 17:04:54 +0100 Subject: [PATCH 10/60] refactor TestMoveTaskInventoryItemNoParent() --- .../Scenes/Tests/TaskInventoryTests.cs | 75 +++++++++++-------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index f848e80816..ed2f324fb9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -44,6 +44,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Services.Interfaces; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Setup; @@ -53,6 +54,42 @@ namespace OpenSim.Region.Framework.Tests [TestFixture] public class TaskInventoryTests { + protected UserAccount CreateUser(Scene scene) + { + string userFirstName = "Jock"; + string userLastName = "Stirrup"; + string userPassword = "troll"; + UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); + return UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); + } + + protected SceneObjectGroup CreateSO1(Scene scene, UUID ownerId) + { + string part1Name = "part1"; + UUID part1Id = UUID.Parse("10000000-0000-0000-0000-000000000000"); + SceneObjectPart part1 + = new SceneObjectPart(ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) + { Name = part1Name, UUID = part1Id }; + return new SceneObjectGroup(part1); + } + + protected TaskInventoryItem CreateSOItem1(Scene scene, SceneObjectPart part) + { + AssetNotecard nc = new AssetNotecard("Hello World!"); + UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); + UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); + AssetBase ncAsset + = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); + scene.AssetService.Store(ncAsset); + TaskInventoryItem ncItem + = new TaskInventoryItem + { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid, + Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard }; + part.Inventory.AddInventoryItem(ncItem, true); + + return ncItem; + } + /// /// Test MoveTaskInventoryItem where the item has no parent folder assigned. /// @@ -64,40 +101,16 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene("inventory"); - - // Create user - string userFirstName = "Jock"; - string userLastName = "Stirrup"; - string userPassword = "troll"; - UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); - - // Create scene object - string part1Name = "part1"; - UUID part1Id = UUID.Parse("10000000-0000-0000-0000-000000000000"); - SceneObjectPart part1 - = new SceneObjectPart(userId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) - { Name = part1Name, UUID = part1Id }; - SceneObjectGroup so = new SceneObjectGroup(part1); - - // Create scene object inventory item - AssetNotecard nc = new AssetNotecard("Hello World!"); - UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); - UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); - AssetBase ncAsset - = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); - scene.AssetService.Store(ncAsset); - TaskInventoryItem ncItem - = new TaskInventoryItem - { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid, - Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard }; - part1.Inventory.AddInventoryItem(ncItem, true); + UserAccount user1 = CreateUser(scene); + SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); + SceneObjectPart sop1 = sog1.RootPart; + TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1); // Perform test - scene.MoveTaskInventoryItem(userId, UUID.Zero, part1, ncItemUuid); - + scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID); + InventoryItemBase ncUserItem - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userId, "Notecards/ncItem"); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Notecards/ncItem"); Assert.That(ncUserItem, Is.Not.Null, "Notecards/ncItem was not found"); } } From 8bb073d99af8aa5873b4adb6e0e985e98d804c62 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 17:06:04 +0100 Subject: [PATCH 11/60] minor: stop test using obsolete property --- OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index fc66c85b84..3e2a2af94b 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs @@ -134,7 +134,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests sop.Text = RandomName(); sop.SitName = RandomName(); sop.TouchName = RandomName(); - sop.ObjectFlags |= (uint)PrimFlags.Phantom; + sop.Flags |= PrimFlags.Phantom; SceneObjectGroup sog = new SceneObjectGroup(sop); scene.AddNewSceneObject(sog, false); From 46d06b6c4c858779472220db88dc64bae4489c38 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 17:10:52 +0100 Subject: [PATCH 12/60] add test to check move of task item to user inventory when a target folder is explicitly given --- .../Scenes/Tests/TaskInventoryTests.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs index ed2f324fb9..da8199ddf4 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs @@ -90,6 +90,32 @@ namespace OpenSim.Region.Framework.Tests return ncItem; } + /// + /// Test MoveTaskInventoryItem where the item has no parent folder assigned. + /// + /// This should place it in the most suitable user folder. + [Test] + public void TestMoveTaskInventoryItem() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + Scene scene = SceneSetupHelpers.SetupScene("inventory"); + UserAccount user1 = CreateUser(scene); + SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); + SceneObjectPart sop1 = sog1.RootPart; + TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1); + InventoryFolderBase folder + = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; + + // Perform test + scene.MoveTaskInventoryItem(user1.PrincipalID, folder.ID, sop1, sopItem1.ItemID); + + InventoryItemBase ncUserItem + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Objects/ncItem"); + Assert.That(ncUserItem, Is.Not.Null, "Objects/ncItem was not found"); + } + /// /// Test MoveTaskInventoryItem where the item has no parent folder assigned. /// From b9e12ed3b7e6f33a824129ce6e79519140a34aa2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:20:24 +0200 Subject: [PATCH 13/60] Add a method to delete left over / dropped attachments --- OpenSim/Region/Framework/Scenes/Scene.cs | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 957c4e8978..d0619d7ff1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5040,5 +5040,37 @@ namespace OpenSim.Region.Framework.Scenes throw new Exception(error); } } + + public void CleanDroppedAttachments() + { + List objectsToDelete = + new List(); + + ForEachSOG(delegate (SceneObjectGroup grp) + { + if (grp.RootPart.Shape.State != 0) + { + UUID agentID = grp.OwnerID; + if (agentID == UUID.Zero) + { + objectsToDelete.Add(grp); + return; + } + + ScenePresence sp = GetScenePresence(agentID); + if (sp == null) + { + objectsToDelete.Add(grp); + return; + } + } + }); + + foreach (SceneObjectGroup grp in objectsToDelete) + { + m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); + DeleteSceneObject(grp, true); + } + } } } From 5a05de0eec5cba9500fd4803e2bf2ffb54d92265 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:38:54 +0200 Subject: [PATCH 14/60] Call attachment cleanup when an agent crosses out --- .../Framework/EntityTransfer/EntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0ba67d3ebf..ee07f30178 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -446,6 +446,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); + sp.Scene.CleanDroppedAttachments(); + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) From 512a13dbe7a8dfa36a662f64caf573f467173b95 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:52:00 +0200 Subject: [PATCH 15/60] Call the Cleanup when an agent logs out, when an agent leaves and just before an agent logs in directly. Intentionally not calling this from MakeRoot as that would mess up attachment transfer in teleport --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d0619d7ff1..6452dfe31b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3199,6 +3199,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); m_log.Debug("[Scene] Finished ClientClosed"); + CleanDroppedAttachments(); } catch (NullReferenceException) { @@ -3442,6 +3443,8 @@ namespace OpenSim.Region.Framework.Scenes if (vialogin) { + CleanDroppedAttachments(); + if (TestBorderCross(agent.startpos, Cardinals.E)) { Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); From 4e324ae3cbf5c4ce16900bd5e57d8671c1de0cfc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 19:07:42 +0200 Subject: [PATCH 16/60] Call the cleanup after saving attachment states, so that the attachments don't get killed before they can be saved --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6452dfe31b..37d797e2ae 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3199,7 +3199,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); m_log.Debug("[Scene] Finished ClientClosed"); - CleanDroppedAttachments(); } catch (NullReferenceException) { @@ -3210,6 +3209,9 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning OnRemovePresence"); m_eventManager.TriggerOnRemovePresence(agentID); m_log.Debug("[Scene] Finished OnRemovePresence"); + + CleanDroppedAttachments(); + ForEachClient( delegate(IClientAPI client) { From a7a45cb22cd0488d89fa6ca53757a21188d6842f Mon Sep 17 00:00:00 2001 From: Marck Date: Tue, 24 Aug 2010 10:33:50 +0200 Subject: [PATCH 17/60] Patch by Apelsin that fixes behaviour of llSetPos and llGetLocalPos for attachments. This fixes Mantis #3923. Signed-off-by: Melanie --- .../Shared/Api/Implementation/LSL_Api.cs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index dc43e453b8..21604d0a45 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1936,7 +1936,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { - if ((targetPos.z < ground) && disable_underground_movement) + if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) targetPos.z = ground; SceneObjectGroup parent = part.ParentGroup; LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); @@ -1968,18 +1968,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected LSL_Vector GetPartLocalPos(SceneObjectPart part) { m_host.AddScriptLPS(1); - if (part.ParentID != 0) - { - return new LSL_Vector(part.OffsetPosition.X, - part.OffsetPosition.Y, - part.OffsetPosition.Z); - } - else + if (part.ParentID == 0) { return new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); } + else + { + if (m_host.IsRoot) + { + return new LSL_Vector(m_host.AttachedPos.X, + m_host.AttachedPos.Y, + m_host.AttachedPos.Z); + } + else + { + return new LSL_Vector(part.OffsetPosition.X, + part.OffsetPosition.Y, + part.OffsetPosition.Z); + } + } } public void llSetRot(LSL_Rotation rot) From 07d5a0779a8330a56fd6ca6d30918de7c8161f98 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 20:53:25 +0100 Subject: [PATCH 18/60] refactor: make RezObject() more readable --- .../Framework/Scenes/Scene.Inventory.cs | 157 +++++++++--------- 1 file changed, 78 insertions(+), 79 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index fa9653f7af..9c62ad392b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1951,7 +1951,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, RezSelected, RemoveItem, fromTaskID, false); } - + /// /// Rez an object into the scene from a prim's inventory. /// @@ -1966,95 +1966,94 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion rot, Vector3 vel, int param) { - // Rez object - if (item != null) + if (null == item) + return null; + + UUID ownerID = item.OwnerID; + AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); + + if (null == rezAsset) + return null; + + string xmlData = Utils.BytesToString(rezAsset.Data); + SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos)) + return null; + + group.ResetIDs(); + + AddNewSceneObject(group, true); + + // we set it's position in world. + group.AbsolutePosition = pos; + + SceneObjectPart rootPart = group.GetChildPart(group.UUID); + + // Since renaming the item in the inventory does not affect the name stored + // in the serialization, transfer the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + + List partList = new List(group.Children.Values); + + group.SetGroup(sourcePart.GroupID, null); + + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { - UUID ownerID = item.OwnerID; - - AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); - - if (rezAsset != null) + if (Permissions.PropagatePermissions()) { - string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos)) - { - return null; - } - group.ResetIDs(); - - AddNewSceneObject(group, true); - - // we set it's position in world. - group.AbsolutePosition = pos; - - SceneObjectPart rootPart = group.GetChildPart(group.UUID); - - // Since renaming the item in the inventory does not affect the name stored - // in the serialization, transfer the correct name from the inventory to the - // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - - List partList = new List(group.Children.Values); - - group.SetGroup(sourcePart.GroupID, null); - - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - if (Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in partList) - { - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } - group.ApplyNextOwnerPermissions(); - } - } - foreach (SceneObjectPart part in partList) { - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.OwnerID; - part.Inventory.ChangeInventoryOwner(item.OwnerID); - } part.EveryoneMask = item.EveryonePermissions; part.NextOwnerMask = item.NextPermissions; } - rootPart.TrimPermissions(); - - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) - { - group.ClearPartAttachmentData(); - } - - group.UpdateGroupRotationR(rot); - - //group.ApplyPhysics(m_physicalPrim); - if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) - { - group.RootPart.ApplyImpulse((vel * group.GetMass()), false); - group.Velocity = vel; - rootPart.ScheduleFullUpdate(); - } - group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); - rootPart.ScheduleFullUpdate(); - - if (!Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - sourcePart.Inventory.RemoveInventoryItem(item.ItemID); - } - return rootPart.ParentGroup; + group.ApplyNextOwnerPermissions(); } } - return null; + foreach (SceneObjectPart part in partList) + { + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.Inventory.ChangeInventoryOwner(item.OwnerID); + } + + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + rootPart.TrimPermissions(); + + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + group.ClearPartAttachmentData(); + } + + group.UpdateGroupRotationR(rot); + + //group.ApplyPhysics(m_physicalPrim); + if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) + { + group.RootPart.ApplyImpulse((vel * group.GetMass()), false); + group.Velocity = vel; + rootPart.ScheduleFullUpdate(); + } + + group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); + rootPart.ScheduleFullUpdate(); + + if (!Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + sourcePart.Inventory.RemoveInventoryItem(item.ItemID); + } + + return rootPart.ParentGroup; } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) From d69e992665495b98fac4ae8c74266294e85804e6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 24 Aug 2010 23:25:19 +0100 Subject: [PATCH 19/60] Split out actual scene object insertion code from Scene.Inventory.RezObject and move into SceneGraph.AddNewSceneObject() The new SceneGraph method is more consumable by region modules that want to extract objects from inventory and add them to the scene in separate stages. This change also reduces the number of redundant client updates scheduled when an object is rezzed directly by a script or region module This code does not touch direct rez by a user --- .../Framework/Scenes/Scene.Inventory.cs | 33 +++++------------ OpenSim/Region/Framework/Scenes/Scene.cs | 18 +++++++++- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 36 +++++++++++++++++++ 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9c62ad392b..01be491573 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1983,11 +1983,6 @@ namespace OpenSim.Region.Framework.Scenes group.ResetIDs(); - AddNewSceneObject(group, true); - - // we set it's position in world. - group.AbsolutePosition = pos; - SceneObjectPart rootPart = group.GetChildPart(group.UUID); // Since renaming the item in the inventory does not affect the name stored @@ -2027,31 +2022,21 @@ namespace OpenSim.Region.Framework.Scenes part.NextOwnerMask = item.NextPermissions; } - rootPart.TrimPermissions(); - - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) - { - group.ClearPartAttachmentData(); - } - - group.UpdateGroupRotationR(rot); - - //group.ApplyPhysics(m_physicalPrim); - if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) - { - group.RootPart.ApplyImpulse((vel * group.GetMass()), false); - group.Velocity = vel; - rootPart.ScheduleFullUpdate(); - } - - group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); - rootPart.ScheduleFullUpdate(); + rootPart.TrimPermissions(); if (!Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) sourcePart.Inventory.RemoveInventoryItem(item.ItemID); } + + AddNewSceneObject(group, true, pos, rot, vel); + + // We can only call this after adding the scene object, since the scene object references the scene + // to find out if scripts should be activated at all. + group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); + + group.ScheduleGroupForFullUpdate(); return rootPart.ParentGroup; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a14762841d..b808c6d74c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -42,7 +42,6 @@ using OpenMetaverse.Imaging; using OpenSim.Framework; using OpenSim.Services.Interfaces; using OpenSim.Framework.Communications; - using OpenSim.Framework.Console; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; @@ -2008,6 +2007,23 @@ namespace OpenSim.Region.Framework.Scenes { return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); } + + /// + /// Add a newly created object to the scene. + /// + /// + /// This method does not send updates to the client - callers need to handle this themselves. + /// + /// + /// Position of the object + /// Rotation of the object + /// Velocity of the object. This parameter only has an effect if the object is physical + /// + public bool AddNewSceneObject( + SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) + { + return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel); + } /// /// Delete every object from the scene. This does not include attachments worn by avatars. diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9f38a999de..31faeec620 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -292,6 +292,42 @@ namespace OpenSim.Region.Framework.Scenes return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } + + /// + /// Add a newly created object to the scene. + /// + /// + /// This method does not send updates to the client - callers need to handle this themselves. + /// + /// + /// Position of the object + /// Rotation of the object + /// Velocity of the object. This parameter only has an effect if the object is physical + /// + public bool AddNewSceneObject( + SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) + { + AddNewSceneObject(sceneObject, true, false); + + // we set it's position in world. + sceneObject.AbsolutePosition = pos; + + if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) + { + sceneObject.ClearPartAttachmentData(); + } + + sceneObject.UpdateGroupRotationR(rot); + + //group.ApplyPhysics(m_physicalPrim); + if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) + { + sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false); + sceneObject.Velocity = vel; + } + + return true; + } /// /// Add an object to the scene. This will both update the scene, and send information about the From a2113ecc71ea29aebb05c2aa676afc7ce05b9563 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 24 Aug 2010 21:01:37 -0700 Subject: [PATCH 20/60] Typo --- bin/Robust.HG.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 122ba2e5f5..554d00f86b 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -100,7 +100,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 [UserAccountService] ; for the server connector LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ; Realm = "usersaccounts" + ; Realm = "useraccounts" ; These are for creating new accounts by the service AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" From 314d1171efd6d45686ad54944e9bf53ec8cd0b7f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 16:06:06 +0200 Subject: [PATCH 21/60] Lock the attachment cleanup so it doesn't go into an endless deletion frenzy --- OpenSim/Region/Framework/Scenes/Scene.cs | 36 +++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 37d797e2ae..2324f7aa3f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -399,6 +399,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_firstHeartbeat = true; private object m_deleting_scene_object = new object(); + private object m_cleaningAttachments = new object(); // the minimum time that must elapse before a changed object will be considered for persisted public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; @@ -5051,26 +5052,29 @@ namespace OpenSim.Region.Framework.Scenes List objectsToDelete = new List(); - ForEachSOG(delegate (SceneObjectGroup grp) - { - if (grp.RootPart.Shape.State != 0) + lock (m_cleaningAttachments) + { + ForEachSOG(delegate (SceneObjectGroup grp) { - UUID agentID = grp.OwnerID; - if (agentID == UUID.Zero) + if (grp.RootPart.Shape.State != 0 || objectsToDelete.Contains(grp)) { - objectsToDelete.Add(grp); - return; - } + UUID agentID = grp.OwnerID; + if (agentID == UUID.Zero) + { + objectsToDelete.Add(grp); + return; + } - ScenePresence sp = GetScenePresence(agentID); - if (sp == null) - { - objectsToDelete.Add(grp); - return; + ScenePresence sp = GetScenePresence(agentID); + if (sp == null) + { + objectsToDelete.Add(grp); + return; + } } - } - }); - + }); + } + foreach (SceneObjectGroup grp in objectsToDelete) { m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); From c13045b25e6424c90642613d400ab6ebf2744064 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 20:11:47 +0200 Subject: [PATCH 22/60] Correct a logic error in attachment cleanup --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2324f7aa3f..c7b38a1df4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5056,7 +5056,7 @@ namespace OpenSim.Region.Framework.Scenes { ForEachSOG(delegate (SceneObjectGroup grp) { - if (grp.RootPart.Shape.State != 0 || objectsToDelete.Contains(grp)) + if (grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) { UUID agentID = grp.OwnerID; if (agentID == UUID.Zero) @@ -5075,10 +5075,15 @@ namespace OpenSim.Region.Framework.Scenes }); } - foreach (SceneObjectGroup grp in objectsToDelete) + if (objectsToDelete.Count > 0) { - m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); - DeleteSceneObject(grp, true); + m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count); + foreach (SceneObjectGroup grp in objectsToDelete) + { + m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); + DeleteSceneObject(grp, true); + } + m_log.Debug("[SCENE]: Finished dropped attachment deletion"); } } } From 1bcb2e788fd895a7d8165797c29e6f2a652eff8b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:04:12 +0200 Subject: [PATCH 23/60] Change some e.Message to e.ToString. Don't use e.Message, it doesn't carry any useful information. Error messages are useless without location information. It looks more elegant, but is totally pointless. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 92a6caa184..e9ae3a3df1 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: {1}", requestUrl, e.Message); + m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); } finally { @@ -112,7 +112,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on receiving reply {0}", e.Message); + m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); } finally { From dc1baf802545329fc78d5fa36174e27025629527 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:11:00 +0200 Subject: [PATCH 24/60] Change object cleanup again. Make scene object directories more robust and prevent deleted SOP's from sticking around --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 46 ++++++++++++------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c7b38a1df4..eb5c3cbcf0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3211,8 +3211,6 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); m_log.Debug("[Scene] Finished OnRemovePresence"); - CleanDroppedAttachments(); - ForEachClient( delegate(IClientAPI client) { @@ -3248,6 +3246,7 @@ namespace OpenSim.Region.Framework.Scenes } m_log.Debug("[Scene] Done. Firing RemoveCircuit"); m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); + CleanDroppedAttachments(); m_log.Debug("[Scene] The avatar has left the building"); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 94ec534f80..1268259341 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByLocalID = new Dictionary(); protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); - private readonly Object m_dictionary_lock = new Object(); private Object m_updateLock = new Object(); @@ -150,11 +149,10 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresencesLock.ExitWriteLock(); } - lock (m_dictionary_lock) - { + lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID.Clear(); + lock (SceneObjectGroupsByLocalID) SceneObjectGroupsByLocalID.Clear(); - } Entities.Clear(); } @@ -385,15 +383,17 @@ namespace OpenSim.Region.Framework.Scenes OnObjectCreate(sceneObject); } - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + } + lock (SceneObjectGroupsByLocalID) + { SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values) - { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } } } @@ -408,24 +408,32 @@ namespace OpenSim.Region.Framework.Scenes { if (Entities.ContainsKey(uuid)) { + SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; + if (!resultOfObjectLinked) { m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; - if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) - { - RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); - } + if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + RemovePhysicalPrim(grp.Children.Count); } if (OnObjectRemove != null) OnObjectRemove(Entities[uuid]); - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { - SceneObjectGroupsByFullID.Remove(uuid); - SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByFullID.Remove(part.UUID); + SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); } + lock (SceneObjectGroupsByLocalID) + { + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByLocalID.Remove(part.LocalId); + SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); + } + Entities.Remove(uuid); //SceneObjectGroup part; //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) @@ -884,7 +892,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) { - return sog; + if (sog.HasChildPrim(localID)) + return sog; + SceneObjectGroupsByLocalID.Remove(localID); } } @@ -920,7 +930,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) { - return sog; + if (sog.Children.ContainsKey(fullID)) + return sog; + SceneObjectGroupsByFullID.Remove(fullID); } } From 1096f43f0d3db628b463d4494c98ad496cf1f039 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:34:39 +0200 Subject: [PATCH 25/60] Prevent an object disposed exception that made forms comms unreliable. After starting an asynchronous write, one should not close the channel it will be written to synchrnously, that leads to grief. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index e9ae3a3df1..f955df7731 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -85,8 +85,13 @@ namespace OpenSim.Framework.Servers.HttpServer } finally { - if (requestStream != null) - requestStream.Close(); + // If this is closed, it will be disposed internally, + // but the above write is asynchronous and may hit after + // we're through here. So the thread handling that will + // throw and put us back into the catch above. Isn't + // .NET great? + //if (requestStream != null) + // requestStream.Close(); // Let's not close this //buffer.Close(); From 46c6c35d4868e4ff538bdc2c65a7fade936c0ce1 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 25 Aug 2010 22:46:49 +0100 Subject: [PATCH 26/60] refactor: Push item retrieval and fixing part of Scene.RezObject() down into SceneObjectPartInventory --- .../Framework/Interfaces/IEntityInventory.cs | 12 ++++ .../Framework/Scenes/Scene.Inventory.cs | 61 ++--------------- .../Scenes/SceneObjectPartInventory.cs | 66 ++++++++++++++++++- 3 files changed, 83 insertions(+), 56 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index fd43923cb3..ae2e8443fc 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.Collections; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { @@ -153,6 +154,17 @@ namespace OpenSim.Region.Framework.Interfaces /// If no inventory item has that name then an empty list is returned. /// IList GetInventoryItems(string name); + + /// + /// Get the scene object referenced by an inventory item. + /// + /// + /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have + /// been adjusted to reflect the part and item from which it originates. + /// + /// + /// The scene object. Null if the scene object asset couldn't be found + SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item); /// /// Update an existing inventory item. diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 01be491573..9fef8f46f1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1969,60 +1969,13 @@ namespace OpenSim.Region.Framework.Scenes if (null == item) return null; - UUID ownerID = item.OwnerID; - AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); - - if (null == rezAsset) - return null; - - string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos)) - return null; - - group.ResetIDs(); - - SceneObjectPart rootPart = group.GetChildPart(group.UUID); - - // Since renaming the item in the inventory does not affect the name stored - // in the serialization, transfer the correct name from the inventory to the - // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - - List partList = new List(group.Children.Values); - - group.SetGroup(sourcePart.GroupID, null); - - if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - if (Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in partList) - { - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } - - group.ApplyNextOwnerPermissions(); - } - } - - foreach (SceneObjectPart part in partList) - { - if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.OwnerID; - part.Inventory.ChangeInventoryOwner(item.OwnerID); - } - - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } + SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); - rootPart.TrimPermissions(); + if (null == group) + return null; + + if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos)) + return null; if (!Permissions.BypassPermissions()) { @@ -2038,7 +1991,7 @@ namespace OpenSim.Region.Framework.Scenes group.ScheduleGroupForFullUpdate(); - return rootPart.ParentGroup; + return group; } public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4ae53a2dd8..84b73658c6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -37,6 +37,7 @@ using log4net; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Scripting; +using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.Framework.Scenes { @@ -574,6 +575,68 @@ namespace OpenSim.Region.Framework.Scenes return items; } + public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) + { + UUID ownerID = item.OwnerID; + AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); + + if (null == rezAsset) + { + m_log.WarnFormat( + "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", + item.AssetID, item.Name, m_part.Name); + return null; + } + + string xmlData = Utils.BytesToString(rezAsset.Data); + SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + group.ResetIDs(); + + SceneObjectPart rootPart = group.GetChildPart(group.UUID); + + // Since renaming the item in the inventory does not affect the name stored + // in the serialization, transfer the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + + List partList = new List(group.Children.Values); + + group.SetGroup(m_part.GroupID, null); + + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) + { + if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart part in partList) + { + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + group.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in partList) + { + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.Inventory.ChangeInventoryOwner(item.OwnerID); + } + + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; + } + + rootPart.TrimPermissions(); + + return group; + } + /// /// Update an existing inventory item. /// @@ -1029,6 +1092,5 @@ namespace OpenSim.Region.Framework.Scenes } } } - } -} +} \ No newline at end of file From 24d06b12c2c361305dfcfd78497abb4bec3e3a38 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 25 Aug 2010 23:05:54 +0100 Subject: [PATCH 27/60] If setting SOG.UUID, update the SOG.m_parts index as well as the root part UUID Being able to change a SOG.UUID is useful for region modules that want to supply their own UUID, before the object is rezzed --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 117f86900b..952d28009f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -335,7 +335,16 @@ namespace OpenSim.Region.Framework.Scenes public override UUID UUID { get { return m_rootPart.UUID; } - set { m_rootPart.UUID = value; } + set + { + m_rootPart.UUID = value; + + lock (m_parts) + { + m_parts.Remove(m_rootPart.UUID); + m_parts.Add(m_rootPart.UUID, m_rootPart); + } + } } public UUID OwnerID From 22fd00b002eab6fba066d76de7de224a01327fcb Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 25 Aug 2010 23:07:43 +0100 Subject: [PATCH 28/60] minor: remove mono compiler warning --- .../Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 5ae64395e7..665b39f6fc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -253,16 +253,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api idx++; } - return values; - } private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) { RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); - LSL_List values = new LSL_List(); +// LSL_List values = new LSL_List(); int idx = 0; while (idx < rules.Length) { From 739eb14741151716bf1325c0d73a95e6ee8c148d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:04:12 +0200 Subject: [PATCH 29/60] Change some e.Message to e.ToString. Don't use e.Message, it doesn't carry any useful information. Error messages are useless without location information. It looks more elegant, but is totally pointless. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index b0cf34d16e..acf725abb2 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: {1}", requestUrl, e.Message); + m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); } finally { @@ -112,7 +112,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on receiving reply {0}", e.Message); + m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); } finally { From 604423d52bb66b1cc08adac557450addc7ebc94b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:11:00 +0200 Subject: [PATCH 30/60] Make scene object directories more robust and prevent deleted SOP's from sticking around --- OpenSim/Region/Framework/Scenes/Scene.cs | 1 - OpenSim/Region/Framework/Scenes/SceneGraph.cs | 46 ++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b808c6d74c..f4cbe1f128 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3159,7 +3159,6 @@ namespace OpenSim.Region.Framework.Scenes } m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); - //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 31faeec620..58a7661ab2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -95,7 +95,6 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByLocalID = new Dictionary(); protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); - private readonly Object m_dictionary_lock = new Object(); private Object m_updateLock = new Object(); @@ -136,11 +135,10 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresenceArray = newlist; } - lock (m_dictionary_lock) - { + lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID.Clear(); + lock (SceneObjectGroupsByLocalID) SceneObjectGroupsByLocalID.Clear(); - } Entities.Clear(); } @@ -395,15 +393,17 @@ namespace OpenSim.Region.Framework.Scenes if (OnObjectCreate != null) OnObjectCreate(sceneObject); - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + } + lock (SceneObjectGroupsByLocalID) + { SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values) - { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } } } @@ -418,24 +418,32 @@ namespace OpenSim.Region.Framework.Scenes { if (Entities.ContainsKey(uuid)) { + SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; + if (!resultOfObjectLinked) { m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; - if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) - { - RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); - } + if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + RemovePhysicalPrim(grp.Children.Count); } if (OnObjectRemove != null) OnObjectRemove(Entities[uuid]); - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { - SceneObjectGroupsByFullID.Remove(uuid); - SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByFullID.Remove(part.UUID); + SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); } + lock (SceneObjectGroupsByLocalID) + { + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByLocalID.Remove(part.LocalId); + SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); + } + Entities.Remove(uuid); //SceneObjectGroup part; //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) @@ -860,7 +868,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) { - return sog; + if (sog.HasChildPrim(localID)) + return sog; + SceneObjectGroupsByLocalID.Remove(localID); } } @@ -896,7 +906,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) { - return sog; + if (sog.Children.ContainsKey(fullID)) + return sog; + SceneObjectGroupsByFullID.Remove(fullID); } } From 75e2a2b3ceeb67d3124bc8b4534b6927d288fd57 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:34:39 +0200 Subject: [PATCH 31/60] Prevent an object disposed exception that made forms comms unreliable. After starting an asynchronous write, one should not close the channel it will be written to synchrnously, that leads to grief. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index acf725abb2..b2c1c54954 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -85,8 +85,13 @@ namespace OpenSim.Framework.Servers.HttpServer } finally { - if (requestStream != null) - requestStream.Close(); + // If this is closed, it will be disposed internally, + // but the above write is asynchronous and may hit after + // we're through here. So the thread handling that will + // throw and put us back into the catch above. Isn't + // .NET great? + //if (requestStream != null) + // requestStream.Close(); // Let's not close this //buffer.Close(); From 4b47008d30a42bd836ab3efeb399beb672a2446d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 26 Aug 2010 00:37:54 +0200 Subject: [PATCH 32/60] Correct whitespace --- .../Shared/Api/Implementation/LS_Api.cs | 510 ------------------ 1 file changed, 510 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 91e2c3b32f..665b39f6fc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -1,512 +1,3 @@ -<<<<<<< HEAD:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Remoting.Lifetime; -using OpenMetaverse; -using Nini.Config; -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.World.LightShare; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.ScriptEngine.Shared; -using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; -using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; - -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; - -namespace OpenSim.Region.ScriptEngine.Shared.Api -{ - [Serializable] - public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi - { - internal IScriptEngine m_ScriptEngine; - internal SceneObjectPart m_host; - internal uint m_localID; - internal UUID m_itemID; - internal bool m_LSFunctionsEnabled = false; - internal IScriptModuleComms m_comms = null; - - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) - { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_localID = localID; - m_itemID = itemID; - - if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) - m_LSFunctionsEnabled = true; - - if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) - m_LSFunctionsEnabled = true; - - m_comms = m_ScriptEngine.World.RequestModuleInterface(); - if (m_comms == null) - m_LSFunctionsEnabled = false; - } - - public override Object InitializeLifetimeService() - { - ILease lease = (ILease)base.InitializeLifetimeService(); - - if (lease.CurrentState == LeaseState.Initial) - { - lease.InitialLeaseTime = TimeSpan.FromMinutes(0); - // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); - // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); - } - return lease; - } - - public Scene World - { - get { return m_ScriptEngine.World; } - } - - // - //Dumps an error message on the debug console. - // - - internal void LSShoutError(string message) - { - if (message.Length > 1023) - message = message.Substring(0, 1023); - - World.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); - - IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); - wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); - } - - /// - /// Get the current Windlight scene - /// - /// List of windlight parameters - public LSL_List lsGetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return new LSL_List(); - } - m_host.AddScriptLPS(1); - RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_List toadd = new LSL_List(); - - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - toadd.Add(new LSL_Float(wl.blurMultiplier)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - toadd.Add(new LSL_Float(wl.cloudCoverage)); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - toadd.Add(new LSL_Float(wl.cloudScale)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - toadd.Add(new LSL_Float(wl.cloudScrollX)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - toadd.Add(new LSL_Float(wl.cloudScrollY)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - toadd.Add(new LSL_Float(wl.densityMultiplier)); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - toadd.Add(new LSL_Float(wl.distanceMultiplier)); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - toadd.Add(new LSL_Float(wl.eastAngle)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - toadd.Add(new LSL_Float(wl.fresnelOffset)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - toadd.Add(new LSL_Float(wl.fresnelScale)); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - toadd.Add(new LSL_Float(wl.hazeDensity)); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - toadd.Add(new LSL_Float(wl.hazeHorizon)); - break; - case (int)ScriptBaseClass.WL_HORIZON: - toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - toadd.Add(new LSL_Integer(wl.maxAltitude)); - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - toadd.Add(new LSL_Float(wl.refractScaleAbove)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - toadd.Add(new LSL_Float(wl.refractScaleBelow)); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - toadd.Add(new LSL_Float(wl.sceneGamma)); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - toadd.Add(new LSL_Float(wl.starBrightness)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - toadd.Add(new LSL_Float(wl.sunGlowFocus)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - toadd.Add(new LSL_Float(wl.sunGlowSize)); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - toadd.Add(new LSL_Float(wl.underwaterFogModifier)); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); - break; - } - - if (toadd.Length > 0) - { - values.Add(new LSL_Integer(rule)); - values.Add(toadd.Data[0]); - } - idx++; - } - - - return values; - - } - - private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) - { - RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - } - idx++; - } - return wl; - } - /// - /// Set the current Windlight scene - /// - /// - /// success: true or false - public int lsSetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - - } -} -======= /* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. @@ -1009,4 +500,3 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } ->>>>>>> master:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs From 47818a2db303eefaf59f7c98d03112bfb1371379 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 26 Aug 2010 01:06:50 +0200 Subject: [PATCH 33/60] Fix a horrible bug in SG, where iteration of scene objects is carried out in a fashion that causes the delegate to be invoked once per child prim for a given group. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9c5ee60549..1d952c495c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1140,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void ForEachSOG(Action action) { - List objlist = new List(SceneObjectGroupsByFullID.Values); - foreach (SceneObjectGroup obj in objlist) + List objlist = Entities.GetAllByType(); + foreach (EntityBase ent in objlist) { + SceneObjectGroup obj = (SceneObjectGroup)ent; + try { action(obj); From 8031f8ec09df4f654c86a9c7bc498664f7b9d9dc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 00:08:53 +0100 Subject: [PATCH 34/60] Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 104 ++-- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 210 +++---- OpenSim/Data/SQLite/SQLiteRegionData.cs | 9 +- OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs | 9 +- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- .../InventoryAccess/InventoryAccessModule.cs | 6 +- .../World/Archiver/ArchiveReadRequest.cs | 55 +- .../World/Objects/BuySell/BuySellModule.cs | 5 +- .../World/WorldMap/MapImageModule.cs | 514 +++++++++--------- .../Framework/Scenes/Scene.Inventory.cs | 21 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 38 +- OpenSim/Region/Framework/Scenes/Scene.cs | 35 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 111 ++-- .../Framework/Scenes/SceneObjectGroup.cs | 131 +++-- .../Scenes/SceneObjectPartInventory.cs | 5 +- .../CMEntityCollection.cs | 19 +- .../ContentManagementSystem/CMModel.cs | 35 +- .../ContentManagementSystem/CMView.cs | 9 +- .../ContentManagementEntity.cs | 173 +++--- .../ContentManagementSystem/MetaEntity.cs | 38 +- .../Scripting/Minimodule/SOPObject.cs | 19 +- .../Shared/Api/Implementation/LSL_Api.cs | 100 ++-- OpenSim/Region/ScriptEngine/Shared/Helpers.cs | 11 +- 23 files changed, 912 insertions(+), 747 deletions(-) diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index 7d017a6e17..4ce93e55c8 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -232,66 +232,68 @@ namespace OpenSim.Data.MSSQL /// public void StoreObject(SceneObjectGroup obj, UUID regionUUID) { - _Log.InfoFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); - - using (SqlConnection conn = new SqlConnection(m_connectionString)) + lock (obj.Children) { - conn.Open(); - SqlTransaction transaction = conn.BeginTransaction(); - - try + _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + + using (SqlConnection conn = new SqlConnection(m_connectionString)) { - foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) - { - //Update prim - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - - //Update primshapes - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - } - - transaction.Commit(); - } - catch (Exception ex) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); + conn.Open(); + SqlTransaction transaction = conn.BeginTransaction(); + try { - transaction.Rollback(); + foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) + { + //Update prim + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + + //Update primshapes + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + } + + transaction.Commit(); } - catch (Exception ex2) + catch (Exception ex) { - //Show error - _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); - + _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); + try + { + transaction.Rollback(); + } + catch (Exception ex2) + { + //Show error + _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); + + } } } } - } /// diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 1edcb5d499..b756b4fe07 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -135,111 +135,115 @@ namespace OpenSim.Data.MySQL dbcon.Open(); MySqlCommand cmd = dbcon.CreateCommand(); - foreach (SceneObjectPart prim in obj.Children.Values) + lock (obj.Children) { - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into prims (" + - "UUID, CreationDate, " + - "Name, Text, Description, " + - "SitName, TouchName, ObjectFlags, " + - "OwnerMask, NextOwnerMask, GroupMask, " + - "EveryoneMask, BaseMask, PositionX, " + - "PositionY, PositionZ, GroupPositionX, " + - "GroupPositionY, GroupPositionZ, VelocityX, " + - "VelocityY, VelocityZ, AngularVelocityX, " + - "AngularVelocityY, AngularVelocityZ, " + - "AccelerationX, AccelerationY, " + - "AccelerationZ, RotationX, " + - "RotationY, RotationZ, " + - "RotationW, SitTargetOffsetX, " + - "SitTargetOffsetY, SitTargetOffsetZ, " + - "SitTargetOrientW, SitTargetOrientX, " + - "SitTargetOrientY, SitTargetOrientZ, " + - "RegionUUID, CreatorID, " + - "OwnerID, GroupID, " + - "LastOwnerID, SceneGroupID, " + - "PayPrice, PayButton1, " + - "PayButton2, PayButton3, " + - "PayButton4, LoopedSound, " + - "LoopedSoundGain, TextureAnimation, " + - "OmegaX, OmegaY, OmegaZ, " + - "CameraEyeOffsetX, CameraEyeOffsetY, " + - "CameraEyeOffsetZ, CameraAtOffsetX, " + - "CameraAtOffsetY, CameraAtOffsetZ, " + - "ForceMouselook, ScriptAccessPin, " + - "AllowedDrop, DieAtEdge, " + - "SalePrice, SaleType, " + - "ColorR, ColorG, ColorB, ColorA, " + - "ParticleSystem, ClickAction, Material, " + - "CollisionSound, CollisionSoundVolume, " + - "PassTouches, " + - "LinkNumber, MediaURL) values (" + "?UUID, " + - "?CreationDate, ?Name, ?Text, " + - "?Description, ?SitName, ?TouchName, " + - "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + - "?GroupMask, ?EveryoneMask, ?BaseMask, " + - "?PositionX, ?PositionY, ?PositionZ, " + - "?GroupPositionX, ?GroupPositionY, " + - "?GroupPositionZ, ?VelocityX, " + - "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + - "?AngularVelocityY, ?AngularVelocityZ, " + - "?AccelerationX, ?AccelerationY, " + - "?AccelerationZ, ?RotationX, " + - "?RotationY, ?RotationZ, " + - "?RotationW, ?SitTargetOffsetX, " + - "?SitTargetOffsetY, ?SitTargetOffsetZ, " + - "?SitTargetOrientW, ?SitTargetOrientX, " + - "?SitTargetOrientY, ?SitTargetOrientZ, " + - "?RegionUUID, ?CreatorID, ?OwnerID, " + - "?GroupID, ?LastOwnerID, ?SceneGroupID, " + - "?PayPrice, ?PayButton1, ?PayButton2, " + - "?PayButton3, ?PayButton4, ?LoopedSound, " + - "?LoopedSoundGain, ?TextureAnimation, " + - "?OmegaX, ?OmegaY, ?OmegaZ, " + - "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + - "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + - "?CameraAtOffsetY, ?CameraAtOffsetZ, " + - "?ForceMouselook, ?ScriptAccessPin, " + - "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + - "?SaleType, ?ColorR, ?ColorG, " + - "?ColorB, ?ColorA, ?ParticleSystem, " + - "?ClickAction, ?Material, ?CollisionSound, " + - "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; - - FillPrimCommand(cmd, prim, obj.UUID, regionUUID); - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into primshapes (" + - "UUID, Shape, ScaleX, ScaleY, " + - "ScaleZ, PCode, PathBegin, PathEnd, " + - "PathScaleX, PathScaleY, PathShearX, " + - "PathShearY, PathSkew, PathCurve, " + - "PathRadiusOffset, PathRevolutions, " + - "PathTaperX, PathTaperY, PathTwist, " + - "PathTwistBegin, ProfileBegin, ProfileEnd, " + - "ProfileCurve, ProfileHollow, Texture, " + - "ExtraParams, State, Media) values (?UUID, " + - "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + - "?PCode, ?PathBegin, ?PathEnd, " + - "?PathScaleX, ?PathScaleY, " + - "?PathShearX, ?PathShearY, " + - "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + - "?PathRevolutions, ?PathTaperX, " + - "?PathTaperY, ?PathTwist, " + - "?PathTwistBegin, ?ProfileBegin, " + - "?ProfileEnd, ?ProfileCurve, " + - "?ProfileHollow, ?Texture, ?ExtraParams, " + - "?State, ?Media)"; - - FillShapeCommand(cmd, prim); - - ExecuteNonQuery(cmd); + foreach (SceneObjectPart prim in obj.Children.Values) + { + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into prims (" + + "UUID, CreationDate, " + + "Name, Text, Description, " + + "SitName, TouchName, ObjectFlags, " + + "OwnerMask, NextOwnerMask, GroupMask, " + + "EveryoneMask, BaseMask, PositionX, " + + "PositionY, PositionZ, GroupPositionX, " + + "GroupPositionY, GroupPositionZ, VelocityX, " + + "VelocityY, VelocityZ, AngularVelocityX, " + + "AngularVelocityY, AngularVelocityZ, " + + "AccelerationX, AccelerationY, " + + "AccelerationZ, RotationX, " + + "RotationY, RotationZ, " + + "RotationW, SitTargetOffsetX, " + + "SitTargetOffsetY, SitTargetOffsetZ, " + + "SitTargetOrientW, SitTargetOrientX, " + + "SitTargetOrientY, SitTargetOrientZ, " + + "RegionUUID, CreatorID, " + + "OwnerID, GroupID, " + + "LastOwnerID, SceneGroupID, " + + "PayPrice, PayButton1, " + + "PayButton2, PayButton3, " + + "PayButton4, LoopedSound, " + + "LoopedSoundGain, TextureAnimation, " + + "OmegaX, OmegaY, OmegaZ, " + + "CameraEyeOffsetX, CameraEyeOffsetY, " + + "CameraEyeOffsetZ, CameraAtOffsetX, " + + "CameraAtOffsetY, CameraAtOffsetZ, " + + "ForceMouselook, ScriptAccessPin, " + + "AllowedDrop, DieAtEdge, " + + "SalePrice, SaleType, " + + "ColorR, ColorG, ColorB, ColorA, " + + "ParticleSystem, ClickAction, Material, " + + "CollisionSound, CollisionSoundVolume, " + + "PassTouches, " + + "LinkNumber, MediaURL) values (" + "?UUID, " + + "?CreationDate, ?Name, ?Text, " + + "?Description, ?SitName, ?TouchName, " + + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + + "?GroupMask, ?EveryoneMask, ?BaseMask, " + + "?PositionX, ?PositionY, ?PositionZ, " + + "?GroupPositionX, ?GroupPositionY, " + + "?GroupPositionZ, ?VelocityX, " + + "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + + "?AngularVelocityY, ?AngularVelocityZ, " + + "?AccelerationX, ?AccelerationY, " + + "?AccelerationZ, ?RotationX, " + + "?RotationY, ?RotationZ, " + + "?RotationW, ?SitTargetOffsetX, " + + "?SitTargetOffsetY, ?SitTargetOffsetZ, " + + "?SitTargetOrientW, ?SitTargetOrientX, " + + "?SitTargetOrientY, ?SitTargetOrientZ, " + + "?RegionUUID, ?CreatorID, ?OwnerID, " + + "?GroupID, ?LastOwnerID, ?SceneGroupID, " + + "?PayPrice, ?PayButton1, ?PayButton2, " + + "?PayButton3, ?PayButton4, ?LoopedSound, " + + "?LoopedSoundGain, ?TextureAnimation, " + + "?OmegaX, ?OmegaY, ?OmegaZ, " + + "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + + "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + + "?CameraAtOffsetY, ?CameraAtOffsetZ, " + + "?ForceMouselook, ?ScriptAccessPin, " + + "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + + "?SaleType, ?ColorR, ?ColorG, " + + "?ColorB, ?ColorA, ?ParticleSystem, " + + "?ClickAction, ?Material, ?CollisionSound, " + + "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; + + FillPrimCommand(cmd, prim, obj.UUID, regionUUID); + + ExecuteNonQuery(cmd); + + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into primshapes (" + + "UUID, Shape, ScaleX, ScaleY, " + + "ScaleZ, PCode, PathBegin, PathEnd, " + + "PathScaleX, PathScaleY, PathShearX, " + + "PathShearY, PathSkew, PathCurve, " + + "PathRadiusOffset, PathRevolutions, " + + "PathTaperX, PathTaperY, PathTwist, " + + "PathTwistBegin, ProfileBegin, ProfileEnd, " + + "ProfileCurve, ProfileHollow, Texture, " + + "ExtraParams, State, Media) values (?UUID, " + + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + + "?PCode, ?PathBegin, ?PathEnd, " + + "?PathScaleX, ?PathScaleY, " + + "?PathShearX, ?PathShearY, " + + "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + + "?PathRevolutions, ?PathTaperX, " + + "?PathTaperY, ?PathTwist, " + + "?PathTwistBegin, ?ProfileBegin, " + + "?ProfileEnd, ?ProfileCurve, " + + "?ProfileHollow, ?Texture, ?ExtraParams, " + + "?State, ?Media)"; + + FillShapeCommand(cmd, prim); + + ExecuteNonQuery(cmd); + } + + cmd.Dispose(); } - cmd.Dispose(); } } } diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 4208050ab9..bfd8279f7b 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -360,10 +360,13 @@ namespace OpenSim.Data.SQLite lock (ds) { - foreach (SceneObjectPart prim in obj.Children.Values) + lock (obj.Children) { -// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); + foreach (SceneObjectPart prim in obj.Children.Values) + { + // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, obj.UUID, regionUUID); + } } } diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs index 289fd948ce..779b2ed331 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs @@ -327,10 +327,13 @@ namespace OpenSim.Data.SQLiteLegacy lock (ds) { - foreach (SceneObjectPart prim in obj.Children.Values) + lock (obj.Children) { -// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); + foreach (SceneObjectPart prim in obj.Children.Values) + { + // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, obj.UUID, regionUUID); + } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 365cdbb16e..847a9991a8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -406,7 +406,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { if (!m_scene.Permissions.CanRezObject( - part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition)) + part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) return; presence.Appearance.DetachAttachment(itemID); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index eef0c731af..6decf54aa9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.RootPart.CreateSelected = true; if (!m_Scene.Permissions.CanRezObject( - group.Children.Count, remoteClient.AgentId, pos) + group.PrimCount, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will @@ -594,7 +594,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess rootPart.Name = item.Name; rootPart.Description = item.Description; - List partList = new List(group.Children.Values); + List partList = null; + lock (group.Children) + partList = new List(group.Children.Values); group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index bc653ce5e9..1623e6e3c2 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -243,36 +243,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver // to the same scene (when this is possible). sceneObject.ResetIDs(); - foreach (SceneObjectPart part in sceneObject.Children.Values) + lock (sceneObject.Children) { - 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) + foreach (SceneObjectPart part in sceneObject.Children.Values) { - TaskInventoryDictionary inv = part.TaskInventory; - foreach (KeyValuePair kvp in inv) + 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(kvp.Value.OwnerID)) + TaskInventoryDictionary inv = part.TaskInventory; + foreach (KeyValuePair kvp in inv) { - kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; - } - if (!ResolveUserUuid(kvp.Value.CreatorID)) - { - kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; + if (!ResolveUserUuid(kvp.Value.OwnerID)) + { + kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; + } + if (!ResolveUserUuid(kvp.Value.CreatorID)) + { + kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; + } } } } diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 62abd4cfaf..8ce6dafc95 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -128,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); - List partList = new List(group.Children.Values); + List partList = null; + + lock (group.Children) + partList = new List(group.Children.Values); if (m_scene.Permissions.PropagatePermissions()) { diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index b96d95a09c..2f70c0a267 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs @@ -227,277 +227,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 - foreach (SceneObjectPart part in mapdot.Children.Values) + lock (mapdot.Children) { - 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) + foreach (SceneObjectPart part in mapdot.Children.Values) { - // Try to get the RGBA of the default texture entry.. - // - try + 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) { - // 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 get the RGBA of the default texture entry.. + // + try { - //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) + // 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) + { + } } } - } - 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; - -#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++) + catch (IndexOutOfRangeException) { - 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; + // Windows Array } - - 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++) + 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; + + #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++) //{ - //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); - //try + //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) //{ - // Remember, flip the y! - // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); + //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; //} - //catch (ArgumentException) - //{ - // breakYN = true; - //} - + //if (breakYN) // break; //} - - //if (breakYN) - // break; - //} - } // Object is within 256m Z of terrain - } // object is at least a meter wide + } // Object is within 256m Z of terrain + } // object is at least a meter wide + } // mapdot.Children lock } // loop over group children } // entitybase is sceneobject group } // foreach loop over entities diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9fef8f46f1..379128a2fc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1974,7 +1974,7 @@ namespace OpenSim.Region.Framework.Scenes if (null == group) return null; - if (!Permissions.CanRezObject(group.Children.Count, item.OwnerID, pos)) + if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) return null; if (!Permissions.BypassPermissions()) @@ -2051,8 +2051,11 @@ namespace OpenSim.Region.Framework.Scenes sog.SetGroup(groupID, remoteClient); sog.ScheduleGroupForFullUpdate(); - foreach (SceneObjectPart child in sog.Children.Values) - child.Inventory.ChangeInventoryOwner(ownerID); + lock (sog.Children) + { + foreach (SceneObjectPart child in sog.Children.Values) + child.Inventory.ChangeInventoryOwner(ownerID); + } } else { @@ -2062,16 +2065,18 @@ namespace OpenSim.Region.Framework.Scenes if (sog.GroupID != groupID) continue; - foreach (SceneObjectPart child in sog.Children.Values) + lock (sog.Children) { - child.LastOwnerID = child.OwnerID; - child.Inventory.ChangeInventoryOwner(groupID); + foreach (SceneObjectPart child in sog.Children.Values) + { + child.LastOwnerID = child.OwnerID; + child.Inventory.ChangeInventoryOwner(groupID); + } } sog.SetOwnerId(groupID); sog.ApplyNextOwnerPermissions(); - } - + } } foreach (uint localID in localIDs) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e25b1f1503..9f1575dad1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -156,21 +156,29 @@ namespace OpenSim.Region.Framework.Scenes } break; } - else - { - // We also need to check the children of this prim as they - // can be selected as well and send property information - bool foundPrim = false; - foreach (KeyValuePair child in ((SceneObjectGroup) ent).Children) - { - if (child.Value.LocalId == primLocalID) - { - child.Value.GetProperties(remoteClient); - foundPrim = true; - break; - } - } - if (foundPrim) break; + else + { + // We also need to check the children of this prim as they + // can be selected as well and send property information + bool foundPrim = false; + + SceneObjectGroup sog = ent as SceneObjectGroup; + + lock (sog.Children) + { + foreach (KeyValuePair child in (sog.Children)) + { + if (child.Value.LocalId == primLocalID) + { + child.Value.GetProperties(remoteClient); + foundPrim = true; + break; + } + } + } + + if (foundPrim) + break; } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b808c6d74c..855610547a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1756,8 +1756,9 @@ namespace OpenSim.Region.Framework.Scenes if (group.RootPart == null) { - m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", - group.Children == null ? 0 : group.Children.Count); + m_log.ErrorFormat( + "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", + group.Children == null ? 0 : group.PrimCount); } AddRestoredSceneObject(group, true, true); @@ -2064,18 +2065,22 @@ namespace OpenSim.Region.Framework.Scenes group.RemoveScriptInstances(true); } - foreach (SceneObjectPart part in group.Children.Values) + lock (group.Children) { - if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) + foreach (SceneObjectPart part in group.Children.Values) { - PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? - } - else if (part.PhysActor != null) - { - PhysicsScene.RemovePrim(part.PhysActor); - part.PhysActor = null; + 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; + } } } + // if (rootPart.PhysActor != null) // { // PhysicsScene.RemovePrim(rootPart.PhysActor); @@ -2426,14 +2431,16 @@ namespace OpenSim.Region.Framework.Scenes // Force allocation of new LocalId // - foreach (SceneObjectPart p in sceneObject.Children.Values) - p.LocalId = 0; + lock (sceneObject.Children) + { + foreach (SceneObjectPart p in sceneObject.Children.Values) + p.LocalId = 0; + } if (sceneObject.IsAttachmentCheckFull()) // Attachment { sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); - // Don't sent a full update here because this will cause full updates to be sent twice for // attachments on region crossings, resulting in viewer glitches. @@ -2447,7 +2454,6 @@ namespace OpenSim.Region.Framework.Scenes if (sp != null) { - SceneObjectGroup grp = sceneObject; m_log.DebugFormat( @@ -2459,7 +2465,6 @@ namespace OpenSim.Region.Framework.Scenes if (AttachmentsModule != null) AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); - } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 31faeec620..2b247065f6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -364,45 +364,48 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); - if (m_parentScene.m_clampPrimSize) + lock (sceneObject.Children) { - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (m_parentScene.m_clampPrimSize) { - Vector3 scale = part.Shape.Scale; - - if (scale.X > m_parentScene.m_maxNonphys) - scale.X = m_parentScene.m_maxNonphys; - if (scale.Y > m_parentScene.m_maxNonphys) - scale.Y = m_parentScene.m_maxNonphys; - if (scale.Z > m_parentScene.m_maxNonphys) - scale.Z = m_parentScene.m_maxNonphys; - - part.Shape.Scale = scale; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + Vector3 scale = part.Shape.Scale; + + if (scale.X > m_parentScene.m_maxNonphys) + scale.X = m_parentScene.m_maxNonphys; + if (scale.Y > m_parentScene.m_maxNonphys) + scale.Y = m_parentScene.m_maxNonphys; + if (scale.Z > m_parentScene.m_maxNonphys) + scale.Z = m_parentScene.m_maxNonphys; + + part.Shape.Scale = scale; + } } - } + + sceneObject.AttachToScene(m_parentScene); + + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + + Entities.Add(sceneObject); + m_numPrim += sceneObject.Children.Count; - sceneObject.AttachToScene(m_parentScene); + if (attachToBackup) + sceneObject.AttachToBackup(); - if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); - - Entities.Add(sceneObject); - m_numPrim += sceneObject.Children.Count; - - if (attachToBackup) - sceneObject.AttachToBackup(); - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - lock (m_dictionary_lock) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (m_dictionary_lock) { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } } } } @@ -420,11 +423,16 @@ namespace OpenSim.Region.Framework.Scenes { if (!resultOfObjectLinked) { - m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; - - if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + SceneObjectGroup sog = Entities[uuid] as SceneObjectGroup; + + lock (sog.Children) { - RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); + m_numPrim -= sog.PrimCount; + + if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + { + RemovePhysicalPrim(sog.PrimCount); + } } } @@ -1603,7 +1611,7 @@ namespace OpenSim.Region.Framework.Scenes { if (part != null) { - if (part.ParentGroup.Children.Count != 1) // Skip single + if (part.ParentGroup.PrimCount != 1) // Skip single { if (part.LinkNum < 2) // Root rootParts.Add(part); @@ -1631,8 +1639,15 @@ namespace OpenSim.Region.Framework.Scenes // However, editing linked parts and unlinking may be different // SceneObjectGroup group = root.ParentGroup; - List newSet = new List(group.Children.Values); - int numChildren = group.Children.Count; + + List newSet = null; + int numChildren = -1; + + lock (group.Children) + { + newSet = new List(group.Children.Values); + numChildren = group.PrimCount; + } // If there are prims left in a link set, but the root is // slated for unlink, we need to do this @@ -1711,12 +1726,17 @@ namespace OpenSim.Region.Framework.Scenes { if (ent is SceneObjectGroup) { - foreach (KeyValuePair subent in ((SceneObjectGroup)ent).Children) + SceneObjectGroup sog = ent as SceneObjectGroup; + + lock (sog.Children) { - if (subent.Value.LocalId == localID) + foreach (KeyValuePair subent in sog.Children) { - objid = subent.Key; - obj = subent.Value; + if (subent.Value.LocalId == localID) + { + objid = subent.Key; + obj = subent.Value; + } } } } @@ -1781,7 +1801,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup original = GetGroupByPrim(originalPrimID); if (original != null) { - if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) + if (m_parentScene.Permissions.CanDuplicateObject( + original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) { SceneObjectGroup copy = original.Copy(true); copy.AbsolutePosition = copy.AbsolutePosition + offset; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 952d28009f..5ee8d7390e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes /// public int PrimCount { - get { return m_parts.Count; } + get { lock (m_parts) { return m_parts.Count; } } } protected Quaternion m_rotation = Quaternion.Identity; @@ -237,6 +237,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// The parts of this scene object group. You must lock this property before using it. + /// If you want to know the number of children, consider using the PrimCount property instead /// public Dictionary Children { @@ -298,6 +299,7 @@ namespace OpenSim.Region.Framework.Scenes { m_scene.CrossPrimGroupIntoNewRegion(val, this, true); } + if (RootPart.GetStatusSandbox()) { if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) @@ -308,6 +310,7 @@ namespace OpenSim.Region.Framework.Scenes return; } } + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -558,21 +561,23 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.LocalId == 0) m_rootPart.LocalId = m_scene.AllocateLocalId(); - // No need to lock here since the object isn't yet in a scene - foreach (SceneObjectPart part in m_parts.Values) + lock (m_parts) { - if (Object.ReferenceEquals(part, m_rootPart)) + foreach (SceneObjectPart part in m_parts.Values) { - continue; + if (Object.ReferenceEquals(part, m_rootPart)) + { + continue; + } + + if (part.LocalId == 0) + { + part.LocalId = m_scene.AllocateLocalId(); + } + + part.ParentID = m_rootPart.LocalId; + //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); } - - if (part.LocalId == 0) - { - part.LocalId = m_scene.AllocateLocalId(); - } - - part.ParentID = m_rootPart.LocalId; - //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); } ApplyPhysics(m_scene.m_physicalPrim); @@ -670,7 +675,7 @@ namespace OpenSim.Region.Framework.Scenes minY = 256f; minZ = 8192f; - lock(m_parts); + lock(m_parts) { foreach (SceneObjectPart part in m_parts.Values) { @@ -995,9 +1000,12 @@ namespace OpenSim.Region.Framework.Scenes m_rootPart.AttachedAvatar = agentID; //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + lock (m_parts) { - p.AttachedAvatar = agentID; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = agentID; + } } if (m_rootPart.PhysActor != null) @@ -1065,10 +1073,14 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = detachedpos; m_rootPart.AttachedAvatar = UUID.Zero; - //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + + //Anakin Lohner bug #3839 + lock (m_parts) { - p.AttachedAvatar = UUID.Zero; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = UUID.Zero; + } } m_rootPart.SetParentLocalId(0); @@ -1094,10 +1106,14 @@ namespace OpenSim.Region.Framework.Scenes } m_rootPart.AttachedAvatar = UUID.Zero; + //Anakin Lohner bug #3839 - foreach (SceneObjectPart p in m_parts.Values) + lock (m_parts) { - p.AttachedAvatar = UUID.Zero; + foreach (SceneObjectPart p in m_parts.Values) + { + p.AttachedAvatar = UUID.Zero; + } } m_rootPart.SetParentLocalId(0); @@ -1160,9 +1176,8 @@ namespace OpenSim.Region.Framework.Scenes part.ParentID = 0; part.LinkNum = 0; - // No locking required since the SOG should not be in the scene yet - one can't change root parts after - // the scene object has been attached to the scene - m_parts.Add(m_rootPart.UUID, m_rootPart); + lock (m_parts) + m_parts.Add(m_rootPart.UUID, m_rootPart); } /// @@ -1625,7 +1640,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// + /// Copy the given part as the root part of this scene object. /// /// /// @@ -1882,11 +1897,12 @@ namespace OpenSim.Region.Framework.Scenes /// public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); - newPart.SetParent(this); - + SceneObjectPart newPart = null; + lock (m_parts) - { + { + newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); + newPart.SetParent(this); m_parts.Add(newPart.UUID, newPart); } @@ -1903,14 +1919,15 @@ namespace OpenSim.Region.Framework.Scenes /// public void ResetIDs() { - // As this is only ever called for prims which are not currently part of the scene (and hence - // not accessible by clients), there should be no need to lock - List partsList = new List(m_parts.Values); - m_parts.Clear(); - foreach (SceneObjectPart part in partsList) + lock (m_parts) { - part.ResetIDs(part.LinkNum); // Don't change link nums - m_parts.Add(part.UUID, part); + List partsList = new List(m_parts.Values); + m_parts.Clear(); + foreach (SceneObjectPart part in partsList) + { + part.ResetIDs(part.LinkNum); // Don't change link nums + m_parts.Add(part.UUID, part); + } } } @@ -2136,10 +2153,15 @@ namespace OpenSim.Region.Framework.Scenes public SceneObjectPart GetChildPart(UUID primID) { SceneObjectPart childPart = null; - if (m_parts.ContainsKey(primID)) + + lock (m_parts) { - childPart = m_parts[primID]; + if (m_parts.ContainsKey(primID)) + { + childPart = m_parts[primID]; + } } + return childPart; } @@ -2174,9 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes /// public bool HasChildPrim(UUID primID) { - if (m_parts.ContainsKey(primID)) + lock (m_parts) { - return true; + if (m_parts.ContainsKey(primID)) + return true; } return false; @@ -2370,17 +2393,19 @@ namespace OpenSim.Region.Framework.Scenes lock (m_parts) { m_parts.Remove(linkPart.UUID); - } - - if (m_parts.Count == 1 && RootPart != null) //Single prim is left - RootPart.LinkNum = 0; - else - { - foreach (SceneObjectPart p in m_parts.Values) + + if (m_parts.Count == 1 && RootPart != null) //Single prim is left { - if (p.LinkNum > linkPart.LinkNum) - p.LinkNum--; + RootPart.LinkNum = 0; } + else + { + foreach (SceneObjectPart p in m_parts.Values) + { + if (p.LinkNum > linkPart.LinkNum) + p.LinkNum--; + } + } } linkPart.ParentID = 0; @@ -2762,9 +2787,11 @@ namespace OpenSim.Region.Framework.Scenes public void UpdatePermissions(UUID AgentID, byte field, uint localID, uint mask, byte addRemTF) { - foreach (SceneObjectPart part in m_parts.Values) - part.UpdatePermissions(AgentID, field, localID, mask, - addRemTF); + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); + } HasGroupChanged = true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 84b73658c6..e08fa7731c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -601,7 +601,10 @@ namespace OpenSim.Region.Framework.Scenes rootPart.Name = item.Name; rootPart.Description = item.Description; - List partList = new List(group.Children.Values); + List partList = null; + + lock (group.Children) + partList = new List(group.Children.Values); group.SetGroup(m_part.GroupID, null); diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs index 56656fc8b8..de1e01c89d 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs @@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement continue; temp = (SceneObjectGroup) currObj; - if (m_CMEntityHash.ContainsKey(temp.UUID)) + lock (temp.Children) { - foreach (SceneObjectPart part in temp.Children.Values) - if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) + if (m_CMEntityHash.ContainsKey(temp.UUID)) + { + foreach (SceneObjectPart part in temp.Children.Values) + if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) + missingList.Add(part); + } + else //Entire group is missing from revision. (and is a new part in region) + { + foreach (SceneObjectPart part in temp.Children.Values) missingList.Add(part); - } - else //Entire group is missing from revision. (and is a new part in region) - { - foreach (SceneObjectPart part in temp.Children.Values) - missingList.Add(part); + } } } return missingList; diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 0dc78c0d41..e5fcb54f80 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) { // Deal with new parts not revisioned that have been deleted. - foreach (SceneObjectPart part in group.Children.Values) - if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) - m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); + lock (group.Children) + { + foreach (SceneObjectPart part in group.Children.Values) + if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) + m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); + } } /// @@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { temp = SceneObjectSerializer.FromXml2Format(xml); temp.SetScene(scene); - foreach (SceneObjectPart part in temp.Children.Values) - part.RegionHandle = scene.RegionInfo.RegionHandle; + + lock (temp.Children) + { + foreach (SceneObjectPart part in temp.Children.Values) + part.RegionHandle = scene.RegionInfo.RegionHandle; + } + ReplacementList.Add(temp.UUID, (EntityBase)temp); } catch (Exception e) @@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement System.Collections.ArrayList auraList = new System.Collections.ArrayList(); if (group == null) return null; - foreach (SceneObjectPart part in group.Children.Values) + + lock (group.Children) { - if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) + foreach (SceneObjectPart part in group.Children.Values) { - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); - ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); - auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); + if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) + { + ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); + ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); + auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); + } } } + return auraList; } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs index 46fbd394dd..f75f40a109 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs @@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); // Deal with new parts not revisioned that have been deleted. - foreach (SceneObjectPart part in group.Children.Values) - if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) - ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); + lock (group.Children) + { + foreach (SceneObjectPart part in group.Children.Values) + if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) + ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); + } } public void SendMetaEntitiesToNewClient(IClientAPI client) diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs index ada67011b3..2730eee2e5 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement // if group is not contained in scene's list if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) { - foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) + lock (m_UnchangedEntity.Children) { - // if scene list no longer contains this part, display translucent part and mark with red aura - if (!ContainsKey(sceneEntityList, part.UUID)) + foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) { - // if already displaying a red aura over part, make sure its red - if (m_AuraEntities.ContainsKey(part.UUID)) + // if scene list no longer contains this part, display translucent part and mark with red aura + if (!ContainsKey(sceneEntityList, part.UUID)) { - m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); + // if already displaying a red aura over part, make sure its red + if (m_AuraEntities.ContainsKey(part.UUID)) + { + m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale); + } + else + { + AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, + part.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + new Vector3(254,0,0), + part.Scale + ); + m_AuraEntities.Add(part.UUID, auraGroup); + } + SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); + SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); } - else - { - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - part.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(254,0,0), - part.Scale - ); - m_AuraEntities.Add(part.UUID, auraGroup); - } - SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); - SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT); + // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id } - // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id } // a deleted part has no where to point a beam particle system, @@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public bool HasChildPrim(UUID uuid) { - if (m_UnchangedEntity.Children.ContainsKey(uuid)) - return true; + lock (m_UnchangedEntity.Children) + if (m_UnchangedEntity.Children.ContainsKey(uuid)) + return true; + return false; } @@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public bool HasChildPrim(uint localID) { - foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) - if (part.LocalId == localID) - return true; + lock (m_UnchangedEntity.Children) + { + foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) + if (part.LocalId == localID) + return true; + } + return false; } @@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user // had originally saved. // m_Entity will NOT necessarily be the same entity as the user had saved. - foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) + lock (m_UnchangedEntity.Children) { - //This is the part that we use to show changes. - metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); - if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) + foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) { - sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; - differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); - if (differences != Diff.NONE) - metaEntityPart.Text = "CHANGE: " + differences.ToString(); - if (differences != 0) + //This is the part that we use to show changes. + metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum); + if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID)) { - // Root Part that has been modified - if ((differences&Diff.POSITION) > 0) + sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; + differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); + if (differences != Diff.NONE) + metaEntityPart.Text = "CHANGE: " + differences.ToString(); + if (differences != 0) + { + // Root Part that has been modified + if ((differences&Diff.POSITION) > 0) + { + // If the position of any part has changed, make sure the RootPart of the + // meta entity is pointing with a beam particle system + if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) + { + m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); + m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); + } + BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, + m_UnchangedEntity.RootPart.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + sceneEntityPart, + new Vector3(0,0,254) + ); + m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); + } + + if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) + { + m_AuraEntities[UnchangedPart.UUID].HideFromAll(); + m_AuraEntities.Remove(UnchangedPart.UUID); + } + AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, + UnchangedPart.GetWorldPosition(), + MetaEntity.TRANSLUCENT, + new Vector3(0,0,254), + UnchangedPart.Scale + ); + m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); + SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); + + DiffersFromSceneGroup = true; + } + else // no differences between scene part and meta part { - // If the position of any part has changed, make sure the RootPart of the - // meta entity is pointing with a beam particle system if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) { m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); } - BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, - m_UnchangedEntity.RootPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - sceneEntityPart, - new Vector3(0,0,254) - ); - m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup); + if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) + { + m_AuraEntities[UnchangedPart.UUID].HideFromAll(); + m_AuraEntities.Remove(UnchangedPart.UUID); + } + SetPartTransparency(metaEntityPart, MetaEntity.NONE); } - + } + else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. + { if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) { m_AuraEntities[UnchangedPart.UUID].HideFromAll(); @@ -267,48 +311,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, UnchangedPart.GetWorldPosition(), MetaEntity.TRANSLUCENT, - new Vector3(0,0,254), + new Vector3(254,0,0), UnchangedPart.Scale ); m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - + DiffersFromSceneGroup = true; } - else // no differences between scene part and meta part - { - if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) - { - m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); - m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); - } - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - SetPartTransparency(metaEntityPart, MetaEntity.NONE); - } - } - else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted. - { - if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) - { - m_AuraEntities[UnchangedPart.UUID].HideFromAll(); - m_AuraEntities.Remove(UnchangedPart.UUID); - } - AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, - UnchangedPart.GetWorldPosition(), - MetaEntity.TRANSLUCENT, - new Vector3(254,0,0), - UnchangedPart.Scale - ); - m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); - SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); - - DiffersFromSceneGroup = true; } } + return changed; } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index 841ee00e59..796f437974 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs @@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { //make new uuids Dictionary parts = new Dictionary(); - foreach (SceneObjectPart part in m_Entity.Children.Values) + + lock (m_Entity.Children) { - part.ResetIDs(part.LinkNum); - parts.Add(part.UUID, part); + foreach (SceneObjectPart part in m_Entity.Children.Values) + { + part.ResetIDs(part.LinkNum); + parts.Add(part.UUID, part); + } + + //finalize + m_Entity.RootPart.PhysActor = null; + m_Entity.Children = parts; } - - //finalize - m_Entity.RootPart.PhysActor = null; - m_Entity.Children = parts; } #endregion Protected Methods @@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement //This deletes the group without removing from any databases. //This is important because we are not IN any database. //m_Entity.FakeDeleteGroup(); - foreach (SceneObjectPart part in m_Entity.Children.Values) - client.SendKillObject(m_Entity.RegionHandle, part.LocalId); + lock (m_Entity.Children) + { + foreach (SceneObjectPart part in m_Entity.Children.Values) + client.SendKillObject(m_Entity.RegionHandle, part.LocalId); + } } /// @@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public virtual void HideFromAll() { - foreach (SceneObjectPart part in m_Entity.Children.Values) + lock (m_Entity.Children) { - m_Entity.Scene.ForEachClient( - delegate(IClientAPI controller) - { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } - ); + foreach (SceneObjectPart part in m_Entity.Children.Values) + { + m_Entity.Scene.ForEachClient( + delegate(IClientAPI controller) + { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } + ); + } } } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 96cccb77d0..34171b066c 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -185,14 +185,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule get { SceneObjectPart my = GetSOP(); - int total = my.ParentGroup.Children.Count; - - IObject[] rets = new IObject[total]; - - int i = 0; - foreach (KeyValuePair pair in my.ParentGroup.Children) + IObject[] rets = null; + + lock (my.ParentGroup.Children) { - rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); + 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); + } } 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 21604d0a45..af42daef76 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -235,7 +235,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { case ScriptBaseClass.LINK_SET: if (m_host.ParentGroup != null) - return new List(m_host.ParentGroup.Children.Values); + { + lock (m_host.ParentGroup.Children) + return new List(m_host.ParentGroup.Children.Values); + } return ret; case ScriptBaseClass.LINK_ROOT: @@ -250,7 +253,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.LINK_ALL_OTHERS: if (m_host.ParentGroup == null) return new List(); - ret = new List(m_host.ParentGroup.Children.Values); + + lock (m_host.ParentGroup.Children) + ret = new List(m_host.ParentGroup.Children.Values); + if (ret.Contains(m_host)) ret.Remove(m_host); return ret; @@ -258,7 +264,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.LINK_ALL_CHILDREN: if (m_host.ParentGroup == null) return new List(); - ret = new List(m_host.ParentGroup.Children.Values); + + lock (m_host.ParentGroup.Children) + ret = new List(m_host.ParentGroup.Children.Values); + if (ret.Contains(m_host.ParentGroup.RootPart)) ret.Remove(m_host.ParentGroup.RootPart); return ret; @@ -1178,12 +1187,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (group == null) return; bool allow = true; - foreach (SceneObjectPart part in group.Children.Values) + + lock (group.Children) { - if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) + foreach (SceneObjectPart part in group.Children.Values) { - allow = false; - break; + if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) + { + allow = false; + break; + } } } @@ -3492,7 +3505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.Children.Count > 1) + if (m_host.ParentGroup.PrimCount > 1) { return m_host.LinkNum; } @@ -3604,15 +3617,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.LINK_ALL_OTHERS: case ScriptBaseClass.LINK_ALL_CHILDREN: case ScriptBaseClass.LINK_THIS: - foreach (SceneObjectPart part in parentPrim.Children.Values) + lock (parentPrim.Children) { - if (part.UUID != m_host.UUID) + foreach (SceneObjectPart part in parentPrim.Children.Values) { - childPrim = part; - break; + if (part.UUID != m_host.UUID) + { + childPrim = part; + break; + } } + break; } - break; default: childPrim = parentPrim.GetLinkNumPart(linknum); if (childPrim.UUID == m_host.UUID) @@ -3623,27 +3639,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (linknum == ScriptBaseClass.LINK_ROOT) { // Restructuring Multiple Prims. - List parts = new List(parentPrim.Children.Values); - parts.Remove(parentPrim.RootPart); - foreach (SceneObjectPart part in parts) + lock (parentPrim.Children) { - parentPrim.DelinkFromGroup(part.LocalId, true); - } - parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); - parentPrim.TriggerScriptChangedEvent(Changed.LINK); - - if (parts.Count > 0) - { - SceneObjectPart newRoot = parts[0]; - parts.Remove(newRoot); + List parts = new List(parentPrim.Children.Values); + parts.Remove(parentPrim.RootPart); foreach (SceneObjectPart part in parts) { - part.UpdateFlag = 0; - newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + parentPrim.DelinkFromGroup(part.LocalId, true); + } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); + parentPrim.TriggerScriptChangedEvent(Changed.LINK); + + if (parts.Count > 0) + { + SceneObjectPart newRoot = parts[0]; + parts.Remove(newRoot); + foreach (SceneObjectPart part in parts) + { + part.UpdateFlag = 0; + newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + } + newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } - newRoot.ParentGroup.HasGroupChanged = true; - newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } else @@ -3665,16 +3684,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (parentPrim.RootPart.AttachmentPoint != 0) return; // Fail silently if attached - List parts = new List(parentPrim.Children.Values); - parts.Remove(parentPrim.RootPart); - - foreach (SceneObjectPart part in parts) + lock (parentPrim.Children) { - parentPrim.DelinkFromGroup(part.LocalId, true); - parentPrim.TriggerScriptChangedEvent(Changed.LINK); + List parts = new List(parentPrim.Children.Values); + parts.Remove(parentPrim.RootPart); + + foreach (SceneObjectPart part in parts) + { + parentPrim.DelinkFromGroup(part.LocalId, true); + parentPrim.TriggerScriptChangedEvent(Changed.LINK); + } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); } - parentPrim.HasGroupChanged = true; - parentPrim.ScheduleGroupForFullUpdate(); } public LSL_String llGetLinkKey(int linknum) @@ -4200,7 +4222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { partItemID = item.ItemID; int linkNumber = m_host.LinkNum; - if (m_host.ParentGroup.Children.Count == 1) + if (m_host.ParentGroup.PrimCount == 1) linkNumber = 0; object[] resobj = new object[] diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs index 4855d6448e..41501f24dd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs @@ -209,12 +209,15 @@ namespace OpenSim.Region.ScriptEngine.Shared else Type = 0x02; // Passive - foreach (SceneObjectPart p in part.ParentGroup.Children.Values) + lock (part.ParentGroup.Children) { - if (p.Inventory.ContainsScripts()) + foreach (SceneObjectPart p in part.ParentGroup.Children.Values) { - Type |= 0x08; // Scripted - break; + if (p.Inventory.ContainsScripts()) + { + Type |= 0x08; // Scripted + break; + } } } From 166ab59420f34e21fcd9493c1941d7cf43729ca6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 00:15:26 +0100 Subject: [PATCH 35/60] replace m_parts.Count linknum with 0 in CopyRootPart since m_parts.Count is always 0 (and any other number would cause an error anyway) --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5ee8d7390e..fc5eeed9cf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1647,7 +1647,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); + SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); } public void ScriptSetPhysicsStatus(bool UsePhysics) From 692cf3c657aaa74645722491c997f23b4d6f8f76 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 00:17:26 +0100 Subject: [PATCH 36/60] Remove parts locking from data classes since these are using a copy of the scene object --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 104 +++++---- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 211 +++++++++--------- OpenSim/Data/SQLite/SQLiteRegionData.cs | 9 +- OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs | 9 +- 4 files changed, 160 insertions(+), 173 deletions(-) diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index 4ce93e55c8..7ff87379b5 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -89,7 +89,6 @@ namespace OpenSim.Data.MSSQL Dictionary objects = new Dictionary(); SceneObjectGroup grp = null; - string sql = "SELECT *, " + "sort = CASE WHEN prims.UUID = prims.SceneGroupID THEN 0 ELSE 1 END " + "FROM prims " + @@ -232,65 +231,62 @@ namespace OpenSim.Data.MSSQL /// public void StoreObject(SceneObjectGroup obj, UUID regionUUID) { - lock (obj.Children) + _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); + + using (SqlConnection conn = new SqlConnection(m_connectionString)) { - _Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Children.Count); - - using (SqlConnection conn = new SqlConnection(m_connectionString)) + conn.Open(); + SqlTransaction transaction = conn.BeginTransaction(); + + try { - conn.Open(); - SqlTransaction transaction = conn.BeginTransaction(); - + foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) + { + //Update prim + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + + //Update primshapes + using (SqlCommand sqlCommand = conn.CreateCommand()) + { + sqlCommand.Transaction = transaction; + try + { + StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); + } + catch (SqlException sqlEx) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); + throw; + } + } + } + + transaction.Commit(); + } + catch (Exception ex) + { + _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); try { - foreach (SceneObjectPart sceneObjectPart in obj.Children.Values) - { - //Update prim - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrim(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrim SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - - //Update primshapes - using (SqlCommand sqlCommand = conn.CreateCommand()) - { - sqlCommand.Transaction = transaction; - try - { - StoreSceneObjectPrimShapes(sceneObjectPart, sqlCommand, obj.UUID, regionUUID); - } - catch (SqlException sqlEx) - { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectPrimShapes SQL error: {0} at line {1}", sqlEx.Message, sqlEx.LineNumber); - throw; - } - } - } - - transaction.Commit(); + transaction.Rollback(); } - catch (Exception ex) + catch (Exception ex2) { - _Log.ErrorFormat("[REGION DB]: Store SceneObjectGroup error: {0}, Rolling back...", ex.Message); - try - { - transaction.Rollback(); - } - catch (Exception ex2) - { - //Show error - _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); - - } + //Show error + _Log.InfoFormat("[REGION DB]: Rollback of SceneObjectGroup store transaction failed with error: {0}", ex2.Message); + } } } diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index b756b4fe07..37d7a88a63 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -135,115 +135,112 @@ namespace OpenSim.Data.MySQL dbcon.Open(); MySqlCommand cmd = dbcon.CreateCommand(); - lock (obj.Children) + foreach (SceneObjectPart prim in obj.Children.Values) { - foreach (SceneObjectPart prim in obj.Children.Values) - { - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into prims (" + - "UUID, CreationDate, " + - "Name, Text, Description, " + - "SitName, TouchName, ObjectFlags, " + - "OwnerMask, NextOwnerMask, GroupMask, " + - "EveryoneMask, BaseMask, PositionX, " + - "PositionY, PositionZ, GroupPositionX, " + - "GroupPositionY, GroupPositionZ, VelocityX, " + - "VelocityY, VelocityZ, AngularVelocityX, " + - "AngularVelocityY, AngularVelocityZ, " + - "AccelerationX, AccelerationY, " + - "AccelerationZ, RotationX, " + - "RotationY, RotationZ, " + - "RotationW, SitTargetOffsetX, " + - "SitTargetOffsetY, SitTargetOffsetZ, " + - "SitTargetOrientW, SitTargetOrientX, " + - "SitTargetOrientY, SitTargetOrientZ, " + - "RegionUUID, CreatorID, " + - "OwnerID, GroupID, " + - "LastOwnerID, SceneGroupID, " + - "PayPrice, PayButton1, " + - "PayButton2, PayButton3, " + - "PayButton4, LoopedSound, " + - "LoopedSoundGain, TextureAnimation, " + - "OmegaX, OmegaY, OmegaZ, " + - "CameraEyeOffsetX, CameraEyeOffsetY, " + - "CameraEyeOffsetZ, CameraAtOffsetX, " + - "CameraAtOffsetY, CameraAtOffsetZ, " + - "ForceMouselook, ScriptAccessPin, " + - "AllowedDrop, DieAtEdge, " + - "SalePrice, SaleType, " + - "ColorR, ColorG, ColorB, ColorA, " + - "ParticleSystem, ClickAction, Material, " + - "CollisionSound, CollisionSoundVolume, " + - "PassTouches, " + - "LinkNumber, MediaURL) values (" + "?UUID, " + - "?CreationDate, ?Name, ?Text, " + - "?Description, ?SitName, ?TouchName, " + - "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + - "?GroupMask, ?EveryoneMask, ?BaseMask, " + - "?PositionX, ?PositionY, ?PositionZ, " + - "?GroupPositionX, ?GroupPositionY, " + - "?GroupPositionZ, ?VelocityX, " + - "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + - "?AngularVelocityY, ?AngularVelocityZ, " + - "?AccelerationX, ?AccelerationY, " + - "?AccelerationZ, ?RotationX, " + - "?RotationY, ?RotationZ, " + - "?RotationW, ?SitTargetOffsetX, " + - "?SitTargetOffsetY, ?SitTargetOffsetZ, " + - "?SitTargetOrientW, ?SitTargetOrientX, " + - "?SitTargetOrientY, ?SitTargetOrientZ, " + - "?RegionUUID, ?CreatorID, ?OwnerID, " + - "?GroupID, ?LastOwnerID, ?SceneGroupID, " + - "?PayPrice, ?PayButton1, ?PayButton2, " + - "?PayButton3, ?PayButton4, ?LoopedSound, " + - "?LoopedSoundGain, ?TextureAnimation, " + - "?OmegaX, ?OmegaY, ?OmegaZ, " + - "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + - "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + - "?CameraAtOffsetY, ?CameraAtOffsetZ, " + - "?ForceMouselook, ?ScriptAccessPin, " + - "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + - "?SaleType, ?ColorR, ?ColorG, " + - "?ColorB, ?ColorA, ?ParticleSystem, " + - "?ClickAction, ?Material, ?CollisionSound, " + - "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; - - FillPrimCommand(cmd, prim, obj.UUID, regionUUID); - - ExecuteNonQuery(cmd); - - cmd.Parameters.Clear(); - - cmd.CommandText = "replace into primshapes (" + - "UUID, Shape, ScaleX, ScaleY, " + - "ScaleZ, PCode, PathBegin, PathEnd, " + - "PathScaleX, PathScaleY, PathShearX, " + - "PathShearY, PathSkew, PathCurve, " + - "PathRadiusOffset, PathRevolutions, " + - "PathTaperX, PathTaperY, PathTwist, " + - "PathTwistBegin, ProfileBegin, ProfileEnd, " + - "ProfileCurve, ProfileHollow, Texture, " + - "ExtraParams, State, Media) values (?UUID, " + - "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + - "?PCode, ?PathBegin, ?PathEnd, " + - "?PathScaleX, ?PathScaleY, " + - "?PathShearX, ?PathShearY, " + - "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + - "?PathRevolutions, ?PathTaperX, " + - "?PathTaperY, ?PathTwist, " + - "?PathTwistBegin, ?ProfileBegin, " + - "?ProfileEnd, ?ProfileCurve, " + - "?ProfileHollow, ?Texture, ?ExtraParams, " + - "?State, ?Media)"; - - FillShapeCommand(cmd, prim); - - ExecuteNonQuery(cmd); - } - - cmd.Dispose(); + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into prims (" + + "UUID, CreationDate, " + + "Name, Text, Description, " + + "SitName, TouchName, ObjectFlags, " + + "OwnerMask, NextOwnerMask, GroupMask, " + + "EveryoneMask, BaseMask, PositionX, " + + "PositionY, PositionZ, GroupPositionX, " + + "GroupPositionY, GroupPositionZ, VelocityX, " + + "VelocityY, VelocityZ, AngularVelocityX, " + + "AngularVelocityY, AngularVelocityZ, " + + "AccelerationX, AccelerationY, " + + "AccelerationZ, RotationX, " + + "RotationY, RotationZ, " + + "RotationW, SitTargetOffsetX, " + + "SitTargetOffsetY, SitTargetOffsetZ, " + + "SitTargetOrientW, SitTargetOrientX, " + + "SitTargetOrientY, SitTargetOrientZ, " + + "RegionUUID, CreatorID, " + + "OwnerID, GroupID, " + + "LastOwnerID, SceneGroupID, " + + "PayPrice, PayButton1, " + + "PayButton2, PayButton3, " + + "PayButton4, LoopedSound, " + + "LoopedSoundGain, TextureAnimation, " + + "OmegaX, OmegaY, OmegaZ, " + + "CameraEyeOffsetX, CameraEyeOffsetY, " + + "CameraEyeOffsetZ, CameraAtOffsetX, " + + "CameraAtOffsetY, CameraAtOffsetZ, " + + "ForceMouselook, ScriptAccessPin, " + + "AllowedDrop, DieAtEdge, " + + "SalePrice, SaleType, " + + "ColorR, ColorG, ColorB, ColorA, " + + "ParticleSystem, ClickAction, Material, " + + "CollisionSound, CollisionSoundVolume, " + + "PassTouches, " + + "LinkNumber, MediaURL) values (" + "?UUID, " + + "?CreationDate, ?Name, ?Text, " + + "?Description, ?SitName, ?TouchName, " + + "?ObjectFlags, ?OwnerMask, ?NextOwnerMask, " + + "?GroupMask, ?EveryoneMask, ?BaseMask, " + + "?PositionX, ?PositionY, ?PositionZ, " + + "?GroupPositionX, ?GroupPositionY, " + + "?GroupPositionZ, ?VelocityX, " + + "?VelocityY, ?VelocityZ, ?AngularVelocityX, " + + "?AngularVelocityY, ?AngularVelocityZ, " + + "?AccelerationX, ?AccelerationY, " + + "?AccelerationZ, ?RotationX, " + + "?RotationY, ?RotationZ, " + + "?RotationW, ?SitTargetOffsetX, " + + "?SitTargetOffsetY, ?SitTargetOffsetZ, " + + "?SitTargetOrientW, ?SitTargetOrientX, " + + "?SitTargetOrientY, ?SitTargetOrientZ, " + + "?RegionUUID, ?CreatorID, ?OwnerID, " + + "?GroupID, ?LastOwnerID, ?SceneGroupID, " + + "?PayPrice, ?PayButton1, ?PayButton2, " + + "?PayButton3, ?PayButton4, ?LoopedSound, " + + "?LoopedSoundGain, ?TextureAnimation, " + + "?OmegaX, ?OmegaY, ?OmegaZ, " + + "?CameraEyeOffsetX, ?CameraEyeOffsetY, " + + "?CameraEyeOffsetZ, ?CameraAtOffsetX, " + + "?CameraAtOffsetY, ?CameraAtOffsetZ, " + + "?ForceMouselook, ?ScriptAccessPin, " + + "?AllowedDrop, ?DieAtEdge, ?SalePrice, " + + "?SaleType, ?ColorR, ?ColorG, " + + "?ColorB, ?ColorA, ?ParticleSystem, " + + "?ClickAction, ?Material, ?CollisionSound, " + + "?CollisionSoundVolume, ?PassTouches, ?LinkNumber, ?MediaURL)"; + + FillPrimCommand(cmd, prim, obj.UUID, regionUUID); + + ExecuteNonQuery(cmd); + + cmd.Parameters.Clear(); + + cmd.CommandText = "replace into primshapes (" + + "UUID, Shape, ScaleX, ScaleY, " + + "ScaleZ, PCode, PathBegin, PathEnd, " + + "PathScaleX, PathScaleY, PathShearX, " + + "PathShearY, PathSkew, PathCurve, " + + "PathRadiusOffset, PathRevolutions, " + + "PathTaperX, PathTaperY, PathTwist, " + + "PathTwistBegin, ProfileBegin, ProfileEnd, " + + "ProfileCurve, ProfileHollow, Texture, " + + "ExtraParams, State, Media) values (?UUID, " + + "?Shape, ?ScaleX, ?ScaleY, ?ScaleZ, " + + "?PCode, ?PathBegin, ?PathEnd, " + + "?PathScaleX, ?PathScaleY, " + + "?PathShearX, ?PathShearY, " + + "?PathSkew, ?PathCurve, ?PathRadiusOffset, " + + "?PathRevolutions, ?PathTaperX, " + + "?PathTaperY, ?PathTwist, " + + "?PathTwistBegin, ?ProfileBegin, " + + "?ProfileEnd, ?ProfileCurve, " + + "?ProfileHollow, ?Texture, ?ExtraParams, " + + "?State, ?Media)"; + + FillShapeCommand(cmd, prim); + + ExecuteNonQuery(cmd); } + + cmd.Dispose(); } } } diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index bfd8279f7b..4208050ab9 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -360,13 +360,10 @@ namespace OpenSim.Data.SQLite lock (ds) { - lock (obj.Children) + foreach (SceneObjectPart prim in obj.Children.Values) { - foreach (SceneObjectPart prim in obj.Children.Values) - { - // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); - } +// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, obj.UUID, regionUUID); } } diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs index 779b2ed331..289fd948ce 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs @@ -327,13 +327,10 @@ namespace OpenSim.Data.SQLiteLegacy lock (ds) { - lock (obj.Children) + foreach (SceneObjectPart prim in obj.Children.Values) { - foreach (SceneObjectPart prim in obj.Children.Values) - { - // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); - addPrim(prim, obj.UUID, regionUUID); - } +// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); + addPrim(prim, obj.UUID, regionUUID); } } From a6869fbc3ef92733de37f6dc95d62f08034dae17 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 15:33:42 +0100 Subject: [PATCH 37/60] Use SOP.ParentGroup in Prioritizer instead of Scene.GetGroupByPrim() By the time a scheduled update is triggered, a sog may have been removed from the scene. This change prevents NullReferenceExceptions in these situations. --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index de3c360a42..505d01ffa8 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -122,9 +122,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); } @@ -144,9 +151,16 @@ namespace OpenSim.Region.Framework.Scenes // Use group position for child prims Vector3 entityPos = entity.AbsolutePosition; 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; + } if (!presence.IsChildAgent) { From d99c60164dca32fb3b21d343e9066cae45a852d2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 16:06:34 +0100 Subject: [PATCH 38/60] Reinstate kill record check that prevents an entity update being sent to a client after it has been told that the entity has been deleted. On Linden Lab clients and some derivatives, receiving an entity update after an entity deletion notice results in an undeleteable prim that disappears upon client relog. This check was dropped in 0.7 for unknown reasons but renewed testing demonstrates that queued updates can still be present after a scene object has been deleted. --- .../ClientStack/LindenUDP/LLClientView.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 320a2fa94a..677bd146ae 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -327,7 +327,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; @@ -382,18 +382,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++; } } @@ -3528,6 +3532,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP EntityUpdate update; while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) { + // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client + // will never receive an update after a prim kill. Even then, keeping the kill record may be a good + // safety measure. + // + // Receiving updates after kills results in undeleteable prims that persist until relog and + // currently occurs because prims can be deleted before all queued updates are sent. + if (m_killRecord.Contains(update.Entity.LocalId)) + { +// m_log.WarnFormat( +// "[CLIENT]: Preventing full update for prim with local id {0} after client for user {1} told it was deleted", +// update.Entity.LocalId, Name); + continue; + } + if (update.Entity is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)update.Entity; From df702417dc6aba6422b3f252023ea551620f8ee2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 16:27:41 +0100 Subject: [PATCH 39/60] Remove mono compiler warnings --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 3 +-- OpenSim/Region/Framework/Scenes/Scene.cs | 12 ------------ .../Scenes/SceneCommunicationService.cs | 6 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 -- .../Region/Framework/Scenes/SceneObjectPart.cs | 16 ++-------------- .../Framework/Scenes/SceneObjectPartInventory.cs | 3 +-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 1 - 7 files changed, 7 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 505d01ffa8..272f7186e4 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 diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1f4d022be6..5fe944dbe2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3608,18 +3608,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 c675322185..88e084eecd 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 1da428717f..5b4ec3b12b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1700,8 +1700,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/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2ad4223670..3ed74e1f36 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4727,20 +4727,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 e08fa7731c..d7767bd644 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -576,8 +576,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 08c6e270db..a4eae42990 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2327,7 +2327,6 @@ 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; From fe660cd2cce844e2b3d9b3de33c5110c4b0e94b5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 18:11:01 +0100 Subject: [PATCH 40/60] Rename Newtonsoft.Json.dll to properly reflect its actual assembly name --- ...ewtonsoft.Json.dll => Newtonsoft.Json.Net20.dll} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename bin/{Newtonsoft.Json.dll => Newtonsoft.Json.Net20.dll} (100%) 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 From 26fd673e20f56cd8f7b611d4767ad8c9d65b02f6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 Aug 2010 12:26:09 -0700 Subject: [PATCH 41/60] Addresses mantis #4984 -- Datasnapshot exceptions. --- OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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; From 8571a55d29b51428c29790a249f0bea347e5eb2a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 20:42:56 +0100 Subject: [PATCH 42/60] minor: change log message from info to debug --- .../Avatar/Inventory/Transfer/InventoryTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 4117e86f18..d1274e9cf1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -159,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { - m_log.InfoFormat( + m_log.DebugFormat( "[INVENTORY TRANSFER]: {0} IM type received from {1}", (InstantMessageDialog)im.dialog, client.Name); From f3f4428700f2c63901e6f068957f879143ba0bd5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 21:50:19 +0100 Subject: [PATCH 43/60] refactor: break out attachment position change code in Scene.UpdatePrimPosition() and move into AttachmentsModule This allows region modules to change attachment positions. --- .../Avatar/Attachments/AttachmentsModule.cs | 21 ++++++++++- .../Interfaces/IAttachmentsModule.cs | 8 ++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 37 +++++++------------ 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 847a9991a8..b3811bffcf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -455,5 +455,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } } + + 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; + m_scene.UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID); + sog.SetAttachmentPoint(attachmentPoint); + } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 2af25481e4..05c1e009fc 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -131,5 +131,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); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5b4ec3b12b..9db2691355 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1289,37 +1289,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); } @@ -1328,14 +1312,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)) From 2b0f924557575777511432e5d72d21297a8002fd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 22:09:52 +0100 Subject: [PATCH 44/60] refactor: Move Scene.Inventory.UpdateKnownItem() into Attachments module since this appears to relate solely to attachments --- .../Avatar/Attachments/AttachmentsModule.cs | 60 ++++++++++++++++++- .../Framework/Scenes/Scene.Inventory.cs | 47 --------------- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b3811bffcf..d56145a2a5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -37,6 +37,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.CoreModules.Avatar.Attachments { @@ -448,7 +449,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); 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; } @@ -471,8 +472,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sog.UpdateGroupPosition(pos); sog.RootPart.IsAttachment = false; sog.AbsolutePosition = sog.RootPart.AttachedPos; - m_scene.UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID); + 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/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 379128a2fc..8ed8b96a4d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1799,53 +1799,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; From 7f5501d3ab20f986317828c8c41783d64770f7a7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 26 Aug 2010 22:13:31 +0100 Subject: [PATCH 45/60] minor: remove mono compiler warning --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a4eae42990..fbb3177822 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2326,14 +2326,15 @@ namespace OpenSim.Region.Framework.Scenes { m_perfMonMS = Util.EnvironmentTickCount(); - PhysicsActor actor = m_physicsActor; - 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); From 6198fe53e6b14eede432b8ce2825fcb4f933ebd8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 Aug 2010 14:19:52 -0700 Subject: [PATCH 46/60] Addresses mantis #4985 -- exceptions in DataSnapshot --- OpenSim/Region/DataSnapshot/SnapshotStore.cs | 30 +++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/DataSnapshot/SnapshotStore.cs index 70cb2053c9..397739446c 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; @@ -185,12 +186,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 +214,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", ""); From 436fdc2ea828d5bc4fa1a1aa7d4b796ac77cc932 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 Aug 2010 14:48:29 -0700 Subject: [PATCH 47/60] More on mantis #4985 --- OpenSim/Region/DataSnapshot/SnapshotStore.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/DataSnapshot/SnapshotStore.cs index 397739446c..aa3d2ff34c 100644 --- a/OpenSim/Region/DataSnapshot/SnapshotStore.cs +++ b/OpenSim/Region/DataSnapshot/SnapshotStore.cs @@ -99,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 @@ -214,7 +222,7 @@ namespace OpenSim.Region.DataSnapshot #region Helpers private string DataFileNameFragment(Scene scene, String fragmentName) { - return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName) + "_" + fragmentName, "xml")); + return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName + "_" + fragmentName), "xml")); } private string DataFileNameScene(Scene scene) From 5b4e0b72bc889dd03d3c9cd943e7ff00e2a3593c Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 26 Aug 2010 23:38:35 +0100 Subject: [PATCH 48/60] Send a null result search packet when no results are passsed in --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 320a2fa94a..17c051a952 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2724,6 +2724,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; @@ -2762,7 +2765,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - if (replies.Length > 0) + if (replies.Length > 0 || data.Length == 0) OutPacket(packet, ThrottleOutPacketType.Task); } From 3c71e5a3a2708bd9c46f4d0d7f2a8067962d32ad Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 26 Aug 2010 18:23:16 -0700 Subject: [PATCH 49/60] Deleted Check4096 from Robust.ini.example --- bin/Robust.ini.example | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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_ = "" From 8f875700ef3f0d8e4d86192d2985aff250fe2d51 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 27 Aug 2010 22:52:26 +0100 Subject: [PATCH 50/60] refactor: Make IAR tests set up standard iar for loading --- .../Archiver/Tests/InventoryArchiverTests.cs | 104 ++++++++++-------- .../Common/Setup/UserProfileTestUtils.cs | 15 ++- 2 files changed, 71 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 3fb2c8cbac..892680e368 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 @@ -308,34 +354,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 +362,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 +378,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/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 From 86937d0a0f5572b002cdb6efc499c234b2a9bd1b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 27 Aug 2010 23:22:49 +0100 Subject: [PATCH 51/60] allow inventory path specified in "load iar" to start with a / (e.g. /Objects is now valid where it wasn't before) --- .../Archiver/InventoryArchiveUtils.cs | 10 +++++++- .../Archiver/Tests/InventoryArchiverTests.cs | 24 +++++++++++++++++++ .../Common/Mock/TestInventoryDataPlugin.cs | 24 +++++++++---------- 3 files changed, 45 insertions(+), 13 deletions(-) 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/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 892680e368..e8a26b5ea0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -342,6 +342,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. 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; } From 4f9931ec10fe189c29ea3759c6e4ad27780525e5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 27 Aug 2010 23:23:55 +0100 Subject: [PATCH 52/60] minor: reduce log chattiness of "load iar" for IARs with lots of folders --- .../Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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)) { From 1c0b4457cdcd543f04bc818a987f6e3f2311098d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Aug 2010 00:40:33 +0100 Subject: [PATCH 53/60] Improve liveness by operating on list copies of SOG.Children where appropriate --- .../Archiver/Tests/InventoryArchiverTests.cs | 2 +- .../World/Archiver/ArchiveReadRequest.cs | 57 +- .../World/WorldMap/MapImageModule.cs | 515 +++++++++--------- .../Framework/Scenes/Scene.Inventory.cs | 22 +- .../Framework/Scenes/Scene.PacketHandlers.cs | 15 +- OpenSim/Region/Framework/Scenes/Scene.cs | 21 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 55 +- .../Framework/Scenes/SceneObjectGroup.cs | 50 +- .../Scripting/Minimodule/SOPObject.cs | 22 +- 9 files changed, 386 insertions(+), 373 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index e8a26b5ea0..b5f9a8e35a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -349,7 +349,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests public void TestLoadIarPathStartsWithSlash() { TestHelper.InMethod(); - log4net.Config.XmlConfigurator.Configure(); +// log4net.Config.XmlConfigurator.Configure(); SerialiserModule serialiserModule = new SerialiserModule(); InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 1623e6e3c2..1fba6c2f50 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -243,39 +243,40 @@ 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; - - 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) + TaskInventoryDictionary inv = part.TaskInventory; + foreach (KeyValuePair kvp in inv) { - TaskInventoryDictionary inv = part.TaskInventory; - foreach (KeyValuePair kvp in inv) + if (!ResolveUserUuid(kvp.Value.OwnerID)) { - if (!ResolveUserUuid(kvp.Value.OwnerID)) - { - kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; - } - if (!ResolveUserUuid(kvp.Value.CreatorID)) - { - kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; - } + kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; + } + if (!ResolveUserUuid(kvp.Value.CreatorID)) + { + kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; } } } 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/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8ed8b96a4d..2ac46e2a03 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2004,11 +2004,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 { @@ -2017,14 +2018,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 5fe944dbe2..db081cc006 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2065,19 +2065,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; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9db2691355..2c242c9497 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -380,34 +380,35 @@ 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(); - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - lock (SceneObjectGroupsByFullID) - { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - } - - lock (SceneObjectGroupsByLocalID) - { - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } + m_numPrim += sceneObject.Children.Count; + } + + sceneObject.AttachToScene(m_parentScene); + + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + + Entities.Add(sceneObject); + + if (attachToBackup) + sceneObject.AttachToBackup(); + + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (SceneObjectGroupsByFullID) + { + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + } + + lock (SceneObjectGroupsByLocalID) + { + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fc5eeed9cf..40a8f83143 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -237,6 +237,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 @@ -1968,28 +1970,29 @@ namespace OpenSim.Region.Framework.Scenes //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) // return; - lock (m_parts) + 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; + lock (m_parts) + partList = new List(m_parts.Values); + + foreach (SceneObjectPart part in partList) + { + if (!IsSelected) + part.UpdateLookAt(); + part.SendScheduledUpdates(); } } @@ -2787,11 +2790,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/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; From 0f95cd209e8f336ae912dd89f2d15b156f1355d2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 27 Aug 2010 17:25:04 -0700 Subject: [PATCH 54/60] Addresses mantis #4991 -- HG between two regions with the same map coordinates fails with no warning --- .../Framework/EntityTransfer/EntityTransferModule.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index bb98dba7a2..81f49b6710 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 // From def6b1544f51300fcc051bd975df138b23ed2fc7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Aug 2010 02:40:21 +0100 Subject: [PATCH 55/60] very minor log message and var name tweaking for iar saving --- .../Inventory/Archiver/InventoryArchiveWriteRequest.cs | 10 ++++++---- .../Inventory/Archiver/Tests/InventoryArchiverTests.cs | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) 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 b5f9a8e35a..0218f86178 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -168,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); @@ -194,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) // { From 374807d19421963a5ff842513079f94a3044bfa9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Aug 2010 02:45:28 +0100 Subject: [PATCH 56/60] Replace hardcoded 0 with KickFlags provided by the client. This finally completes http://opensimulator.org/mantis/view.php?id=4356 where this change had been accidentally removed. Thanks Revolution. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 34cc7d94a4..092c96ec38 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -8977,7 +8977,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 From 4b2e3bd6c333f68f2a1831ac78b8ddbd1ac0aee3 Mon Sep 17 00:00:00 2001 From: Jonathan Freedman Date: Sun, 29 Aug 2010 21:28:31 -0400 Subject: [PATCH 57/60] local commit with parcel media bits Signed-off-by: Melanie --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 22 +++- .../MySQL/Resources/RegionStore.migrations | 14 +- .../SQLite/Resources/RegionStore.migrations | 10 ++ OpenSim/Data/SQLite/SQLiteRegionData.cs | 6 + OpenSim/Framework/LandData.cs | 104 +++++++++++++-- OpenSim/Framework/LandUpdateArgs.cs | 7 + .../ClientStack/LindenUDP/LLClientView.cs | 124 ++++++++++-------- .../EventQueue/EventQueueGetModule.cs | 18 +-- .../Framework/EventQueue/EventQueueHelper.cs | 120 ++--------------- .../World/Land/LandManagementModule.cs | 63 ++++++++- .../CoreModules/World/Land/LandObject.cs | 7 + .../Framework/Interfaces/IEventQueue.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 8 +- 13 files changed, 306 insertions(+), 200 deletions(-) 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 13697043f1..1405207a4c 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..fe090779d1 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"] = (string) land.MediaWidth + "," + (string) land.MediaHeight; + 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 060e88696a..f263e67d84 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 092c96ec38..0d142f4f66 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; @@ -4199,94 +4200,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); } } 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/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 15dc301aa1..3e79ec0c10 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; @@ -1066,7 +1068,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) @@ -1353,8 +1354,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 6864629bb2..499b60ccdb 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/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/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index af42daef76..b51b410f86 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9137,8 +9137,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 @@ -9224,8 +9224,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; From 0a83fde85c8cffa1da46ef0a17390399ae74fa61 Mon Sep 17 00:00:00 2001 From: Jonathan Freedman Date: Sun, 29 Aug 2010 21:28:31 -0400 Subject: [PATCH 58/60] Implements parcel media setting persistence and packet / CAPS handling properly for the new media settings. Signed-off-by: Melanie --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 22 +++- .../MySQL/Resources/RegionStore.migrations | 14 +- .../SQLite/Resources/RegionStore.migrations | 10 ++ OpenSim/Data/SQLite/SQLiteRegionData.cs | 6 + OpenSim/Framework/LandData.cs | 104 +++++++++++++-- OpenSim/Framework/LandUpdateArgs.cs | 7 + .../ClientStack/LindenUDP/LLClientView.cs | 124 ++++++++++-------- .../EventQueue/EventQueueGetModule.cs | 18 +-- .../Framework/EventQueue/EventQueueHelper.cs | 120 ++--------------- .../World/Land/LandManagementModule.cs | 63 ++++++++- .../CoreModules/World/Land/LandObject.cs | 7 + .../Framework/Interfaces/IEventQueue.cs | 3 +- .../Shared/Api/Implementation/LSL_Api.cs | 8 +- 13 files changed, 306 insertions(+), 200 deletions(-) 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 13697043f1..1405207a4c 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..fe090779d1 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"] = (string) land.MediaWidth + "," + (string) land.MediaHeight; + 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 060e88696a..f263e67d84 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 092c96ec38..0d142f4f66 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; @@ -4199,94 +4200,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); } } 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/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 15dc301aa1..3e79ec0c10 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; @@ -1066,7 +1068,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) @@ -1353,8 +1354,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 6864629bb2..499b60ccdb 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/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/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index af42daef76..b51b410f86 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9137,8 +9137,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 @@ -9224,8 +9224,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; From eefb207c1bf51802bdf5491a15575347960fb798 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 30 Aug 2010 02:10:11 +0100 Subject: [PATCH 59/60] Fix a casting operation to use ToString() --- OpenSim/Data/SQLite/SQLiteRegionData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index fe090779d1..8432e74592 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -1764,7 +1764,7 @@ namespace OpenSim.Data.SQLite row["Dwell"] = land.Dwell; row["MediaType"] = land.MediaType; row["MediaDescription"] = land.MediaDescription; - row["MediaSize"] = (string) land.MediaWidth + "," + (string) land.MediaHeight; + row["MediaSize"] = land.MediaWidth.ToString() + "," + land.MediaHeight.ToString(); row["MediaLoop"] = land.MediaLoop.ToString(); row["ObscureMusic"] = land.ObscureMusic.ToString(); row["ObscureMedia"] = land.ObscureMedia.ToString(); From 8ee31d97a84632e4b6144cf81c4fdcd1e764df7c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 30 Aug 2010 02:19:21 +0100 Subject: [PATCH 60/60] Remove CRLF endings --- .../CoreModules/World/Land/LandObject.cs | 2090 ++++++++--------- 1 file changed, 1045 insertions(+), 1045 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index fcd993cc66..9e9934e09e 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1,1045 +1,1045 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.CoreModules.World.Land -{ - /// - /// Keeps track of a specific piece of land's information - /// - public class LandObject : ILandObject - { - #region Member Variables - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - #pragma warning disable 0429 - private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; - #pragma warning restore 0429 - private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; - - private int m_lastSeqId = 0; - - protected LandData m_landData = new LandData(); - protected Scene m_scene; - protected List primsOverMe = new List(); - - public bool[,] LandBitmap - { - get { return m_landBitmap; } - set { m_landBitmap = value; } - } - - #endregion - - #region ILandObject Members - - public LandData LandData - { - get { return m_landData; } - - set { m_landData = value; } - } - - public UUID RegionUUID - { - get { return m_scene.RegionInfo.RegionID; } - } - - #region Constructors - - public LandObject(UUID owner_id, bool is_group_owned, Scene scene) - { - m_scene = scene; - LandData.OwnerID = owner_id; - if (is_group_owned) - LandData.GroupID = owner_id; - else - LandData.GroupID = UUID.Zero; - LandData.IsGroupOwned = is_group_owned; - } - - #endregion - - #region Member Functions - - #region General Functions - - /// - /// Checks to see if this land object contains a point - /// - /// - /// - /// Returns true if the piece of land contains the specified point - public bool ContainsPoint(int x, int y) - { - if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) - { - return (LandBitmap[x / 4, y / 4] == true); - } - else - { - return false; - } - } - - public ILandObject Copy() - { - ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); - - //Place all new variables here! - newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); - newLand.LandData = LandData.Copy(); - - return newLand; - } - - static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; - static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; - - public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) - { - overrideParcelMaxPrimCount = overrideDel; - } - public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) - { - overrideSimulatorMaxPrimCount = overrideDel; - } - - public int GetParcelMaxPrimCount(ILandObject thisObject) - { - if (overrideParcelMaxPrimCount != null) - { - return overrideParcelMaxPrimCount(thisObject); - } - else - { - // Normal Calculations - return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); - } - } - public int GetSimulatorMaxPrimCount(ILandObject thisObject) - { - if (overrideSimulatorMaxPrimCount != null) - { - return overrideSimulatorMaxPrimCount(thisObject); - } - else - { - //Normal Calculations - return m_scene.RegionInfo.ObjectCapacity; - } - } - #endregion - - #region Packet Request Handling - - public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) - { - IEstateModule estateModule = m_scene.RequestModuleInterface(); - uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); - if (estateModule != null) - regionFlags = estateModule.GetRegionFlags(); - - // In a perfect world, this would have worked. - // -// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) -// regionFlags |= (uint)RegionFlags.AllowLandmark; -// if (landData.OwnerID == remote_client.AgentId) -// regionFlags |= (uint)RegionFlags.AllowSetHome; - - int seq_id; - if (snap_selection && (sequence_id == 0)) - { - seq_id = m_lastSeqId; - } - else - { - seq_id = sequence_id; - m_lastSeqId = seq_id; - } - - remote_client.SendLandProperties(seq_id, - snap_selection, request_result, LandData, - (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, - GetParcelMaxPrimCount(this), - GetSimulatorMaxPrimCount(this), regionFlags); - } - - public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) - { - //Needs later group support - bool snap_selection = false; - LandData newData = LandData.Copy(); - - if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) - { - if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) - { - newData.AuthBuyerID = args.AuthBuyerID; - newData.SalePrice = args.SalePrice; - snap_selection = true; - } - } - newData.Category = args.Category; - newData.Description = args.Desc; - newData.GroupID = args.GroupID; - newData.LandingType = args.LandingType; - newData.MediaAutoScale = args.MediaAutoScale; - newData.MediaID = args.MediaID; - newData.MediaURL = args.MediaURL; - newData.MusicURL = args.MusicURL; - newData.Name = args.Name; - newData.Flags = args.ParcelFlags; - newData.PassHours = args.PassHours; - newData.PassPrice = args.PassPrice; - newData.SnapshotID = args.SnapshotID; - newData.UserLocation = args.UserLocation; - newData.UserLookAt = args.UserLookAt; - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(snap_selection); - } - } - - public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) - { - LandData newData = LandData.Copy(); - newData.OwnerID = avatarID; - newData.GroupID = groupID; - newData.IsGroupOwned = groupOwned; - //newData.auctionID = AuctionID; - newData.ClaimDate = Util.UnixTimeSinceEpoch(); - newData.ClaimPrice = claimprice; - newData.SalePrice = 0; - newData.AuthBuyerID = UUID.Zero; - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public void DeedToGroup(UUID groupID) - { - LandData newData = LandData.Copy(); - newData.OwnerID = groupID; - newData.GroupID = groupID; - newData.IsGroupOwned = true; - - // Reset show in directory flag on deed - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public bool IsEitherBannedOrRestricted(UUID avatar) - { - if (IsBannedFromLand(avatar)) - { - return true; - } - else if (IsRestrictedFromLand(avatar)) - { - return true; - } - return false; - } - - public bool HasGroupAccess(UUID avatar) - { - if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) - { - IGroupsModule groupsModule = - m_scene.RequestModuleInterface(); - - List agentGroups = new List(); - if (groupsModule != null) - { - GroupMembershipData[] GroupMembership = - groupsModule.GetMembershipData(avatar); - - if (GroupMembership != null) - { - for (int i = 0; i < GroupMembership.Length; i++) - { - if (LandData.GroupID == GroupMembership[i].GroupID) - { - return true; - } - } - } - } - } - return false; - } - - public bool IsBannedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Ban; - entry.Time = new DateTime(); - //See if they are on the list, but make sure the owner isn't banned - if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - //They are banned, so lets send them a notice about this parcel - return true; - } - } - return false; - } - - public bool IsRestrictedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Access; - entry.Time = new DateTime(); - - //If they are not on the access list and are not the owner - if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - if (!HasGroupAccess(avatar)) - { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; - } - } - } - - return false; - } - - public void SendLandUpdateToClient(IClientAPI remote_client) - { - SendLandProperties(0, false, 0, remote_client); - } - - public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) - { - SendLandProperties(0, snap_selection, 0, remote_client); - } - - public void SendLandUpdateToAvatarsOverMe() - { - SendLandUpdateToAvatarsOverMe(false); - } - - public void SendLandUpdateToAvatarsOverMe(bool snap_selection) - { - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.IsChildAgent) - return; - - ILandObject over = null; - try - { - over = - m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), - Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); - } - catch (Exception) - { - m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + - Math.Round(avatar.AbsolutePosition.Y)); - } - - if (over != null) - { - if (over.LandData.LocalID == LandData.LocalID) - { - if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && - m_scene.RegionInfo.RegionSettings.AllowDamage) - avatar.Invulnerable = false; - else - avatar.Invulnerable = true; - - SendLandUpdateToClient(snap_selection, avatar.ControllingClient); - } - } - }); - } - - #endregion - - #region AccessList Functions - - public List CreateAccessListArrayByFlag(AccessList flag) - { - List list = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) - { - if (entry.Flags == flag) - { - list.Add(entry.AgentID); - } - } - if (list.Count == 0) - { - list.Add(UUID.Zero); - } - - return list; - } - - public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, - IClientAPI remote_client) - { - - if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Access); - remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); - } - - if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Ban); - remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); - } - } - - public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) - { - LandData newData = LandData.Copy(); - - if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) - { - entries.Clear(); - } - - List toRemove = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) - { - if (entry.Flags == (AccessList)flags) - { - toRemove.Add(entry); - } - } - - foreach (ParcelManager.ParcelAccessEntry entry in toRemove) - { - newData.ParcelAccessList.Remove(entry); - } - foreach (ParcelManager.ParcelAccessEntry entry in entries) - { - ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); - temp.AgentID = entry.AgentID; - temp.Time = new DateTime(); //Pointless? Yes. - temp.Flags = (AccessList)flags; - - if (!newData.ParcelAccessList.Contains(temp)) - { - newData.ParcelAccessList.Add(temp); - } - } - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - } - - #endregion - - #region Update Functions - - public void UpdateLandBitmapByteArray() - { - LandData.Bitmap = ConvertLandBitmapToBytes(); - } - - /// - /// Update all settings in land such as area, bitmap byte array, etc - /// - public void ForceUpdateLandInfo() - { - UpdateAABBAndAreaValues(); - UpdateLandBitmapByteArray(); - } - - public void SetLandBitmapFromByteArray() - { - LandBitmap = ConvertBytesToLandBitmap(); - } - - /// - /// Updates the AABBMin and AABBMax values after area/shape modification of the land object - /// - private void UpdateAABBAndAreaValues() - { - int min_x = 64; - int min_y = 64; - int max_x = 0; - int max_y = 0; - int tempArea = 0; - int x, y; - for (x = 0; x < 64; x++) - { - for (y = 0; y < 64; y++) - { - if (LandBitmap[x, y] == true) - { - if (min_x > x) min_x = x; - if (min_y > y) min_y = y; - if (max_x < x) max_x = x; - if (max_y < y) max_y = y; - tempArea += 16; //16sqm peice of land - } - } - } - int tx = min_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - int ty = min_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMin = - new Vector3((float) (min_x * 4), (float) (min_y * 4), - (float) m_scene.Heightmap[tx, ty]); - - tx = max_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - ty = max_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMax = - new Vector3((float) (max_x * 4), (float) (max_y * 4), - (float) m_scene.Heightmap[tx, ty]); - LandData.Area = tempArea; - } - - #endregion - - #region Land Bitmap Functions - - /// - /// Sets the land's bitmap manually - /// - /// 64x64 block representing where this land is on a map - public void SetLandBitmap(bool[,] bitmap) - { - if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap"); - } - else - { - //Valid: Lets set it - LandBitmap = bitmap; - ForceUpdateLandInfo(); - } - } - - /// - /// Gets the land's bitmap manually - /// - /// - public bool[,] GetLandBitmap() - { - return LandBitmap; - } - - /// - /// Full sim land object creation - /// - /// - public bool[,] BasicFullRegionLandBitmap() - { - return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); - } - - /// - /// Used to modify the bitmap between the x and y points. Points use 64 scale - /// - /// - /// - /// - /// - /// - public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) - { - bool[,] tempBitmap = new bool[64,64]; - tempBitmap.Initialize(); - - tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); - return tempBitmap; - } - - /// - /// Change a land bitmap at within a square and set those points to a specific value - /// - /// - /// - /// - /// - /// - /// - /// - public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, - bool set_value) - { - if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (x >= start_x / 4 && x < end_x / 4 - && y >= start_y / 4 && y < end_y / 4) - { - land_bitmap[x, y] = set_value; - } - } - } - return land_bitmap; - } - - /// - /// Join the true values of 2 bitmaps together - /// - /// - /// - /// - public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) - { - if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); - } - if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (bitmap_add[x, y]) - { - bitmap_base[x, y] = true; - } - } - } - return bitmap_base; - } - - /// - /// Converts the land bitmap to a packet friendly byte array - /// - /// - private byte[] ConvertLandBitmapToBytes() - { - byte[] tempConvertArr = new byte[512]; - byte tempByte = 0; - int x, y, i, byteNum = 0; - i = 0; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); - if (i % 8 == 0) - { - tempConvertArr[byteNum] = tempByte; - tempByte = (byte) 0; - i = 0; - byteNum++; - } - } - } - return tempConvertArr; - } - - private bool[,] ConvertBytesToLandBitmap() - { - bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; - tempConvertMap.Initialize(); - byte tempByte = 0; - int x = 0, y = 0, i = 0, bitNum = 0; - for (i = 0; i < 512; i++) - { - tempByte = LandData.Bitmap[i]; - for (bitNum = 0; bitNum < 8; bitNum++) - { - bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); - tempConvertMap[x, y] = bit; - x++; - if (x > 63) - { - x = 0; - y++; - } - } - } - return tempConvertMap; - } - - #endregion - - #region Object Select and Object Owner Listing - - public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - List resultLocalIDs = new List(); - try - { - lock (primsOverMe) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.LocalId > 0) - { - if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && - obj.OwnerID != remote_client.AgentId) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) - { - resultLocalIDs.Add(obj.LocalId); - } - } - } - } - } catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); - } - - remote_client.SendForceClientSelectObjects(resultLocalIDs); - } - } - - /// - /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes - /// aggreagete details such as the number of prims. - /// - /// - /// - /// A - /// - public void SendLandObjectOwners(IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - Dictionary primCount = new Dictionary(); - List groups = new List(); - - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - try - { - if (!primCount.ContainsKey(obj.OwnerID)) - { - primCount.Add(obj.OwnerID, 0); - } - } - catch (NullReferenceException) - { - m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); - } - try - { - primCount[obj.OwnerID] += obj.PrimCount; - } - catch (KeyNotFoundException) - { - m_log.Error("[LAND]: Unable to match a prim with it's owner."); - } - if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) - groups.Add(obj.OwnerID); - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to Enumerate Land object arr."); - } - } - - remote_client.SendLandObjectOwners(LandData, groups, primCount); - } - } - - public Dictionary GetLandObjectOwners() - { - Dictionary ownersAndCount = new Dictionary(); - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (!ownersAndCount.ContainsKey(obj.OwnerID)) - { - ownersAndCount.Add(obj.OwnerID, 0); - } - ownersAndCount[obj.OwnerID] += obj.PrimCount; - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to enumerate land owners. arr."); - } - - } - return ownersAndCount; - } - - #endregion - - #region Object Returning - - public void ReturnObject(SceneObjectGroup obj) - { - SceneObjectGroup[] objs = new SceneObjectGroup[1]; - objs[0] = obj; - m_scene.returnObjects(objs, obj.OwnerID); - } - - public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) - { - Dictionary> returns = - new Dictionary>(); - - lock (primsOverMe) - { - if (type == (uint)ObjectReturnType.Owner) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID == m_landData.OwnerID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.GroupID == m_landData.GroupID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Other) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID != m_landData.OwnerID && - (obj.GroupID != m_landData.GroupID || - m_landData.GroupID == UUID.Zero)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.List) - { - List ownerlist = new List(owners); - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (ownerlist.Contains(obj.OwnerID)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - } - - foreach (List ol in returns.Values) - { - if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) - m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); - } - } - - #endregion - - #region Object Adding/Removing from Parcel - - public void ResetLandPrimCounts() - { - LandData.GroupPrims = 0; - LandData.OwnerPrims = 0; - LandData.OtherPrims = 0; - LandData.SelectedPrims = 0; - - - lock (primsOverMe) - primsOverMe.Clear(); - } - - public void AddPrimToCount(SceneObjectGroup obj) - { - - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (obj.IsSelected) - { - LandData.SelectedPrims += prim_count; - } - else - { - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims += prim_count; - } - else if ((obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) && - LandData.GroupID != UUID.Zero) - { - LandData.GroupPrims += prim_count; - } - else - { - LandData.OtherPrims += prim_count; - } - } - - lock (primsOverMe) - primsOverMe.Add(obj); - } - - public void RemovePrimFromCount(SceneObjectGroup obj) - { - lock (primsOverMe) - { - if (primsOverMe.Contains(obj)) - { - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims -= prim_count; - } - else if (obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) - { - LandData.GroupPrims -= prim_count; - } - else - { - LandData.OtherPrims -= prim_count; - } - - primsOverMe.Remove(obj); - } - } - } - - #endregion - - #endregion - - #endregion - - /// - /// Set the media url for this land parcel - /// - /// - public void SetMediaUrl(string url) - { - LandData.MediaURL = url; - SendLandUpdateToAvatarsOverMe(); - } - - /// - /// Set the music url for this land parcel - /// - /// - public void SetMusicUrl(string url) - { - LandData.MusicURL = url; - SendLandUpdateToAvatarsOverMe(); - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Land +{ + /// + /// Keeps track of a specific piece of land's information + /// + public class LandObject : ILandObject + { + #region Member Variables + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + #pragma warning disable 0429 + private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; + #pragma warning restore 0429 + private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; + + private int m_lastSeqId = 0; + + protected LandData m_landData = new LandData(); + protected Scene m_scene; + protected List primsOverMe = new List(); + + public bool[,] LandBitmap + { + get { return m_landBitmap; } + set { m_landBitmap = value; } + } + + #endregion + + #region ILandObject Members + + public LandData LandData + { + get { return m_landData; } + + set { m_landData = value; } + } + + public UUID RegionUUID + { + get { return m_scene.RegionInfo.RegionID; } + } + + #region Constructors + + public LandObject(UUID owner_id, bool is_group_owned, Scene scene) + { + m_scene = scene; + LandData.OwnerID = owner_id; + if (is_group_owned) + LandData.GroupID = owner_id; + else + LandData.GroupID = UUID.Zero; + LandData.IsGroupOwned = is_group_owned; + } + + #endregion + + #region Member Functions + + #region General Functions + + /// + /// Checks to see if this land object contains a point + /// + /// + /// + /// Returns true if the piece of land contains the specified point + public bool ContainsPoint(int x, int y) + { + if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) + { + return (LandBitmap[x / 4, y / 4] == true); + } + else + { + return false; + } + } + + public ILandObject Copy() + { + ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); + + //Place all new variables here! + newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); + newLand.LandData = LandData.Copy(); + + return newLand; + } + + static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; + static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; + + public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) + { + overrideParcelMaxPrimCount = overrideDel; + } + public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) + { + overrideSimulatorMaxPrimCount = overrideDel; + } + + public int GetParcelMaxPrimCount(ILandObject thisObject) + { + if (overrideParcelMaxPrimCount != null) + { + return overrideParcelMaxPrimCount(thisObject); + } + else + { + // Normal Calculations + return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); + } + } + public int GetSimulatorMaxPrimCount(ILandObject thisObject) + { + if (overrideSimulatorMaxPrimCount != null) + { + return overrideSimulatorMaxPrimCount(thisObject); + } + else + { + //Normal Calculations + return m_scene.RegionInfo.ObjectCapacity; + } + } + #endregion + + #region Packet Request Handling + + public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) + { + IEstateModule estateModule = m_scene.RequestModuleInterface(); + uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); + if (estateModule != null) + regionFlags = estateModule.GetRegionFlags(); + + // In a perfect world, this would have worked. + // +// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) +// regionFlags |= (uint)RegionFlags.AllowLandmark; +// if (landData.OwnerID == remote_client.AgentId) +// regionFlags |= (uint)RegionFlags.AllowSetHome; + + int seq_id; + if (snap_selection && (sequence_id == 0)) + { + seq_id = m_lastSeqId; + } + else + { + seq_id = sequence_id; + m_lastSeqId = seq_id; + } + + remote_client.SendLandProperties(seq_id, + snap_selection, request_result, LandData, + (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, + GetParcelMaxPrimCount(this), + GetSimulatorMaxPrimCount(this), regionFlags); + } + + public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) + { + //Needs later group support + bool snap_selection = false; + LandData newData = LandData.Copy(); + + if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) + { + if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) + { + newData.AuthBuyerID = args.AuthBuyerID; + newData.SalePrice = args.SalePrice; + snap_selection = true; + } + } + newData.Category = args.Category; + newData.Description = args.Desc; + newData.GroupID = args.GroupID; + newData.LandingType = args.LandingType; + newData.MediaAutoScale = args.MediaAutoScale; + newData.MediaID = args.MediaID; + newData.MediaURL = args.MediaURL; + newData.MusicURL = args.MusicURL; + newData.Name = args.Name; + newData.Flags = args.ParcelFlags; + newData.PassHours = args.PassHours; + newData.PassPrice = args.PassPrice; + newData.SnapshotID = args.SnapshotID; + newData.UserLocation = args.UserLocation; + newData.UserLookAt = args.UserLookAt; + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(snap_selection); + } + } + + public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) + { + LandData newData = LandData.Copy(); + newData.OwnerID = avatarID; + newData.GroupID = groupID; + newData.IsGroupOwned = groupOwned; + //newData.auctionID = AuctionID; + newData.ClaimDate = Util.UnixTimeSinceEpoch(); + newData.ClaimPrice = claimprice; + newData.SalePrice = 0; + newData.AuthBuyerID = UUID.Zero; + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public void DeedToGroup(UUID groupID) + { + LandData newData = LandData.Copy(); + newData.OwnerID = groupID; + newData.GroupID = groupID; + newData.IsGroupOwned = true; + + // Reset show in directory flag on deed + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public bool IsEitherBannedOrRestricted(UUID avatar) + { + if (IsBannedFromLand(avatar)) + { + return true; + } + else if (IsRestrictedFromLand(avatar)) + { + return true; + } + return false; + } + + public bool HasGroupAccess(UUID avatar) + { + if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) + { + IGroupsModule groupsModule = + m_scene.RequestModuleInterface(); + + List agentGroups = new List(); + if (groupsModule != null) + { + GroupMembershipData[] GroupMembership = + groupsModule.GetMembershipData(avatar); + + if (GroupMembership != null) + { + for (int i = 0; i < GroupMembership.Length; i++) + { + if (LandData.GroupID == GroupMembership[i].GroupID) + { + return true; + } + } + } + } + } + return false; + } + + public bool IsBannedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + //See if they are on the list, but make sure the owner isn't banned + if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + //They are banned, so lets send them a notice about this parcel + return true; + } + } + return false; + } + + public bool IsRestrictedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Access; + entry.Time = new DateTime(); + + //If they are not on the access list and are not the owner + if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + if (!HasGroupAccess(avatar)) + { + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; + } + } + } + + return false; + } + + public void SendLandUpdateToClient(IClientAPI remote_client) + { + SendLandProperties(0, false, 0, remote_client); + } + + public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) + { + SendLandProperties(0, snap_selection, 0, remote_client); + } + + public void SendLandUpdateToAvatarsOverMe() + { + SendLandUpdateToAvatarsOverMe(false); + } + + public void SendLandUpdateToAvatarsOverMe(bool snap_selection) + { + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + if (avatar.IsChildAgent) + return; + + ILandObject over = null; + try + { + over = + m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), + Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); + } + catch (Exception) + { + m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + + Math.Round(avatar.AbsolutePosition.Y)); + } + + if (over != null) + { + if (over.LandData.LocalID == LandData.LocalID) + { + if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && + m_scene.RegionInfo.RegionSettings.AllowDamage) + avatar.Invulnerable = false; + else + avatar.Invulnerable = true; + + SendLandUpdateToClient(snap_selection, avatar.ControllingClient); + } + } + }); + } + + #endregion + + #region AccessList Functions + + public List CreateAccessListArrayByFlag(AccessList flag) + { + List list = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) + { + if (entry.Flags == flag) + { + list.Add(entry.AgentID); + } + } + if (list.Count == 0) + { + list.Add(UUID.Zero); + } + + return list; + } + + public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, + IClientAPI remote_client) + { + + if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Access); + remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); + } + + if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Ban); + remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); + } + } + + public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) + { + LandData newData = LandData.Copy(); + + if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) + { + entries.Clear(); + } + + List toRemove = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) + { + if (entry.Flags == (AccessList)flags) + { + toRemove.Add(entry); + } + } + + foreach (ParcelManager.ParcelAccessEntry entry in toRemove) + { + newData.ParcelAccessList.Remove(entry); + } + foreach (ParcelManager.ParcelAccessEntry entry in entries) + { + ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); + temp.AgentID = entry.AgentID; + temp.Time = new DateTime(); //Pointless? Yes. + temp.Flags = (AccessList)flags; + + if (!newData.ParcelAccessList.Contains(temp)) + { + newData.ParcelAccessList.Add(temp); + } + } + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + } + + #endregion + + #region Update Functions + + public void UpdateLandBitmapByteArray() + { + LandData.Bitmap = ConvertLandBitmapToBytes(); + } + + /// + /// Update all settings in land such as area, bitmap byte array, etc + /// + public void ForceUpdateLandInfo() + { + UpdateAABBAndAreaValues(); + UpdateLandBitmapByteArray(); + } + + public void SetLandBitmapFromByteArray() + { + LandBitmap = ConvertBytesToLandBitmap(); + } + + /// + /// Updates the AABBMin and AABBMax values after area/shape modification of the land object + /// + private void UpdateAABBAndAreaValues() + { + int min_x = 64; + int min_y = 64; + int max_x = 0; + int max_y = 0; + int tempArea = 0; + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (LandBitmap[x, y] == true) + { + if (min_x > x) min_x = x; + if (min_y > y) min_y = y; + if (max_x < x) max_x = x; + if (max_y < y) max_y = y; + tempArea += 16; //16sqm peice of land + } + } + } + int tx = min_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + int ty = min_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMin = + new Vector3((float) (min_x * 4), (float) (min_y * 4), + (float) m_scene.Heightmap[tx, ty]); + + tx = max_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + ty = max_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMax = + new Vector3((float) (max_x * 4), (float) (max_y * 4), + (float) m_scene.Heightmap[tx, ty]); + LandData.Area = tempArea; + } + + #endregion + + #region Land Bitmap Functions + + /// + /// Sets the land's bitmap manually + /// + /// 64x64 block representing where this land is on a map + public void SetLandBitmap(bool[,] bitmap) + { + if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap"); + } + else + { + //Valid: Lets set it + LandBitmap = bitmap; + ForceUpdateLandInfo(); + } + } + + /// + /// Gets the land's bitmap manually + /// + /// + public bool[,] GetLandBitmap() + { + return LandBitmap; + } + + /// + /// Full sim land object creation + /// + /// + public bool[,] BasicFullRegionLandBitmap() + { + return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); + } + + /// + /// Used to modify the bitmap between the x and y points. Points use 64 scale + /// + /// + /// + /// + /// + /// + public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) + { + bool[,] tempBitmap = new bool[64,64]; + tempBitmap.Initialize(); + + tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); + return tempBitmap; + } + + /// + /// Change a land bitmap at within a square and set those points to a specific value + /// + /// + /// + /// + /// + /// + /// + /// + public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, + bool set_value) + { + if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (x >= start_x / 4 && x < end_x / 4 + && y >= start_y / 4 && y < end_y / 4) + { + land_bitmap[x, y] = set_value; + } + } + } + return land_bitmap; + } + + /// + /// Join the true values of 2 bitmaps together + /// + /// + /// + /// + public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) + { + if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); + } + if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (bitmap_add[x, y]) + { + bitmap_base[x, y] = true; + } + } + } + return bitmap_base; + } + + /// + /// Converts the land bitmap to a packet friendly byte array + /// + /// + private byte[] ConvertLandBitmapToBytes() + { + byte[] tempConvertArr = new byte[512]; + byte tempByte = 0; + int x, y, i, byteNum = 0; + i = 0; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); + if (i % 8 == 0) + { + tempConvertArr[byteNum] = tempByte; + tempByte = (byte) 0; + i = 0; + byteNum++; + } + } + } + return tempConvertArr; + } + + private bool[,] ConvertBytesToLandBitmap() + { + bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; + tempConvertMap.Initialize(); + byte tempByte = 0; + int x = 0, y = 0, i = 0, bitNum = 0; + for (i = 0; i < 512; i++) + { + tempByte = LandData.Bitmap[i]; + for (bitNum = 0; bitNum < 8; bitNum++) + { + bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); + tempConvertMap[x, y] = bit; + x++; + if (x > 63) + { + x = 0; + y++; + } + } + } + return tempConvertMap; + } + + #endregion + + #region Object Select and Object Owner Listing + + public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + List resultLocalIDs = new List(); + try + { + lock (primsOverMe) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.LocalId > 0) + { + if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && + obj.OwnerID != remote_client.AgentId) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) + { + resultLocalIDs.Add(obj.LocalId); + } + } + } + } + } catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); + } + + remote_client.SendForceClientSelectObjects(resultLocalIDs); + } + } + + /// + /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes + /// aggreagete details such as the number of prims. + /// + /// + /// + /// A + /// + public void SendLandObjectOwners(IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + Dictionary primCount = new Dictionary(); + List groups = new List(); + + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + try + { + if (!primCount.ContainsKey(obj.OwnerID)) + { + primCount.Add(obj.OwnerID, 0); + } + } + catch (NullReferenceException) + { + m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); + } + try + { + primCount[obj.OwnerID] += obj.PrimCount; + } + catch (KeyNotFoundException) + { + m_log.Error("[LAND]: Unable to match a prim with it's owner."); + } + if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) + groups.Add(obj.OwnerID); + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to Enumerate Land object arr."); + } + } + + remote_client.SendLandObjectOwners(LandData, groups, primCount); + } + } + + public Dictionary GetLandObjectOwners() + { + Dictionary ownersAndCount = new Dictionary(); + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (!ownersAndCount.ContainsKey(obj.OwnerID)) + { + ownersAndCount.Add(obj.OwnerID, 0); + } + ownersAndCount[obj.OwnerID] += obj.PrimCount; + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to enumerate land owners. arr."); + } + + } + return ownersAndCount; + } + + #endregion + + #region Object Returning + + public void ReturnObject(SceneObjectGroup obj) + { + SceneObjectGroup[] objs = new SceneObjectGroup[1]; + objs[0] = obj; + m_scene.returnObjects(objs, obj.OwnerID); + } + + public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) + { + Dictionary> returns = + new Dictionary>(); + + lock (primsOverMe) + { + if (type == (uint)ObjectReturnType.Owner) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID == m_landData.OwnerID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.GroupID == m_landData.GroupID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Other) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID != m_landData.OwnerID && + (obj.GroupID != m_landData.GroupID || + m_landData.GroupID == UUID.Zero)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.List) + { + List ownerlist = new List(owners); + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (ownerlist.Contains(obj.OwnerID)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + } + + foreach (List ol in returns.Values) + { + if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) + m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); + } + } + + #endregion + + #region Object Adding/Removing from Parcel + + public void ResetLandPrimCounts() + { + LandData.GroupPrims = 0; + LandData.OwnerPrims = 0; + LandData.OtherPrims = 0; + LandData.SelectedPrims = 0; + + + lock (primsOverMe) + primsOverMe.Clear(); + } + + public void AddPrimToCount(SceneObjectGroup obj) + { + + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (obj.IsSelected) + { + LandData.SelectedPrims += prim_count; + } + else + { + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims += prim_count; + } + else if ((obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) && + LandData.GroupID != UUID.Zero) + { + LandData.GroupPrims += prim_count; + } + else + { + LandData.OtherPrims += prim_count; + } + } + + lock (primsOverMe) + primsOverMe.Add(obj); + } + + public void RemovePrimFromCount(SceneObjectGroup obj) + { + lock (primsOverMe) + { + if (primsOverMe.Contains(obj)) + { + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims -= prim_count; + } + else if (obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) + { + LandData.GroupPrims -= prim_count; + } + else + { + LandData.OtherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + } + + #endregion + + #endregion + + #endregion + + /// + /// Set the media url for this land parcel + /// + /// + public void SetMediaUrl(string url) + { + LandData.MediaURL = url; + SendLandUpdateToAvatarsOverMe(); + } + + /// + /// Set the music url for this land parcel + /// + /// + public void SetMusicUrl(string url) + { + LandData.MusicURL = url; + SendLandUpdateToAvatarsOverMe(); + } + } +}