aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs151
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs80
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs131
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs120
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs3
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs7
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs38
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs29
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs65
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs2097
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs9
-rw-r--r--OpenSim/Region/DataSnapshot/ObjectSnapshot.cs15
-rw-r--r--OpenSim/Region/DataSnapshot/SnapshotStore.cs48
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs8
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs12
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEventQueue.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs189
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs39
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs98
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs205
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs152
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs68
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs143
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs19
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs35
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs9
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs173
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs38
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs106
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs1009
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs2
51 files changed, 2928 insertions, 2357 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index fa72410..105501f 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -37,6 +37,7 @@ using System.Xml;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.Packets; 39using OpenMetaverse.Packets;
40using OpenMetaverse.Messages.Linden;
40using OpenMetaverse.StructuredData; 41using OpenMetaverse.StructuredData;
41using OpenSim.Framework; 42using OpenSim.Framework;
42using OpenSim.Framework.Client; 43using OpenSim.Framework.Client;
@@ -328,7 +329,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
328 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 329 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
329 /// ownerless phantom. 330 /// ownerless phantom.
330 /// 331 ///
331 /// All manipulation of this set has to occur under a m_primFullUpdate.SyncRoot lock 332 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
332 /// 333 ///
333 /// </value> 334 /// </value>
334 protected HashSet<uint> m_killRecord; 335 protected HashSet<uint> m_killRecord;
@@ -394,18 +395,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
394 public string ActiveGroupName { get { return m_activeGroupName; } } 395 public string ActiveGroupName { get { return m_activeGroupName; } }
395 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } 396 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
396 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } 397 public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
398
397 /// <summary> 399 /// <summary>
398 /// First name of the agent/avatar represented by the client 400 /// First name of the agent/avatar represented by the client
399 /// </summary> 401 /// </summary>
400 public string FirstName { get { return m_firstName; } } 402 public string FirstName { get { return m_firstName; } }
403
401 /// <summary> 404 /// <summary>
402 /// Last name of the agent/avatar represented by the client 405 /// Last name of the agent/avatar represented by the client
403 /// </summary> 406 /// </summary>
404 public string LastName { get { return m_lastName; } } 407 public string LastName { get { return m_lastName; } }
408
405 /// <summary> 409 /// <summary>
406 /// Full name of the client (first name and last name) 410 /// Full name of the client (first name and last name)
407 /// </summary> 411 /// </summary>
408 public string Name { get { return FirstName + " " + LastName; } } 412 public string Name { get { return FirstName + " " + LastName; } }
413
409 public uint CircuitCode { get { return m_circuitCode; } } 414 public uint CircuitCode { get { return m_circuitCode; } }
410 public int MoneyBalance { get { return m_moneyBalance; } } 415 public int MoneyBalance { get { return m_moneyBalance; } }
411 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } 416 public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
@@ -742,7 +747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
742 handshake.RegionInfo3.CPURatio = 1; 747 handshake.RegionInfo3.CPURatio = 1;
743 748
744 handshake.RegionInfo3.ColoName = Utils.EmptyBytes; 749 handshake.RegionInfo3.ColoName = Utils.EmptyBytes;
745 handshake.RegionInfo3.ProductName = Utils.EmptyBytes; 750 handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
746 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; 751 handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
747 752
748 OutPacket(handshake, ThrottleOutPacketType.Task); 753 OutPacket(handshake, ThrottleOutPacketType.Task);
@@ -2743,7 +2748,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2743 DirPlacesReplyPacket.StatusDataBlock[] status = 2748 DirPlacesReplyPacket.StatusDataBlock[] status =
2744 new DirPlacesReplyPacket.StatusDataBlock[0]; 2749 new DirPlacesReplyPacket.StatusDataBlock[0];
2745 2750
2746 int i = 0; 2751 packet.QueryReplies = replies;
2752 packet.StatusData = status;
2753
2747 foreach (DirPlacesReplyData d in data) 2754 foreach (DirPlacesReplyData d in data)
2748 { 2755 {
2749 int idx = replies.Length; 2756 int idx = replies.Length;
@@ -2779,11 +2786,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2779 2786
2780 replies = new DirPlacesReplyPacket.QueryRepliesBlock[0]; 2787 replies = new DirPlacesReplyPacket.QueryRepliesBlock[0];
2781 status = new DirPlacesReplyPacket.StatusDataBlock[0]; 2788 status = new DirPlacesReplyPacket.StatusDataBlock[0];
2782
2783 } 2789 }
2784 } 2790 }
2785 2791
2786 if (replies.Length > 0) 2792 if (replies.Length > 0 || data.Length == 0)
2787 OutPacket(packet, ThrottleOutPacketType.Task); 2793 OutPacket(packet, ThrottleOutPacketType.Task);
2788 } 2794 }
2789 2795
@@ -4143,7 +4149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4143 rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue; 4149 rinfopack.RegionInfo2.HardMaxAgents = uint.MaxValue;
4144 rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue; 4150 rinfopack.RegionInfo2.HardMaxObjects = uint.MaxValue;
4145 rinfopack.RegionInfo2.MaxAgents32 = uint.MaxValue; 4151 rinfopack.RegionInfo2.MaxAgents32 = uint.MaxValue;
4146 rinfopack.RegionInfo2.ProductName = Utils.EmptyBytes; 4152 rinfopack.RegionInfo2.ProductName = Util.StringToBytes256(args.regionType);
4147 rinfopack.RegionInfo2.ProductSKU = Utils.EmptyBytes; 4153 rinfopack.RegionInfo2.ProductSKU = Utils.EmptyBytes;
4148 4154
4149 rinfopack.HasVariableBlocks = true; 4155 rinfopack.HasVariableBlocks = true;
@@ -4215,94 +4221,101 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4215 4221
4216 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, LandData landData, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags) 4222 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, LandData landData, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
4217 { 4223 {
4218 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ParcelProperties); 4224 ParcelPropertiesMessage updateMessage = new ParcelPropertiesMessage();
4219 // TODO: don't create new blocks if recycling an old packet
4220 4225
4221 updatePacket.ParcelData.AABBMax = landData.AABBMax; 4226 updateMessage.AABBMax = landData.AABBMax;
4222 updatePacket.ParcelData.AABBMin = landData.AABBMin; 4227 updateMessage.AABBMin = landData.AABBMin;
4223 updatePacket.ParcelData.Area = landData.Area; 4228 updateMessage.Area = landData.Area;
4224 updatePacket.ParcelData.AuctionID = landData.AuctionID; 4229 updateMessage.AuctionID = landData.AuctionID;
4225 updatePacket.ParcelData.AuthBuyerID = landData.AuthBuyerID; 4230 updateMessage.AuthBuyerID = landData.AuthBuyerID;
4226 4231
4227 updatePacket.ParcelData.Bitmap = landData.Bitmap; 4232 updateMessage.Bitmap = landData.Bitmap;
4228 4233
4229 updatePacket.ParcelData.Desc = Utils.StringToBytes(landData.Description); 4234 updateMessage.Desc = landData.Description;
4230 updatePacket.ParcelData.Category = (byte)landData.Category; 4235 updateMessage.Category = landData.Category;
4231 updatePacket.ParcelData.ClaimDate = landData.ClaimDate; 4236 updateMessage.ClaimDate = Util.ToDateTime(landData.ClaimDate);
4232 updatePacket.ParcelData.ClaimPrice = landData.ClaimPrice; 4237 updateMessage.ClaimPrice = landData.ClaimPrice;
4233 updatePacket.ParcelData.GroupID = landData.GroupID; 4238 updateMessage.GroupID = landData.GroupID;
4234 updatePacket.ParcelData.GroupPrims = landData.GroupPrims; 4239 updateMessage.GroupPrims = landData.GroupPrims;
4235 updatePacket.ParcelData.IsGroupOwned = landData.IsGroupOwned; 4240 updateMessage.IsGroupOwned = landData.IsGroupOwned;
4236 updatePacket.ParcelData.LandingType = landData.LandingType; 4241 updateMessage.LandingType = (LandingType) landData.LandingType;
4237 updatePacket.ParcelData.LocalID = landData.LocalID; 4242 updateMessage.LocalID = landData.LocalID;
4238 4243
4239 if (landData.Area > 0) 4244 if (landData.Area > 0)
4240 { 4245 {
4241 updatePacket.ParcelData.MaxPrims = parcelObjectCapacity; 4246 updateMessage.MaxPrims = parcelObjectCapacity;
4242 } 4247 }
4243 else 4248 else
4244 { 4249 {
4245 updatePacket.ParcelData.MaxPrims = 0; 4250 updateMessage.MaxPrims = 0;
4246 } 4251 }
4247 4252
4248 updatePacket.ParcelData.MediaAutoScale = landData.MediaAutoScale; 4253 updateMessage.MediaAutoScale = Convert.ToBoolean(landData.MediaAutoScale);
4249 updatePacket.ParcelData.MediaID = landData.MediaID; 4254 updateMessage.MediaID = landData.MediaID;
4250 updatePacket.ParcelData.MediaURL = Util.StringToBytes256(landData.MediaURL); 4255 updateMessage.MediaURL = landData.MediaURL;
4251 updatePacket.ParcelData.MusicURL = Util.StringToBytes256(landData.MusicURL); 4256 updateMessage.MusicURL = landData.MusicURL;
4252 updatePacket.ParcelData.Name = Util.StringToBytes256(landData.Name); 4257 updateMessage.Name = landData.Name;
4253 updatePacket.ParcelData.OtherCleanTime = landData.OtherCleanTime; 4258 updateMessage.OtherCleanTime = landData.OtherCleanTime;
4254 updatePacket.ParcelData.OtherCount = 0; //TODO: Unimplemented 4259 updateMessage.OtherCount = 0; //TODO: Unimplemented
4255 updatePacket.ParcelData.OtherPrims = landData.OtherPrims; 4260 updateMessage.OtherPrims = landData.OtherPrims;
4256 updatePacket.ParcelData.OwnerID = landData.OwnerID; 4261 updateMessage.OwnerID = landData.OwnerID;
4257 updatePacket.ParcelData.OwnerPrims = landData.OwnerPrims; 4262 updateMessage.OwnerPrims = landData.OwnerPrims;
4258 updatePacket.ParcelData.ParcelFlags = landData.Flags; 4263 updateMessage.ParcelFlags = (ParcelFlags) landData.Flags;
4259 updatePacket.ParcelData.ParcelPrimBonus = simObjectBonusFactor; 4264 updateMessage.ParcelPrimBonus = simObjectBonusFactor;
4260 updatePacket.ParcelData.PassHours = landData.PassHours; 4265 updateMessage.PassHours = landData.PassHours;
4261 updatePacket.ParcelData.PassPrice = landData.PassPrice; 4266 updateMessage.PassPrice = landData.PassPrice;
4262 updatePacket.ParcelData.PublicCount = 0; //TODO: Unimplemented 4267 updateMessage.PublicCount = 0; //TODO: Unimplemented
4263 4268
4264 updatePacket.ParcelData.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0; 4269 updateMessage.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0;
4265 updatePacket.ParcelData.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0; 4270 updateMessage.RegionDenyAnonymous = (regionFlags & (uint)RegionFlags.DenyAnonymous) > 0;
4266 updatePacket.ParcelData.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0; 4271
4267 updatePacket.ParcelData.RegionPushOverride = (regionFlags & (uint)RegionFlags.RestrictPushObject) > 0; 4272 //updateMessage.RegionDenyIdentified = (regionFlags & (uint)RegionFlags.DenyIdentified) > 0;
4268 4273 //updateMessage.RegionDenyTransacted = (regionFlags & (uint)RegionFlags.DenyTransacted) > 0;
4269 updatePacket.ParcelData.RentPrice = 0; 4274
4270 updatePacket.ParcelData.RequestResult = request_result; 4275 updateMessage.RentPrice = 0;
4271 updatePacket.ParcelData.SalePrice = landData.SalePrice; 4276 updateMessage.RequestResult = (ParcelResult) request_result;
4272 updatePacket.ParcelData.SelectedPrims = landData.SelectedPrims; 4277 updateMessage.SalePrice = landData.SalePrice;
4273 updatePacket.ParcelData.SelfCount = 0; //TODO: Unimplemented 4278 updateMessage.SelectedPrims = landData.SelectedPrims;
4274 updatePacket.ParcelData.SequenceID = sequence_id; 4279 updateMessage.SelfCount = 0; //TODO: Unimplemented
4280 updateMessage.SequenceID = sequence_id;
4275 if (landData.SimwideArea > 0) 4281 if (landData.SimwideArea > 0)
4276 { 4282 {
4277 updatePacket.ParcelData.SimWideMaxPrims = parcelObjectCapacity; 4283 updateMessage.SimWideMaxPrims = parcelObjectCapacity;
4278 } 4284 }
4279 else 4285 else
4280 { 4286 {
4281 updatePacket.ParcelData.SimWideMaxPrims = 0; 4287 updateMessage.SimWideMaxPrims = 0;
4282 } 4288 }
4283 updatePacket.ParcelData.SimWideTotalPrims = landData.SimwidePrims; 4289 updateMessage.SimWideTotalPrims = landData.SimwidePrims;
4284 updatePacket.ParcelData.SnapSelection = snap_selection; 4290 updateMessage.SnapSelection = snap_selection;
4285 updatePacket.ParcelData.SnapshotID = landData.SnapshotID; 4291 updateMessage.SnapshotID = landData.SnapshotID;
4286 updatePacket.ParcelData.Status = (byte)landData.Status; 4292 updateMessage.Status = (ParcelStatus) landData.Status;
4287 updatePacket.ParcelData.TotalPrims = landData.OwnerPrims + landData.GroupPrims + landData.OtherPrims + 4293 updateMessage.TotalPrims = landData.OwnerPrims + landData.GroupPrims + landData.OtherPrims +
4288 landData.SelectedPrims; 4294 landData.SelectedPrims;
4289 updatePacket.ParcelData.UserLocation = landData.UserLocation; 4295 updateMessage.UserLocation = landData.UserLocation;
4290 updatePacket.ParcelData.UserLookAt = landData.UserLookAt; 4296 updateMessage.UserLookAt = landData.UserLookAt;
4291 updatePacket.Header.Zerocoded = true; 4297
4298 updateMessage.MediaType = landData.MediaType;
4299 updateMessage.MediaDesc = landData.MediaDescription;
4300 updateMessage.MediaWidth = landData.MediaWidth;
4301 updateMessage.MediaHeight = landData.MediaHeight;
4302 updateMessage.MediaLoop = landData.MediaLoop;
4303 updateMessage.ObscureMusic = landData.ObscureMusic;
4304 updateMessage.ObscureMedia = landData.ObscureMedia;
4292 4305
4293 try 4306 try
4294 { 4307 {
4295 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); 4308 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
4296 if (eq != null) 4309 if (eq != null)
4297 { 4310 {
4298 eq.ParcelProperties(updatePacket, this.AgentId); 4311 eq.ParcelProperties(updateMessage, this.AgentId);
4299 } 4312 } else {
4313 m_log.Warn("No EQ Interface when sending parcel data.");
4314 }
4300 } 4315 }
4301 catch (Exception ex) 4316 catch (Exception ex)
4302 { 4317 {
4303 m_log.Error("Unable to send parcel data via eventqueue - exception: " + ex.ToString()); 4318 m_log.Error("Unable to send parcel data via eventqueue - exception: " + ex.ToString());
4304 m_log.Warn("sending parcel data via UDP");
4305 OutPacket(updatePacket, ThrottleOutPacketType.Task);
4306 } 4319 }
4307 } 4320 }
4308 4321
@@ -8995,7 +9008,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8995 if (handlerGodKickUser != null) 9008 if (handlerGodKickUser != null)
8996 { 9009 {
8997 handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID, 9010 handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID,
8998 gkupack.UserInfo.AgentID, (uint)0, gkupack.UserInfo.Reason); 9011 gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
8999 } 9012 }
9000 } 9013 }
9001 else 9014 else
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index c802490..38152cc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -427,7 +427,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
427 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 427 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
428 { 428 {
429 if (!m_scene.Permissions.CanRezObject( 429 if (!m_scene.Permissions.CanRezObject(
430 part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition)) 430 part.ParentGroup.PrimCount, remoteClient.AgentId, presence.AbsolutePosition))
431 return; 431 return;
432 432
433 presence.Appearance.DetachAttachment(itemID); 433 presence.Appearance.DetachAttachment(itemID);
@@ -471,12 +471,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
471 SceneObjectSerializer.ToOriginalXmlFormat(group); 471 SceneObjectSerializer.ToOriginalXmlFormat(group);
472 group.DetachToInventoryPrep(); 472 group.DetachToInventoryPrep();
473 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 473 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
474 m_scene.UpdateKnownItem(remoteClient, group,group.GetFromItemID(), group.OwnerID); 474 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID);
475 m_scene.DeleteSceneObject(group, false); 475 m_scene.DeleteSceneObject(group, false);
476 return; 476 return;
477 } 477 }
478 } 478 }
479 } 479 }
480 } 480 }
481
482 public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos)
483 {
484 // If this is an attachment, then we need to save the modified
485 // object back into the avatar's inventory. First we save the
486 // attachment point information, then we update the relative
487 // positioning (which caused this method to get driven in the
488 // first place. Then we have to mark the object as NOT an
489 // attachment. This is necessary in order to correctly save
490 // and retrieve GroupPosition information for the attachment.
491 // Then we save the asset back into the appropriate inventory
492 // entry. Finally, we restore the object's attachment status.
493 byte attachmentPoint = sog.GetAttachmentPoint();
494 sog.UpdateGroupPosition(pos);
495 sog.RootPart.IsAttachment = false;
496 sog.AbsolutePosition = sog.RootPart.AttachedPos;
497 UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID);
498 sog.SetAttachmentPoint(attachmentPoint);
499 }
500
501 /// <summary>
502 /// Update the attachment asset for the new sog details if they have changed.
503 /// </summary>
504 ///
505 /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects,
506 /// these details are not stored on the region.
507 ///
508 /// <param name="remoteClient"></param>
509 /// <param name="grp"></param>
510 /// <param name="itemID"></param>
511 /// <param name="agentID"></param>
512 protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
513 {
514 if (grp != null)
515 {
516 if (!grp.HasGroupChanged)
517 {
518 m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID);
519 return;
520 }
521
522 m_log.DebugFormat(
523 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
524 grp.UUID, grp.GetAttachmentPoint());
525
526 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
527
528 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
529 item = m_scene.InventoryService.GetItem(item);
530
531 if (item != null)
532 {
533 AssetBase asset = m_scene.CreateAsset(
534 grp.GetPartName(grp.LocalId),
535 grp.GetPartDescription(grp.LocalId),
536 (sbyte)AssetType.Object,
537 Utils.StringToBytes(sceneObjectXml),
538 remoteClient.AgentId);
539 m_scene.AssetService.Store(asset);
540
541 item.AssetID = asset.FullID;
542 item.Description = asset.Description;
543 item.Name = asset.Name;
544 item.AssetType = asset.Type;
545 item.InvType = (int)InventoryType.Object;
546
547 m_scene.InventoryService.UpdateItem(item);
548
549 // this gets called when the agent logs off!
550 if (remoteClient != null)
551 remoteClient.SendInventoryItemCreateUpdate(item, 0);
552 }
553 }
554 }
481 } 555 }
482} 556} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index 1603c07..fc1afaf 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -223,4 +223,4 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
223 OnInstantMessage(null, msg); 223 OnInstantMessage(null, msg);
224 } 224 }
225 } 225 }
226} 226} \ 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 e1ee0b1..a49faec 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -132,8 +132,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
132 { 132 {
133 UUID toAgentID = new UUID(im.toAgentID); 133 UUID toAgentID = new UUID(im.toAgentID);
134 134
135 //m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString());
136
137 // Try root avatar only first 135 // Try root avatar only first
138 foreach (Scene scene in m_Scenes) 136 foreach (Scene scene in m_Scenes)
139 { 137 {
@@ -176,6 +174,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
176 } 174 }
177 } 175 }
178 176
177 m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
179 SendGridInstantMessageViaXMLRPC(im, result); 178 SendGridInstantMessageViaXMLRPC(im, result);
180 179
181 return; 180 return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 7683288..22c84e9 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
261 261
262 while (archivePath.Length > 0) 262 while (archivePath.Length > 0)
263 { 263 {
264 m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath); 264// m_log.DebugFormat("[INVENTORY ARCHIVER]: Trying to resolve destination folder {0}", archivePath);
265 265
266 if (resolvedFolders.ContainsKey(archivePath)) 266 if (resolvedFolders.ContainsKey(archivePath))
267 { 267 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index 84afb40..8343091 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
41 /// </summary> 41 /// </summary>
42 public static class InventoryArchiveUtils 42 public static class InventoryArchiveUtils
43 { 43 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings 46 // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings
47 public static readonly char ESCAPE_CHARACTER = '\\'; 47 public static readonly char ESCAPE_CHARACTER = '\\';
@@ -120,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
120 foundFolders.Add(startFolder); 120 foundFolders.Add(startFolder);
121 return foundFolders; 121 return foundFolders;
122 } 122 }
123
124 // If the path isn't just / then trim any starting extraneous slashes
125 path = path.TrimStart(new char[] { PATH_DELIMITER });
126
127// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Adjusted path in FindFolderByPath() is [{0}]", path);
123 128
124 string[] components = SplitEscapedPath(path); 129 string[] components = SplitEscapedPath(path);
125 components[0] = UnescapePath(components[0]); 130 components[0] = UnescapePath(components[0]);
@@ -199,6 +204,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
199 public static InventoryItemBase FindItemByPath( 204 public static InventoryItemBase FindItemByPath(
200 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 205 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
201 { 206 {
207 // If the path isn't just / then trim any starting extraneous slashes
208 path = path.TrimStart(new char[] { PATH_DELIMITER });
209
202 string[] components = SplitEscapedPath(path); 210 string[] components = SplitEscapedPath(path);
203 components[0] = UnescapePath(components[0]); 211 components[0] = UnescapePath(components[0]);
204 212
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 25a78ff..9908018 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
221 InventoryItemBase inventoryItem = null; 221 InventoryItemBase inventoryItem = null;
222 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); 222 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID);
223 223
224 bool foundStar = false; 224 bool saveFolderContentsOnly = false;
225 225
226 // Eliminate double slashes and any leading / on the path. 226 // Eliminate double slashes and any leading / on the path.
227 string[] components 227 string[] components
@@ -234,7 +234,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
234 // folder itself. This may get more sophisicated later on 234 // folder itself. This may get more sophisicated later on
235 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) 235 if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
236 { 236 {
237 foundStar = true; 237 saveFolderContentsOnly = true;
238 maxComponentIndex--; 238 maxComponentIndex--;
239 } 239 }
240 240
@@ -281,10 +281,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
281 { 281 {
282 m_log.DebugFormat( 282 m_log.DebugFormat(
283 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", 283 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
284 inventoryFolder.Name, inventoryFolder.ID, m_invPath); 284 inventoryFolder.Name,
285 inventoryFolder.ID,
286 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath );
285 287
286 //recurse through all dirs getting dirs and files 288 //recurse through all dirs getting dirs and files
287 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); 289 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly);
288 } 290 }
289 else if (inventoryItem != null) 291 else if (inventoryItem != null)
290 { 292 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 3fb2c8c..0218f86 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
55 { 55 {
56 protected ManualResetEvent mre = new ManualResetEvent(false); 56 protected ManualResetEvent mre = new ManualResetEvent(false);
57 57
58 /// <summary>
59 /// Stream of data representing a common IAR that can be reused in load tests.
60 /// </summary>
61 protected MemoryStream m_iarStream;
62
63 protected UserAccount m_ua1
64 = new UserAccount {
65 PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"),
66 FirstName = "Mr",
67 LastName = "Tiddles" };
68 protected UserAccount m_ua2
69 = new UserAccount {
70 PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"),
71 FirstName = "Lord",
72 LastName = "Lucan" };
73 string m_item1Name = "b.lsl";
74
58 private void SaveCompleted( 75 private void SaveCompleted(
59 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, 76 Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
60 Exception reportedException) 77 Exception reportedException)
61 { 78 {
62 mre.Set(); 79 mre.Set();
63 } 80 }
81
82 [SetUp]
83 public void Init()
84 {
85 ConstructDefaultIarForTestLoad();
86 }
87
88 protected void ConstructDefaultIarForTestLoad()
89 {
90 string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(m_item1Name, UUID.Random());
91
92 MemoryStream archiveWriteStream = new MemoryStream();
93 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
94
95 InventoryItemBase item1 = new InventoryItemBase();
96 item1.Name = m_item1Name;
97 item1.AssetID = UUID.Random();
98 item1.GroupID = UUID.Random();
99 item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
100 //item1.CreatorId = userUuid.ToString();
101 //item1.CreatorId = "00000000-0000-0000-0000-000000000444";
102 item1.Owner = UUID.Zero;
103
104 string item1FileName
105 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
106 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
107 tar.Close();
108 m_iarStream = new MemoryStream(archiveWriteStream.ToArray());
109 }
64 110
65 /// <summary> 111 /// <summary>
66 /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive 112 /// Test saving an inventory path to a V0.1 OpenSim Inventory Archive
@@ -122,6 +168,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
122 MemoryStream archiveWriteStream = new MemoryStream(); 168 MemoryStream archiveWriteStream = new MemoryStream();
123 archiverModule.OnInventoryArchiveSaved += SaveCompleted; 169 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
124 170
171 // Test saving a particular path
125 mre.Reset(); 172 mre.Reset();
126 archiverModule.ArchiveInventory( 173 archiverModule.ArchiveInventory(
127 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); 174 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
@@ -148,7 +195,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
148 195
149 while (tar.ReadEntry(out filePath, out tarEntryType) != null) 196 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
150 { 197 {
151 Console.WriteLine("Got {0}", filePath); 198// Console.WriteLine("Got {0}", filePath);
152 199
153// if (ArchiveConstants.CONTROL_FILE_PATH == filePath) 200// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
154// { 201// {
@@ -297,6 +344,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
297 } 344 }
298 345
299 /// <summary> 346 /// <summary>
347 /// Test that things work when the load path specified starts with a slash
348 /// </summary>
349 [Test]
350 public void TestLoadIarPathStartsWithSlash()
351 {
352 TestHelper.InMethod();
353// log4net.Config.XmlConfigurator.Configure();
354
355 SerialiserModule serialiserModule = new SerialiserModule();
356 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
357 Scene scene = SceneSetupHelpers.SetupScene("inventory");
358 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
359
360 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "password");
361 archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/Objects", "password", m_iarStream);
362
363 InventoryItemBase foundItem1
364 = InventoryArchiveUtils.FindItemByPath(
365 scene.InventoryService, m_ua1.PrincipalID, "/Objects/" + m_item1Name);
366
367 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()");
368 }
369
370 /// <summary>
300 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 371 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
301 /// an account exists with the creator name. 372 /// an account exists with the creator name.
302 /// </summary> 373 /// </summary>
@@ -308,34 +379,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
308 TestHelper.InMethod(); 379 TestHelper.InMethod();
309 //log4net.Config.XmlConfigurator.Configure(); 380 //log4net.Config.XmlConfigurator.Configure();
310 381
311 string userFirstName = "Mr";
312 string userLastName = "Tiddles";
313 UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000555");
314 string userItemCreatorFirstName = "Lord";
315 string userItemCreatorLastName = "Lucan";
316 UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
317
318 string item1Name = "b.lsl";
319 string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random());
320
321 MemoryStream archiveWriteStream = new MemoryStream();
322 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
323
324 InventoryItemBase item1 = new InventoryItemBase();
325 item1.Name = item1Name;
326 item1.AssetID = UUID.Random();
327 item1.GroupID = UUID.Random();
328 item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
329 //item1.CreatorId = userUuid.ToString();
330 //item1.CreatorId = "00000000-0000-0000-0000-000000000444";
331 item1.Owner = UUID.Zero;
332
333 string item1FileName
334 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
335 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
336 tar.Close();
337
338 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
339 SerialiserModule serialiserModule = new SerialiserModule(); 382 SerialiserModule serialiserModule = new SerialiserModule();
340 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); 383 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
341 384
@@ -344,15 +387,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
344 387
345 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 388 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
346 389
347 UserProfileTestUtils.CreateUserWithInventory( 390 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood");
348 scene, userFirstName, userLastName, userUuid, "meowfood"); 391 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
349 UserProfileTestUtils.CreateUserWithInventory(
350 scene, userItemCreatorFirstName, userItemCreatorLastName, userItemCreatorUuid, "hampshire");
351 392
352 archiverModule.DearchiveInventory(userFirstName, userLastName, "/", "meowfood", archiveReadStream); 393 archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "meowfood", m_iarStream);
353 394
354 InventoryItemBase foundItem1 395 InventoryItemBase foundItem1
355 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, item1Name); 396 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name);
356 397
357 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); 398 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
358 399
@@ -362,31 +403,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
362// foundItem1.CreatorId, Is.EqualTo(item1.CreatorId), 403// foundItem1.CreatorId, Is.EqualTo(item1.CreatorId),
363// "Loaded item non-uuid creator doesn't match original"); 404// "Loaded item non-uuid creator doesn't match original");
364 Assert.That( 405 Assert.That(
365 foundItem1.CreatorId, Is.EqualTo(userItemCreatorUuid.ToString()), 406 foundItem1.CreatorId, Is.EqualTo(m_ua2.PrincipalID.ToString()),
366 "Loaded item non-uuid creator doesn't match original"); 407 "Loaded item non-uuid creator doesn't match original");
367 408
368 Assert.That( 409 Assert.That(
369 foundItem1.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid), 410 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_ua2.PrincipalID),
370 "Loaded item uuid creator doesn't match original"); 411 "Loaded item uuid creator doesn't match original");
371 Assert.That(foundItem1.Owner, Is.EqualTo(userUuid), 412 Assert.That(foundItem1.Owner, Is.EqualTo(m_ua1.PrincipalID),
372 "Loaded item owner doesn't match inventory reciever"); 413 "Loaded item owner doesn't match inventory reciever");
373 414
374 // Now try loading to a root child folder 415 // Now try loading to a root child folder
375 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xA"); 416 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xA");
376 archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); 417 MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
377 archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream); 418 archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xA", "meowfood", archiveReadStream);
378 419
379 InventoryItemBase foundItem2 420 InventoryItemBase foundItem2
380 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xA/" + item1Name); 421 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xA/" + m_item1Name);
381 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); 422 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
382 423
383 // Now try loading to a more deeply nested folder 424 // Now try loading to a more deeply nested folder
384 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, userUuid, "xB/xC"); 425 UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xB/xC");
385 archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); 426 archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
386 archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream); 427 archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xB/xC", "meowfood", archiveReadStream);
387 428
388 InventoryItemBase foundItem3 429 InventoryItemBase foundItem3
389 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userUuid, "xB/xC/" + item1Name); 430 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xB/xC/" + m_item1Name);
390 Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); 431 Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
391 } 432 }
392 433
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 4465e8a..a08a628 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;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35
36using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
@@ -92,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
92 m_TransferModule = m_Scenelist[0].RequestModuleInterface<IMessageTransferModule>(); 91 m_TransferModule = m_Scenelist[0].RequestModuleInterface<IMessageTransferModule>();
93 if (m_TransferModule == null) 92 if (m_TransferModule == null)
94 { 93 {
95 m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); 94 m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only");
96 m_Enabled = false; 95 m_Enabled = false;
97 96
98 m_Scenelist.Clear(); 97 m_Scenelist.Clear();
@@ -185,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
185 { 184 {
186 UUID folderID = new UUID(im.binaryBucket, 1); 185 UUID folderID = new UUID(im.binaryBucket, 1);
187 186
188 m_log.DebugFormat("[AGENT INVENTORY]: Inserting original folder {0} "+ 187 m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} "+
189 "into agent {1}'s inventory", 188 "into agent {1}'s inventory",
190 folderID, new UUID(im.toAgentID)); 189 folderID, new UUID(im.toAgentID));
191 190
@@ -221,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
221 220
222 UUID itemID = new UUID(im.binaryBucket, 1); 221 UUID itemID = new UUID(im.binaryBucket, 1);
223 222
224 m_log.DebugFormat("[AGENT INVENTORY]: (giving) Inserting item {0} "+ 223 m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} "+
225 "into agent {1}'s inventory", 224 "into agent {1}'s inventory",
226 itemID, new UUID(im.toAgentID)); 225 itemID, new UUID(im.toAgentID));
227 226
@@ -288,10 +287,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
288 // inventory is loaded. Courtesy of the above bulk update, 287 // inventory is loaded. Courtesy of the above bulk update,
289 // It will have been pushed to the client, too 288 // It will have been pushed to the client, too
290 // 289 //
291
292 //CachedUserInfo userInfo =
293 // scene.CommsManager.UserProfileCacheService.
294 // GetUserDetails(client.AgentId);
295 IInventoryService invService = scene.InventoryService; 290 IInventoryService invService = scene.InventoryService;
296 291
297 InventoryFolderBase trashFolder = 292 InventoryFolderBase trashFolder =
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index d6f37ae..1cd2ff4 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
200 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", 200 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}",
201 finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID); 201 finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID);
202 202
203 // Check that these are not the same coordinates
204 if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX &&
205 finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY)
206 {
207 // Can't do. Viewer crashes
208 sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again.");
209 return;
210 }
211
203 // 212 //
204 // This is it 213 // This is it
205 // 214 //
@@ -446,6 +455,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
446 // Now let's make it officially a child agent 455 // Now let's make it officially a child agent
447 sp.MakeChildAgent(); 456 sp.MakeChildAgent();
448 457
458 sp.Scene.CleanDroppedAttachments();
459
449 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 460 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
450 461
451 if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 462 if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs
index 0c6cb1b..35b70de 100644
--- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs
@@ -34,6 +34,7 @@ using System.Threading;
34using log4net; 34using log4net;
35using Nini.Config; 35using Nini.Config;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.Messages.Linden;
37using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
38using OpenMetaverse.StructuredData; 39using OpenMetaverse.StructuredData;
39using OpenSim.Framework; 40using OpenSim.Framework;
@@ -137,10 +138,11 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
137 { 138 {
138 if (!queues.ContainsKey(agentId)) 139 if (!queues.ContainsKey(agentId))
139 { 140 {
141 /*
140 m_log.DebugFormat( 142 m_log.DebugFormat(
141 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", 143 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
142 agentId, m_scene.RegionInfo.RegionName); 144 agentId, m_scene.RegionInfo.RegionName);
143 145 */
144 queues[agentId] = new Queue<OSD>(); 146 queues[agentId] = new Queue<OSD>();
145 } 147 }
146 148
@@ -200,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
200 202
201 private void ClientClosed(UUID AgentID, Scene scene) 203 private void ClientClosed(UUID AgentID, Scene scene)
202 { 204 {
203 m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName); 205 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
204 206
205 int count = 0; 207 int count = 0;
206 while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) 208 while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
@@ -284,7 +286,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
284 // Reuse open queues. The client does! 286 // Reuse open queues. The client does!
285 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) 287 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
286 { 288 {
287 m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); 289 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
288 EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; 290 EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
289 } 291 }
290 else 292 else
@@ -365,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
365 { 367 {
366 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! 368 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
367 array.Add(EventQueueHelper.KeepAliveEvent()); 369 array.Add(EventQueueHelper.KeepAliveEvent());
368 m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName); 370 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
369 } 371 }
370 else 372 else
371 { 373 {
@@ -394,8 +396,8 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
394 responsedata["keepalive"] = false; 396 responsedata["keepalive"] = false;
395 responsedata["reusecontext"] = false; 397 responsedata["reusecontext"] = false;
396 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); 398 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
399 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
397 return responsedata; 400 return responsedata;
398 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
399 } 401 }
400 402
401 public Hashtable NoEvents(UUID requestID, UUID agentID) 403 public Hashtable NoEvents(UUID requestID, UUID agentID)
@@ -461,7 +463,7 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
461 { 463 {
462 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say! 464 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
463 array.Add(EventQueueHelper.KeepAliveEvent()); 465 array.Add(EventQueueHelper.KeepAliveEvent());
464 m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 466 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
465 } 467 }
466 else 468 else
467 { 469 {
@@ -697,9 +699,9 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
697 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 699 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
698 } 700 }
699 701
700 public void ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket, UUID avatarID) 702 public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID)
701 { 703 {
702 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesPacket); 704 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage);
703 Enqueue(item, avatarID); 705 Enqueue(item, avatarID);
704 } 706 }
705 707
diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs
index e9bcae3..6294935 100644
--- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueHelper.cs
@@ -30,6 +30,7 @@ using System.Net;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenMetaverse.Packets; 31using OpenMetaverse.Packets;
32using OpenMetaverse.StructuredData; 32using OpenMetaverse.StructuredData;
33using OpenMetaverse.Messages.Linden;
33 34
34namespace OpenSim.Region.CoreModules.Framework.EventQueue 35namespace OpenSim.Region.CoreModules.Framework.EventQueue
35{ 36{
@@ -309,116 +310,6 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
309 return chatterBoxSessionAgentListUpdates; 310 return chatterBoxSessionAgentListUpdates;
310 } 311 }
311 312
312 public static OSD ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket)
313 {
314 OSDMap parcelProperties = new OSDMap();
315 OSDMap body = new OSDMap();
316
317 OSDArray ageVerificationBlock = new OSDArray();
318 OSDMap ageVerificationMap = new OSDMap();
319 ageVerificationMap.Add("RegionDenyAgeUnverified",
320 OSD.FromBoolean(parcelPropertiesPacket.AgeVerificationBlock.RegionDenyAgeUnverified));
321 ageVerificationBlock.Add(ageVerificationMap);
322 body.Add("AgeVerificationBlock", ageVerificationBlock);
323
324 // LL sims send media info in this event queue message but it's not in the UDP
325 // packet we construct this event queue message from. This should be refactored in
326 // other areas of the code so it can all be send in the same message. Until then we will
327 // still send the media info via UDP
328
329 //OSDArray mediaData = new OSDArray();
330 //OSDMap mediaDataMap = new OSDMap();
331 //mediaDataMap.Add("MediaDesc", OSD.FromString(""));
332 //mediaDataMap.Add("MediaHeight", OSD.FromInteger(0));
333 //mediaDataMap.Add("MediaLoop", OSD.FromInteger(0));
334 //mediaDataMap.Add("MediaType", OSD.FromString("type/type"));
335 //mediaDataMap.Add("MediaWidth", OSD.FromInteger(0));
336 //mediaDataMap.Add("ObscureMedia", OSD.FromInteger(0));
337 //mediaDataMap.Add("ObscureMusic", OSD.FromInteger(0));
338 //mediaData.Add(mediaDataMap);
339 //body.Add("MediaData", mediaData);
340
341 OSDArray parcelData = new OSDArray();
342 OSDMap parcelDataMap = new OSDMap();
343 OSDArray AABBMax = new OSDArray(3);
344 AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.X));
345 AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.Y));
346 AABBMax.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMax.Z));
347 parcelDataMap.Add("AABBMax", AABBMax);
348
349 OSDArray AABBMin = new OSDArray(3);
350 AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.X));
351 AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.Y));
352 AABBMin.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.AABBMin.Z));
353 parcelDataMap.Add("AABBMin", AABBMin);
354
355 parcelDataMap.Add("Area", OSD.FromInteger(parcelPropertiesPacket.ParcelData.Area));
356 parcelDataMap.Add("AuctionID", OSD.FromBinary(uintToByteArray(parcelPropertiesPacket.ParcelData.AuctionID)));
357 parcelDataMap.Add("AuthBuyerID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.AuthBuyerID));
358 parcelDataMap.Add("Bitmap", OSD.FromBinary(parcelPropertiesPacket.ParcelData.Bitmap));
359 parcelDataMap.Add("Category", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.Category));
360 parcelDataMap.Add("ClaimDate", OSD.FromInteger(parcelPropertiesPacket.ParcelData.ClaimDate));
361 parcelDataMap.Add("ClaimPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.ClaimPrice));
362 parcelDataMap.Add("Desc", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.Desc)));
363 parcelDataMap.Add("GroupID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.GroupID));
364 parcelDataMap.Add("GroupPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.GroupPrims));
365 parcelDataMap.Add("IsGroupOwned", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.IsGroupOwned));
366 parcelDataMap.Add("LandingType", OSD.FromInteger(parcelPropertiesPacket.ParcelData.LandingType));
367 parcelDataMap.Add("LocalID", OSD.FromInteger(parcelPropertiesPacket.ParcelData.LocalID));
368 parcelDataMap.Add("MaxPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.MaxPrims));
369 parcelDataMap.Add("MediaAutoScale", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.MediaAutoScale));
370 parcelDataMap.Add("MediaID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.MediaID));
371 parcelDataMap.Add("MediaURL", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.MediaURL)));
372 parcelDataMap.Add("MusicURL", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.MusicURL)));
373 parcelDataMap.Add("Name", OSD.FromString(Utils.BytesToString(parcelPropertiesPacket.ParcelData.Name)));
374 parcelDataMap.Add("OtherCleanTime", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherCleanTime));
375 parcelDataMap.Add("OtherCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherCount));
376 parcelDataMap.Add("OtherPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OtherPrims));
377 parcelDataMap.Add("OwnerID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.OwnerID));
378 parcelDataMap.Add("OwnerPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.OwnerPrims));
379 parcelDataMap.Add("ParcelFlags", OSD.FromBinary(uintToByteArray(parcelPropertiesPacket.ParcelData.ParcelFlags)));
380 parcelDataMap.Add("ParcelPrimBonus", OSD.FromReal(parcelPropertiesPacket.ParcelData.ParcelPrimBonus));
381 parcelDataMap.Add("PassHours", OSD.FromReal(parcelPropertiesPacket.ParcelData.PassHours));
382 parcelDataMap.Add("PassPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.PassPrice));
383 parcelDataMap.Add("PublicCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.PublicCount));
384 parcelDataMap.Add("RegionDenyAnonymous", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyAnonymous));
385 parcelDataMap.Add("RegionDenyIdentified", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyIdentified));
386 parcelDataMap.Add("RegionDenyTransacted", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionDenyTransacted));
387
388 parcelDataMap.Add("RegionPushOverride", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.RegionPushOverride));
389 parcelDataMap.Add("RentPrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.RentPrice));
390 parcelDataMap.Add("RequestResult", OSD.FromInteger(parcelPropertiesPacket.ParcelData.RequestResult));
391 parcelDataMap.Add("SalePrice", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SalePrice));
392 parcelDataMap.Add("SelectedPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SelectedPrims));
393 parcelDataMap.Add("SelfCount", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SelfCount));
394 parcelDataMap.Add("SequenceID", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SequenceID));
395 parcelDataMap.Add("SimWideMaxPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SimWideMaxPrims));
396 parcelDataMap.Add("SimWideTotalPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.SimWideTotalPrims));
397 parcelDataMap.Add("SnapSelection", OSD.FromBoolean(parcelPropertiesPacket.ParcelData.SnapSelection));
398 parcelDataMap.Add("SnapshotID", OSD.FromUUID(parcelPropertiesPacket.ParcelData.SnapshotID));
399 parcelDataMap.Add("Status", OSD.FromInteger((int)parcelPropertiesPacket.ParcelData.Status));
400 parcelDataMap.Add("TotalPrims", OSD.FromInteger(parcelPropertiesPacket.ParcelData.TotalPrims));
401
402 OSDArray UserLocation = new OSDArray(3);
403 UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.X));
404 UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.Y));
405 UserLocation.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLocation.Z));
406 parcelDataMap.Add("UserLocation", UserLocation);
407
408 OSDArray UserLookAt = new OSDArray(3);
409 UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.X));
410 UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.Y));
411 UserLookAt.Add(OSD.FromReal(parcelPropertiesPacket.ParcelData.UserLookAt.Z));
412 parcelDataMap.Add("UserLookAt", UserLookAt);
413
414 parcelData.Add(parcelDataMap);
415 body.Add("ParcelData", parcelData);
416 parcelProperties.Add("body", body);
417 parcelProperties.Add("message", OSD.FromString("ParcelProperties"));
418
419 return parcelProperties;
420 }
421
422 public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket) 313 public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket)
423 { 314 {
424 OSDMap groupUpdate = new OSDMap(); 315 OSDMap groupUpdate = new OSDMap();
@@ -495,5 +386,14 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue
495 return placesReply; 386 return placesReply;
496 } 387 }
497 388
389 public static OSD ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage)
390 {
391 OSDMap message = new OSDMap();
392 message.Add("message", OSD.FromString("ParcelProperties"));
393 OSD message_body = parcelPropertiesMessage.Serialize();
394 message.Add("body", message_body);
395 return message;
396 }
397
498 } 398 }
499} 399}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index cc12df0..2a36362 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -549,7 +549,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
549 } 549 }
550 550
551 if (!m_Scene.Permissions.CanRezObject( 551 if (!m_Scene.Permissions.CanRezObject(
552 group.Children.Count, remoteClient.AgentId, pos) 552 group.PrimCount, remoteClient.AgentId, pos)
553 && !attachment) 553 && !attachment)
554 { 554 {
555 // The client operates in no fail mode. It will 555 // The client operates in no fail mode. It will
@@ -629,7 +629,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
629 rootPart.Name = item.Name; 629 rootPart.Name = item.Name;
630 rootPart.Description = item.Description; 630 rootPart.Description = item.Description;
631 631
632 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); 632 List<SceneObjectPart> partList = null;
633 lock (group.Children)
634 partList = new List<SceneObjectPart>(group.Children.Values);
633 635
634 group.SetGroup(remoteClient.ActiveGroupId, remoteClient); 636 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
635 if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) 637 if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs
index 1e51187..dcf08e3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/BaseInventoryConnector.cs
@@ -27,15 +27,12 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30
31using OpenMetaverse; 30using OpenMetaverse;
32using Nini.Config; 31using Nini.Config;
33using log4net; 32using log4net;
34
35using OpenSim.Framework; 33using OpenSim.Framework;
36using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
37 35
38
39namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory 36namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
40{ 37{
41 public abstract class BaseInventoryConnector : IInventoryService 38 public abstract class BaseInventoryConnector : IInventoryService
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
index c97ab9e..4e2f602 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
161 /// <returns></returns> 161 /// <returns></returns>
162 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) 162 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
163 { 163 {
164 m_log.DebugFormat("[INVENTORY CACHE]: Getting folder for asset type {0} for user {1}", type, userID);
165
164 Dictionary<AssetType, InventoryFolderBase> folders = null; 166 Dictionary<AssetType, InventoryFolderBase> folders = null;
165 167
166 lock (m_InventoryCache) 168 lock (m_InventoryCache)
@@ -177,8 +179,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
177 179
178 if ((folders != null) && folders.ContainsKey(type)) 180 if ((folders != null) && folders.ContainsKey(type))
179 { 181 {
182 m_log.DebugFormat(
183 "[INVENTORY CACHE]: Returning folder {0} as type {1} for {2}", folders[type], type, userID);
184
180 return folders[type]; 185 return folders[type];
181 } 186 }
187
188 m_log.WarnFormat("[INVENTORY CACHE]: Could not find folder for system type {0} for {1}", type, userID);
182 189
183 return null; 190 return null;
184 } 191 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 22bd04c..915b59e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -216,13 +216,40 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
216 return m_InventoryService.PurgeFolder(folder); 216 return m_InventoryService.PurgeFolder(folder);
217 } 217 }
218 218
219 /// <summary>
220 /// Add a new item to the user's inventory
221 /// </summary>
222 /// <param name="item"></param>
223 /// <returns>true if the item was successfully added</returns>
224 public bool AddItem(InventoryItemBase item) 219 public bool AddItem(InventoryItemBase item)
225 { 220 {
221// m_log.DebugFormat(
222// "[LOCAL INVENTORY SERVICES CONNECTOR]: Adding inventory item {0} to user {1} folder {2}",
223// item.Name, item.Owner, item.Folder);
224
225 if (UUID.Zero == item.Folder)
226 {
227 InventoryFolderBase f = m_InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType);
228 if (f != null)
229 {
230// m_log.DebugFormat(
231// "[LOCAL INVENTORY SERVICES CONNECTOR]: Found folder {0} type {1} for item {2}",
232// f.Name, (AssetType)f.Type, item.Name);
233
234 item.Folder = f.ID;
235 }
236 else
237 {
238 f = m_InventoryService.GetRootFolder(item.Owner);
239 if (f != null)
240 {
241 item.Folder = f.ID;
242 }
243 else
244 {
245// m_log.WarnFormat(
246// "[LOCAL INVENTORY SERVICES CONNECTOR]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
247// item.Owner, item.Name);
248 return false;
249 }
250 }
251 }
252
226 return m_InventoryService.AddItem(item); 253 return m_InventoryService.AddItem(item);
227 } 254 }
228 255
@@ -236,7 +263,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
236 return m_InventoryService.UpdateItem(item); 263 return m_InventoryService.UpdateItem(item);
237 } 264 }
238 265
239
240 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items) 266 public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
241 { 267 {
242 return m_InventoryService.MoveItems(ownerID, items); 268 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 153aeec..17d80c7 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
75 base.Init(source); 75 base.Init(source);
76 } 76 }
77 77
78
79 #region ISharedRegionModule 78 #region ISharedRegionModule
80 79
81 public void Initialise(IConfigSource source) 80 public void Initialise(IConfigSource source)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index ada26cc..4211fa9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -228,6 +228,30 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
228 { 228 {
229 if (item == null) 229 if (item == null)
230 return false; 230 return false;
231
232 if (UUID.Zero == item.Folder)
233 {
234 InventoryFolderBase f = m_RemoteConnector.GetFolderForType(item.Owner, (AssetType)item.AssetType);
235 if (f != null)
236 {
237 item.Folder = f.ID;
238 }
239 else
240 {
241 f = m_RemoteConnector.GetRootFolder(item.Owner);
242 if (f != null)
243 {
244 item.Folder = f.ID;
245 }
246 else
247 {
248 m_log.WarnFormat(
249 "[LOCAL INVENTORY SERVICES CONNECTOR]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified",
250 item.Owner, item.Name);
251 return false;
252 }
253 }
254 }
231 255
232 return m_RemoteConnector.AddItem(item); 256 return m_RemoteConnector.AddItem(item);
233 } 257 }
@@ -294,9 +318,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
294 return m_RemoteConnector.GetAssetPermissions(userID, assetID); 318 return m_RemoteConnector.GetAssetPermissions(userID, assetID);
295 } 319 }
296 320
297
298 #endregion 321 #endregion
299
300
301 } 322 }
302} 323} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 57b7672..e51f118 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -243,7 +243,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
243 // to the same scene (when this is possible). 243 // to the same scene (when this is possible).
244 sceneObject.ResetIDs(); 244 sceneObject.ResetIDs();
245 245
246 foreach (SceneObjectPart part in sceneObject.Children.Values) 246 List<SceneObjectPart> partList = null;
247 lock (sceneObject.Children)
248 partList = new List<SceneObjectPart>(sceneObject.Children.Values);
249
250 foreach (SceneObjectPart part in partList)
247 { 251 {
248 if (!ResolveUserUuid(part.CreatorID)) 252 if (!ResolveUserUuid(part.CreatorID))
249 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 253 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -261,11 +265,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
261 // Fix ownership/creator of inventory items 265 // Fix ownership/creator of inventory items
262 // Not doing so results in inventory items 266 // Not doing so results in inventory items
263 // being no copy/no mod for everyone 267 // being no copy/no mod for everyone
264 part.TaskInventory.LockItemsForRead(true); 268 lock (part.TaskInventory)
265 TaskInventoryDictionary inv = part.TaskInventory;
266 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
267 { 269 {
268 if (!ResolveUserUuid(kvp.Value.OwnerID)) 270 if (!ResolveUserUuid(part.CreatorID))
271 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
272
273 if (!ResolveUserUuid(part.OwnerID))
274 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
275
276 if (!ResolveUserUuid(part.LastOwnerID))
277 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
278
279 // And zap any troublesome sit target information
280 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
281 part.SitTargetPosition = new Vector3(0, 0, 0);
282
283 // Fix ownership/creator of inventory items
284 // Not doing so results in inventory items
285 // being no copy/no mod for everyone
286 part.TaskInventory.LockItemsForRead(true);
287 TaskInventoryDictionary inv = part.TaskInventory;
288 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
269 { 289 {
270 if (!ResolveUserUuid(kvp.Value.OwnerID)) 290 if (!ResolveUserUuid(kvp.Value.OwnerID))
271 { 291 {
@@ -276,8 +296,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
276 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 296 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
277 } 297 }
278 } 298 }
299 part.TaskInventory.LockItemsForRead(false);
279 } 300 }
280 part.TaskInventory.LockItemsForRead(false);
281 } 301 }
282 302
283 if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) 303 if (m_scene.AddRestoredSceneObject(sceneObject, true, false))
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 8411d04..fb15d91 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -684,6 +684,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
684 args.useEstateSun = m_scene.RegionInfo.RegionSettings.UseEstateSun; 684 args.useEstateSun = m_scene.RegionInfo.RegionSettings.UseEstateSun;
685 args.waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; 685 args.waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight;
686 args.simName = m_scene.RegionInfo.RegionName; 686 args.simName = m_scene.RegionInfo.RegionName;
687 args.regionType = m_scene.RegionInfo.RegionType;
687 688
688 remote_client.SendRegionInfoToEstateMenu(args); 689 remote_client.SendRegionInfoToEstateMenu(args);
689 } 690 }
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index d00cb07..776fe30 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -33,6 +33,8 @@ using System.Reflection;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenMetaverse.Messages.Linden;
36using OpenSim.Framework; 38using OpenSim.Framework;
37using OpenSim.Framework.Capabilities; 39using OpenSim.Framework.Capabilities;
38using OpenSim.Framework.Servers; 40using OpenSim.Framework.Servers;
@@ -1078,7 +1080,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1078 { 1080 {
1079 for (int y = 0; y < inc_y; y++) 1081 for (int y = 0; y < inc_y; y++)
1080 { 1082 {
1081
1082 ILandObject currentParcel = GetLandObject(start_x + x, start_y + y); 1083 ILandObject currentParcel = GetLandObject(start_x + x, start_y + y);
1083 1084
1084 if (currentParcel != null) 1085 if (currentParcel != null)
@@ -1378,8 +1379,68 @@ namespace OpenSim.Region.CoreModules.World.Land
1378 { 1379 {
1379 return RemoteParcelRequest(request, path, param, agentID, caps); 1380 return RemoteParcelRequest(request, path, param, agentID, caps);
1380 })); 1381 }));
1381 } 1382 UUID parcelCapID = UUID.Random();
1383 caps.RegisterHandler("ParcelPropertiesUpdate",
1384 new RestStreamHandler("POST", "/CAPS/" + parcelCapID,
1385 delegate(string request, string path, string param,
1386 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
1387 {
1388 return ProcessPropertiesUpdate(request, path, param, agentID, caps);
1389 }));
1390 }
1391 private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps)
1392 {
1393 IClientAPI client;
1394 if ( ! m_scene.TryGetClient(agentID, out client) ) {
1395 m_log.WarnFormat("[LAND] unable to retrieve IClientAPI for {0}", agentID.ToString() );
1396 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1397 }
1398
1399 ParcelPropertiesUpdateMessage properties = new ParcelPropertiesUpdateMessage();
1400 OpenMetaverse.StructuredData.OSDMap args = (OpenMetaverse.StructuredData.OSDMap) OSDParser.DeserializeLLSDXml(request);
1401
1402 properties.Deserialize(args);
1403
1404 LandUpdateArgs land_update = new LandUpdateArgs();
1405 int parcelID = properties.LocalID;
1406 land_update.AuthBuyerID = properties.AuthBuyerID;
1407 land_update.Category = properties.Category;
1408 land_update.Desc = properties.Desc;
1409 land_update.GroupID = properties.GroupID;
1410 land_update.LandingType = (byte) properties.Landing;
1411 land_update.MediaAutoScale = (byte) Convert.ToInt32(properties.MediaAutoScale);
1412 land_update.MediaID = properties.MediaID;
1413 land_update.MediaURL = properties.MediaURL;
1414 land_update.MusicURL = properties.MusicURL;
1415 land_update.Name = properties.Name;
1416 land_update.ParcelFlags = (uint) properties.ParcelFlags;
1417 land_update.PassHours = (int) properties.PassHours;
1418 land_update.PassPrice = (int) properties.PassPrice;
1419 land_update.SalePrice = (int) properties.SalePrice;
1420 land_update.SnapshotID = properties.SnapshotID;
1421 land_update.UserLocation = properties.UserLocation;
1422 land_update.UserLookAt = properties.UserLookAt;
1423 land_update.MediaDescription = properties.MediaDesc;
1424 land_update.MediaType = properties.MediaType;
1425 land_update.MediaWidth = properties.MediaWidth;
1426 land_update.MediaHeight = properties.MediaHeight;
1427 land_update.MediaLoop = properties.MediaLoop;
1428 land_update.ObscureMusic = properties.ObscureMusic;
1429 land_update.ObscureMedia = properties.ObscureMedia;
1430
1431 ILandObject land;
1432 lock (m_landList)
1433 {
1434 m_landList.TryGetValue(parcelID, out land);
1435 }
1382 1436
1437 if (land != null) {
1438 land.UpdateLandProperties(land_update, client);
1439 } else {
1440 m_log.WarnFormat("[LAND] unable to find parcelID {0}", parcelID);
1441 }
1442 return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty());
1443 }
1383 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the 1444 // we cheat here: As we don't have (and want) a grid-global parcel-store, we can't return the
1384 // "real" parcelID, because we wouldn't be able to map that to the region the parcel belongs to. 1445 // "real" parcelID, because we wouldn't be able to map that to the region the parcel belongs to.
1385 // So, we create a "fake" parcelID by using the regionHandle (64 bit), and the local (integer) x 1446 // 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 fcd993c..1b2cabb 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -1,1045 +1,1052 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36 36
37namespace OpenSim.Region.CoreModules.World.Land 37namespace OpenSim.Region.CoreModules.World.Land
38{ 38{
39 /// <summary> 39 /// <summary>
40 /// Keeps track of a specific piece of land's information 40 /// Keeps track of a specific piece of land's information
41 /// </summary> 41 /// </summary>
42 public class LandObject : ILandObject 42 public class LandObject : ILandObject
43 { 43 {
44 #region Member Variables 44 #region Member Variables
45 45
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 #pragma warning disable 0429 47 #pragma warning disable 0429
48 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; 48 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
49 #pragma warning restore 0429 49 #pragma warning restore 0429
50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 53
54 protected LandData m_landData = new LandData(); 54 protected LandData m_landData = new LandData();
55 protected Scene m_scene; 55 protected Scene m_scene;
56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
57 57
58 public bool[,] LandBitmap 58 public bool[,] LandBitmap
59 { 59 {
60 get { return m_landBitmap; } 60 get { return m_landBitmap; }
61 set { m_landBitmap = value; } 61 set { m_landBitmap = value; }
62 } 62 }
63 63
64 #endregion 64 #endregion
65 65
66 #region ILandObject Members 66 #region ILandObject Members
67 67
68 public LandData LandData 68 public LandData LandData
69 { 69 {
70 get { return m_landData; } 70 get { return m_landData; }
71 71
72 set { m_landData = value; } 72 set { m_landData = value; }
73 } 73 }
74 74
75 public UUID RegionUUID 75 public UUID RegionUUID
76 { 76 {
77 get { return m_scene.RegionInfo.RegionID; } 77 get { return m_scene.RegionInfo.RegionID; }
78 } 78 }
79 79
80 #region Constructors 80 #region Constructors
81 81
82 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 82 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
83 { 83 {
84 m_scene = scene; 84 m_scene = scene;
85 LandData.OwnerID = owner_id; 85 LandData.OwnerID = owner_id;
86 if (is_group_owned) 86 if (is_group_owned)
87 LandData.GroupID = owner_id; 87 LandData.GroupID = owner_id;
88 else 88 else
89 LandData.GroupID = UUID.Zero; 89 LandData.GroupID = UUID.Zero;
90 LandData.IsGroupOwned = is_group_owned; 90 LandData.IsGroupOwned = is_group_owned;
91 } 91 }
92 92
93 #endregion 93 #endregion
94 94
95 #region Member Functions 95 #region Member Functions
96 96
97 #region General Functions 97 #region General Functions
98 98
99 /// <summary> 99 /// <summary>
100 /// Checks to see if this land object contains a point 100 /// Checks to see if this land object contains a point
101 /// </summary> 101 /// </summary>
102 /// <param name="x"></param> 102 /// <param name="x"></param>
103 /// <param name="y"></param> 103 /// <param name="y"></param>
104 /// <returns>Returns true if the piece of land contains the specified point</returns> 104 /// <returns>Returns true if the piece of land contains the specified point</returns>
105 public bool ContainsPoint(int x, int y) 105 public bool ContainsPoint(int x, int y)
106 { 106 {
107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) 107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize)
108 { 108 {
109 return (LandBitmap[x / 4, y / 4] == true); 109 return (LandBitmap[x / 4, y / 4] == true);
110 } 110 }
111 else 111 else
112 { 112 {
113 return false; 113 return false;
114 } 114 }
115 } 115 }
116 116
117 public ILandObject Copy() 117 public ILandObject Copy()
118 { 118 {
119 ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); 119 ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene);
120 120
121 //Place all new variables here! 121 //Place all new variables here!
122 newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); 122 newLand.LandBitmap = (bool[,]) (LandBitmap.Clone());
123 newLand.LandData = LandData.Copy(); 123 newLand.LandData = LandData.Copy();
124 124
125 return newLand; 125 return newLand;
126 } 126 }
127 127
128 static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; 128 static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount;
129 static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; 129 static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount;
130 130
131 public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) 131 public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
132 { 132 {
133 overrideParcelMaxPrimCount = overrideDel; 133 overrideParcelMaxPrimCount = overrideDel;
134 } 134 }
135 public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) 135 public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
136 { 136 {
137 overrideSimulatorMaxPrimCount = overrideDel; 137 overrideSimulatorMaxPrimCount = overrideDel;
138 } 138 }
139 139
140 public int GetParcelMaxPrimCount(ILandObject thisObject) 140 public int GetParcelMaxPrimCount(ILandObject thisObject)
141 { 141 {
142 if (overrideParcelMaxPrimCount != null) 142 if (overrideParcelMaxPrimCount != null)
143 { 143 {
144 return overrideParcelMaxPrimCount(thisObject); 144 return overrideParcelMaxPrimCount(thisObject);
145 } 145 }
146 else 146 else
147 { 147 {
148 // Normal Calculations 148 // Normal Calculations
149 return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 149 return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
150 } 150 }
151 } 151 }
152 public int GetSimulatorMaxPrimCount(ILandObject thisObject) 152 public int GetSimulatorMaxPrimCount(ILandObject thisObject)
153 { 153 {
154 if (overrideSimulatorMaxPrimCount != null) 154 if (overrideSimulatorMaxPrimCount != null)
155 { 155 {
156 return overrideSimulatorMaxPrimCount(thisObject); 156 return overrideSimulatorMaxPrimCount(thisObject);
157 } 157 }
158 else 158 else
159 { 159 {
160 //Normal Calculations 160 //Normal Calculations
161 return m_scene.RegionInfo.ObjectCapacity; 161 return m_scene.RegionInfo.ObjectCapacity;
162 } 162 }
163 } 163 }
164 #endregion 164 #endregion
165 165
166 #region Packet Request Handling 166 #region Packet Request Handling
167 167
168 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 168 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
169 { 169 {
170 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 170 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
171 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 171 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
172 if (estateModule != null) 172 if (estateModule != null)
173 regionFlags = estateModule.GetRegionFlags(); 173 regionFlags = estateModule.GetRegionFlags();
174 174
175 // In a perfect world, this would have worked. 175 // In a perfect world, this would have worked.
176 // 176 //
177// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) 177// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0)
178// regionFlags |= (uint)RegionFlags.AllowLandmark; 178// regionFlags |= (uint)RegionFlags.AllowLandmark;
179// if (landData.OwnerID == remote_client.AgentId) 179// if (landData.OwnerID == remote_client.AgentId)
180// regionFlags |= (uint)RegionFlags.AllowSetHome; 180// regionFlags |= (uint)RegionFlags.AllowSetHome;
181 181
182 int seq_id; 182 int seq_id;
183 if (snap_selection && (sequence_id == 0)) 183 if (snap_selection && (sequence_id == 0))
184 { 184 {
185 seq_id = m_lastSeqId; 185 seq_id = m_lastSeqId;
186 } 186 }
187 else 187 else
188 { 188 {
189 seq_id = sequence_id; 189 seq_id = sequence_id;
190 m_lastSeqId = seq_id; 190 m_lastSeqId = seq_id;
191 } 191 }
192 192
193 remote_client.SendLandProperties(seq_id, 193 remote_client.SendLandProperties(seq_id,
194 snap_selection, request_result, LandData, 194 snap_selection, request_result, LandData,
195 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 195 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
196 GetParcelMaxPrimCount(this), 196 GetParcelMaxPrimCount(this),
197 GetSimulatorMaxPrimCount(this), regionFlags); 197 GetSimulatorMaxPrimCount(this), regionFlags);
198 } 198 }
199 199
200 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) 200 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client)
201 { 201 {
202 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) 202 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this))
203 { 203 {
204 //Needs later group support 204 //Needs later group support
205 bool snap_selection = false; 205 bool snap_selection = false;
206 LandData newData = LandData.Copy(); 206 LandData newData = LandData.Copy();
207 207
208 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) 208 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice)
209 { 209 {
210 if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) 210 if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this))
211 { 211 {
212 newData.AuthBuyerID = args.AuthBuyerID; 212 newData.AuthBuyerID = args.AuthBuyerID;
213 newData.SalePrice = args.SalePrice; 213 newData.SalePrice = args.SalePrice;
214 snap_selection = true; 214 snap_selection = true;
215 } 215 }
216 } 216 }
217 newData.Category = args.Category; 217 newData.Category = args.Category;
218 newData.Description = args.Desc; 218 newData.Description = args.Desc;
219 newData.GroupID = args.GroupID; 219 newData.GroupID = args.GroupID;
220 newData.LandingType = args.LandingType; 220 newData.LandingType = args.LandingType;
221 newData.MediaAutoScale = args.MediaAutoScale; 221 newData.MediaAutoScale = args.MediaAutoScale;
222 newData.MediaID = args.MediaID; 222 newData.MediaID = args.MediaID;
223 newData.MediaURL = args.MediaURL; 223 newData.MediaURL = args.MediaURL;
224 newData.MusicURL = args.MusicURL; 224 newData.MusicURL = args.MusicURL;
225 newData.Name = args.Name; 225 newData.Name = args.Name;
226 newData.Flags = args.ParcelFlags; 226 newData.Flags = args.ParcelFlags;
227 newData.PassHours = args.PassHours; 227 newData.PassHours = args.PassHours;
228 newData.PassPrice = args.PassPrice; 228 newData.PassPrice = args.PassPrice;
229 newData.SnapshotID = args.SnapshotID; 229 newData.SnapshotID = args.SnapshotID;
230 newData.UserLocation = args.UserLocation; 230 newData.UserLocation = args.UserLocation;
231 newData.UserLookAt = args.UserLookAt; 231 newData.UserLookAt = args.UserLookAt;
232 232 newData.MediaType = args.MediaType;
233 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 233 newData.MediaDescription = args.MediaDescription;
234 234 newData.MediaWidth = args.MediaWidth;
235 SendLandUpdateToAvatarsOverMe(snap_selection); 235 newData.MediaHeight = args.MediaHeight;
236 } 236 newData.MediaLoop = args.MediaLoop;
237 } 237 newData.ObscureMusic = args.ObscureMusic;
238 238 newData.ObscureMedia = args.ObscureMedia;
239 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 239
240 { 240 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
241 LandData newData = LandData.Copy(); 241
242 newData.OwnerID = avatarID; 242 SendLandUpdateToAvatarsOverMe(snap_selection);
243 newData.GroupID = groupID; 243 }
244 newData.IsGroupOwned = groupOwned; 244 }
245 //newData.auctionID = AuctionID; 245
246 newData.ClaimDate = Util.UnixTimeSinceEpoch(); 246 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
247 newData.ClaimPrice = claimprice; 247 {
248 newData.SalePrice = 0; 248 LandData newData = LandData.Copy();
249 newData.AuthBuyerID = UUID.Zero; 249 newData.OwnerID = avatarID;
250 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 250 newData.GroupID = groupID;
251 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 251 newData.IsGroupOwned = groupOwned;
252 252 //newData.auctionID = AuctionID;
253 SendLandUpdateToAvatarsOverMe(true); 253 newData.ClaimDate = Util.UnixTimeSinceEpoch();
254 } 254 newData.ClaimPrice = claimprice;
255 255 newData.SalePrice = 0;
256 public void DeedToGroup(UUID groupID) 256 newData.AuthBuyerID = UUID.Zero;
257 { 257 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
258 LandData newData = LandData.Copy(); 258 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
259 newData.OwnerID = groupID; 259
260 newData.GroupID = groupID; 260 SendLandUpdateToAvatarsOverMe(true);
261 newData.IsGroupOwned = true; 261 }
262 262
263 // Reset show in directory flag on deed 263 public void DeedToGroup(UUID groupID)
264 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 264 {
265 265 LandData newData = LandData.Copy();
266 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 266 newData.OwnerID = groupID;
267 267 newData.GroupID = groupID;
268 SendLandUpdateToAvatarsOverMe(true); 268 newData.IsGroupOwned = true;
269 } 269
270 270 // Reset show in directory flag on deed
271 public bool IsEitherBannedOrRestricted(UUID avatar) 271 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
272 { 272
273 if (IsBannedFromLand(avatar)) 273 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
274 { 274
275 return true; 275 SendLandUpdateToAvatarsOverMe(true);
276 } 276 }
277 else if (IsRestrictedFromLand(avatar)) 277
278 { 278 public bool IsEitherBannedOrRestricted(UUID avatar)
279 return true; 279 {
280 } 280 if (IsBannedFromLand(avatar))
281 return false; 281 {
282 } 282 return true;
283 283 }
284 public bool HasGroupAccess(UUID avatar) 284 else if (IsRestrictedFromLand(avatar))
285 { 285 {
286 if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 286 return true;
287 { 287 }
288 IGroupsModule groupsModule = 288 return false;
289 m_scene.RequestModuleInterface<IGroupsModule>(); 289 }
290 290
291 List<UUID> agentGroups = new List<UUID>(); 291 public bool HasGroupAccess(UUID avatar)
292 if (groupsModule != null) 292 {
293 { 293 if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
294 GroupMembershipData[] GroupMembership = 294 {
295 groupsModule.GetMembershipData(avatar); 295 IGroupsModule groupsModule =
296 296 m_scene.RequestModuleInterface<IGroupsModule>();
297 if (GroupMembership != null) 297
298 { 298 List<UUID> agentGroups = new List<UUID>();
299 for (int i = 0; i < GroupMembership.Length; i++) 299 if (groupsModule != null)
300 { 300 {
301 if (LandData.GroupID == GroupMembership[i].GroupID) 301 GroupMembershipData[] GroupMembership =
302 { 302 groupsModule.GetMembershipData(avatar);
303 return true; 303
304 } 304 if (GroupMembership != null)
305 } 305 {
306 } 306 for (int i = 0; i < GroupMembership.Length; i++)
307 } 307 {
308 } 308 if (LandData.GroupID == GroupMembership[i].GroupID)
309 return false; 309 {
310 } 310 return true;
311 311 }
312 public bool IsBannedFromLand(UUID avatar) 312 }
313 { 313 }
314 if (m_scene.Permissions.IsAdministrator(avatar)) 314 }
315 return false; 315 }
316 316 return false;
317 if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) 317 }
318 { 318
319 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 319 public bool IsBannedFromLand(UUID avatar)
320 entry.AgentID = avatar; 320 {
321 entry.Flags = AccessList.Ban; 321 if (m_scene.Permissions.IsAdministrator(avatar))
322 entry.Time = new DateTime(); 322 return false;
323 //See if they are on the list, but make sure the owner isn't banned 323
324 if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) 324 if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0)
325 { 325 {
326 //They are banned, so lets send them a notice about this parcel 326 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
327 return true; 327 entry.AgentID = avatar;
328 } 328 entry.Flags = AccessList.Ban;
329 } 329 entry.Time = new DateTime();
330 return false; 330 //See if they are on the list, but make sure the owner isn't banned
331 } 331 if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar)
332 332 {
333 public bool IsRestrictedFromLand(UUID avatar) 333 //They are banned, so lets send them a notice about this parcel
334 { 334 return true;
335 if (m_scene.Permissions.IsAdministrator(avatar)) 335 }
336 return false; 336 }
337 337 return false;
338 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) 338 }
339 { 339
340 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 340 public bool IsRestrictedFromLand(UUID avatar)
341 entry.AgentID = avatar; 341 {
342 entry.Flags = AccessList.Access; 342 if (m_scene.Permissions.IsAdministrator(avatar))
343 entry.Time = new DateTime(); 343 return false;
344 344
345 //If they are not on the access list and are not the owner 345 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0)
346 if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) 346 {
347 { 347 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
348 if (!HasGroupAccess(avatar)) 348 entry.AgentID = avatar;
349 { 349 entry.Flags = AccessList.Access;
350 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel 350 entry.Time = new DateTime();
351 return true; 351
352 } 352 //If they are not on the access list and are not the owner
353 } 353 if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar)
354 } 354 {
355 355 if (!HasGroupAccess(avatar))
356 return false; 356 {
357 } 357 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
358 358 return true;
359 public void SendLandUpdateToClient(IClientAPI remote_client) 359 }
360 { 360 }
361 SendLandProperties(0, false, 0, remote_client); 361 }
362 } 362
363 363 return false;
364 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) 364 }
365 { 365
366 SendLandProperties(0, snap_selection, 0, remote_client); 366 public void SendLandUpdateToClient(IClientAPI remote_client)
367 } 367 {
368 368 SendLandProperties(0, false, 0, remote_client);
369 public void SendLandUpdateToAvatarsOverMe() 369 }
370 { 370
371 SendLandUpdateToAvatarsOverMe(false); 371 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
372 } 372 {
373 373 SendLandProperties(0, snap_selection, 0, remote_client);
374 public void SendLandUpdateToAvatarsOverMe(bool snap_selection) 374 }
375 { 375
376 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 376 public void SendLandUpdateToAvatarsOverMe()
377 { 377 {
378 if (avatar.IsChildAgent) 378 SendLandUpdateToAvatarsOverMe(false);
379 return; 379 }
380 380
381 ILandObject over = null; 381 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
382 try 382 {
383 { 383 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
384 over = 384 {
385 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), 385 if (avatar.IsChildAgent)
386 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); 386 return;
387 } 387
388 catch (Exception) 388 ILandObject over = null;
389 { 389 try
390 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + 390 {
391 Math.Round(avatar.AbsolutePosition.Y)); 391 over =
392 } 392 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
393 393 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
394 if (over != null) 394 }
395 { 395 catch (Exception)
396 if (over.LandData.LocalID == LandData.LocalID) 396 {
397 { 397 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
398 if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && 398 Math.Round(avatar.AbsolutePosition.Y));
399 m_scene.RegionInfo.RegionSettings.AllowDamage) 399 }
400 avatar.Invulnerable = false; 400
401 else 401 if (over != null)
402 avatar.Invulnerable = true; 402 {
403 403 if (over.LandData.LocalID == LandData.LocalID)
404 SendLandUpdateToClient(snap_selection, avatar.ControllingClient); 404 {
405 } 405 if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
406 } 406 m_scene.RegionInfo.RegionSettings.AllowDamage)
407 }); 407 avatar.Invulnerable = false;
408 } 408 else
409 409 avatar.Invulnerable = true;
410 #endregion 410
411 411 SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
412 #region AccessList Functions 412 }
413 413 }
414 public List<UUID> CreateAccessListArrayByFlag(AccessList flag) 414 });
415 { 415 }
416 List<UUID> list = new List<UUID>(); 416
417 foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) 417 #endregion
418 { 418
419 if (entry.Flags == flag) 419 #region AccessList Functions
420 { 420
421 list.Add(entry.AgentID); 421 public List<UUID> CreateAccessListArrayByFlag(AccessList flag)
422 } 422 {
423 } 423 List<UUID> list = new List<UUID>();
424 if (list.Count == 0) 424 foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList)
425 { 425 {
426 list.Add(UUID.Zero); 426 if (entry.Flags == flag)
427 } 427 {
428 428 list.Add(entry.AgentID);
429 return list; 429 }
430 } 430 }
431 431 if (list.Count == 0)
432 public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, 432 {
433 IClientAPI remote_client) 433 list.Add(UUID.Zero);
434 { 434 }
435 435
436 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) 436 return list;
437 { 437 }
438 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Access); 438
439 remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); 439 public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID,
440 } 440 IClientAPI remote_client)
441 441 {
442 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) 442
443 { 443 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both)
444 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Ban); 444 {
445 remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); 445 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Access);
446 } 446 remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID);
447 } 447 }
448 448
449 public void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) 449 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both)
450 { 450 {
451 LandData newData = LandData.Copy(); 451 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Ban);
452 452 remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID);
453 if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) 453 }
454 { 454 }
455 entries.Clear(); 455
456 } 456 public void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
457 457 {
458 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); 458 LandData newData = LandData.Copy();
459 foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) 459
460 { 460 if (entries.Count == 1 && entries[0].AgentID == UUID.Zero)
461 if (entry.Flags == (AccessList)flags) 461 {
462 { 462 entries.Clear();
463 toRemove.Add(entry); 463 }
464 } 464
465 } 465 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
466 466 foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList)
467 foreach (ParcelManager.ParcelAccessEntry entry in toRemove) 467 {
468 { 468 if (entry.Flags == (AccessList)flags)
469 newData.ParcelAccessList.Remove(entry); 469 {
470 } 470 toRemove.Add(entry);
471 foreach (ParcelManager.ParcelAccessEntry entry in entries) 471 }
472 { 472 }
473 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); 473
474 temp.AgentID = entry.AgentID; 474 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
475 temp.Time = new DateTime(); //Pointless? Yes. 475 {
476 temp.Flags = (AccessList)flags; 476 newData.ParcelAccessList.Remove(entry);
477 477 }
478 if (!newData.ParcelAccessList.Contains(temp)) 478 foreach (ParcelManager.ParcelAccessEntry entry in entries)
479 { 479 {
480 newData.ParcelAccessList.Add(temp); 480 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
481 } 481 temp.AgentID = entry.AgentID;
482 } 482 temp.Time = new DateTime(); //Pointless? Yes.
483 483 temp.Flags = (AccessList)flags;
484 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 484
485 } 485 if (!newData.ParcelAccessList.Contains(temp))
486 486 {
487 #endregion 487 newData.ParcelAccessList.Add(temp);
488 488 }
489 #region Update Functions 489 }
490 490
491 public void UpdateLandBitmapByteArray() 491 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
492 { 492 }
493 LandData.Bitmap = ConvertLandBitmapToBytes(); 493
494 } 494 #endregion
495 495
496 /// <summary> 496 #region Update Functions
497 /// Update all settings in land such as area, bitmap byte array, etc 497
498 /// </summary> 498 public void UpdateLandBitmapByteArray()
499 public void ForceUpdateLandInfo() 499 {
500 { 500 LandData.Bitmap = ConvertLandBitmapToBytes();
501 UpdateAABBAndAreaValues(); 501 }
502 UpdateLandBitmapByteArray(); 502
503 } 503 /// <summary>
504 504 /// Update all settings in land such as area, bitmap byte array, etc
505 public void SetLandBitmapFromByteArray() 505 /// </summary>
506 { 506 public void ForceUpdateLandInfo()
507 LandBitmap = ConvertBytesToLandBitmap(); 507 {
508 } 508 UpdateAABBAndAreaValues();
509 509 UpdateLandBitmapByteArray();
510 /// <summary> 510 }
511 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object 511
512 /// </summary> 512 public void SetLandBitmapFromByteArray()
513 private void UpdateAABBAndAreaValues() 513 {
514 { 514 LandBitmap = ConvertBytesToLandBitmap();
515 int min_x = 64; 515 }
516 int min_y = 64; 516
517 int max_x = 0; 517 /// <summary>
518 int max_y = 0; 518 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
519 int tempArea = 0; 519 /// </summary>
520 int x, y; 520 private void UpdateAABBAndAreaValues()
521 for (x = 0; x < 64; x++) 521 {
522 { 522 int min_x = 64;
523 for (y = 0; y < 64; y++) 523 int min_y = 64;
524 { 524 int max_x = 0;
525 if (LandBitmap[x, y] == true) 525 int max_y = 0;
526 { 526 int tempArea = 0;
527 if (min_x > x) min_x = x; 527 int x, y;
528 if (min_y > y) min_y = y; 528 for (x = 0; x < 64; x++)
529 if (max_x < x) max_x = x; 529 {
530 if (max_y < y) max_y = y; 530 for (y = 0; y < 64; y++)
531 tempArea += 16; //16sqm peice of land 531 {
532 } 532 if (LandBitmap[x, y] == true)
533 } 533 {
534 } 534 if (min_x > x) min_x = x;
535 int tx = min_x * 4; 535 if (min_y > y) min_y = y;
536 if (tx > ((int)Constants.RegionSize - 1)) 536 if (max_x < x) max_x = x;
537 tx = ((int)Constants.RegionSize - 1); 537 if (max_y < y) max_y = y;
538 int ty = min_y * 4; 538 tempArea += 16; //16sqm peice of land
539 if (ty > ((int)Constants.RegionSize - 1)) 539 }
540 ty = ((int)Constants.RegionSize - 1); 540 }
541 LandData.AABBMin = 541 }
542 new Vector3((float) (min_x * 4), (float) (min_y * 4), 542 int tx = min_x * 4;
543 (float) m_scene.Heightmap[tx, ty]); 543 if (tx > ((int)Constants.RegionSize - 1))
544 544 tx = ((int)Constants.RegionSize - 1);
545 tx = max_x * 4; 545 int ty = min_y * 4;
546 if (tx > ((int)Constants.RegionSize - 1)) 546 if (ty > ((int)Constants.RegionSize - 1))
547 tx = ((int)Constants.RegionSize - 1); 547 ty = ((int)Constants.RegionSize - 1);
548 ty = max_y * 4; 548 LandData.AABBMin =
549 if (ty > ((int)Constants.RegionSize - 1)) 549 new Vector3((float) (min_x * 4), (float) (min_y * 4),
550 ty = ((int)Constants.RegionSize - 1); 550 (float) m_scene.Heightmap[tx, ty]);
551 LandData.AABBMax = 551
552 new Vector3((float) (max_x * 4), (float) (max_y * 4), 552 tx = max_x * 4;
553 (float) m_scene.Heightmap[tx, ty]); 553 if (tx > ((int)Constants.RegionSize - 1))
554 LandData.Area = tempArea; 554 tx = ((int)Constants.RegionSize - 1);
555 } 555 ty = max_y * 4;
556 556 if (ty > ((int)Constants.RegionSize - 1))
557 #endregion 557 ty = ((int)Constants.RegionSize - 1);
558 558 LandData.AABBMax =
559 #region Land Bitmap Functions 559 new Vector3((float) (max_x * 4), (float) (max_y * 4),
560 560 (float) m_scene.Heightmap[tx, ty]);
561 /// <summary> 561 LandData.Area = tempArea;
562 /// Sets the land's bitmap manually 562 }
563 /// </summary> 563
564 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 564 #endregion
565 public void SetLandBitmap(bool[,] bitmap) 565
566 { 566 #region Land Bitmap Functions
567 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 567
568 { 568 /// <summary>
569 //Throw an exception - The bitmap is not 64x64 569 /// Sets the land's bitmap manually
570 //throw new Exception("Error: Invalid Parcel Bitmap"); 570 /// </summary>
571 } 571 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
572 else 572 public void SetLandBitmap(bool[,] bitmap)
573 { 573 {
574 //Valid: Lets set it 574 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
575 LandBitmap = bitmap; 575 {
576 ForceUpdateLandInfo(); 576 //Throw an exception - The bitmap is not 64x64
577 } 577 //throw new Exception("Error: Invalid Parcel Bitmap");
578 } 578 }
579 579 else
580 /// <summary> 580 {
581 /// Gets the land's bitmap manually 581 //Valid: Lets set it
582 /// </summary> 582 LandBitmap = bitmap;
583 /// <returns></returns> 583 ForceUpdateLandInfo();
584 public bool[,] GetLandBitmap() 584 }
585 { 585 }
586 return LandBitmap; 586
587 } 587 /// <summary>
588 588 /// Gets the land's bitmap manually
589 /// <summary> 589 /// </summary>
590 /// Full sim land object creation 590 /// <returns></returns>
591 /// </summary> 591 public bool[,] GetLandBitmap()
592 /// <returns></returns> 592 {
593 public bool[,] BasicFullRegionLandBitmap() 593 return LandBitmap;
594 { 594 }
595 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 595
596 } 596 /// <summary>
597 597 /// Full sim land object creation
598 /// <summary> 598 /// </summary>
599 /// Used to modify the bitmap between the x and y points. Points use 64 scale 599 /// <returns></returns>
600 /// </summary> 600 public bool[,] BasicFullRegionLandBitmap()
601 /// <param name="start_x"></param> 601 {
602 /// <param name="start_y"></param> 602 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
603 /// <param name="end_x"></param> 603 }
604 /// <param name="end_y"></param> 604
605 /// <returns></returns> 605 /// <summary>
606 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 606 /// Used to modify the bitmap between the x and y points. Points use 64 scale
607 { 607 /// </summary>
608 bool[,] tempBitmap = new bool[64,64]; 608 /// <param name="start_x"></param>
609 tempBitmap.Initialize(); 609 /// <param name="start_y"></param>
610 610 /// <param name="end_x"></param>
611 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 611 /// <param name="end_y"></param>
612 return tempBitmap; 612 /// <returns></returns>
613 } 613 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
614 614 {
615 /// <summary> 615 bool[,] tempBitmap = new bool[64,64];
616 /// Change a land bitmap at within a square and set those points to a specific value 616 tempBitmap.Initialize();
617 /// </summary> 617
618 /// <param name="land_bitmap"></param> 618 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
619 /// <param name="start_x"></param> 619 return tempBitmap;
620 /// <param name="start_y"></param> 620 }
621 /// <param name="end_x"></param> 621
622 /// <param name="end_y"></param> 622 /// <summary>
623 /// <param name="set_value"></param> 623 /// Change a land bitmap at within a square and set those points to a specific value
624 /// <returns></returns> 624 /// </summary>
625 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 625 /// <param name="land_bitmap"></param>
626 bool set_value) 626 /// <param name="start_x"></param>
627 { 627 /// <param name="start_y"></param>
628 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) 628 /// <param name="end_x"></param>
629 { 629 /// <param name="end_y"></param>
630 //Throw an exception - The bitmap is not 64x64 630 /// <param name="set_value"></param>
631 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); 631 /// <returns></returns>
632 } 632 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
633 633 bool set_value)
634 int x, y; 634 {
635 for (y = 0; y < 64; y++) 635 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
636 { 636 {
637 for (x = 0; x < 64; x++) 637 //Throw an exception - The bitmap is not 64x64
638 { 638 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
639 if (x >= start_x / 4 && x < end_x / 4 639 }
640 && y >= start_y / 4 && y < end_y / 4) 640
641 { 641 int x, y;
642 land_bitmap[x, y] = set_value; 642 for (y = 0; y < 64; y++)
643 } 643 {
644 } 644 for (x = 0; x < 64; x++)
645 } 645 {
646 return land_bitmap; 646 if (x >= start_x / 4 && x < end_x / 4
647 } 647 && y >= start_y / 4 && y < end_y / 4)
648 648 {
649 /// <summary> 649 land_bitmap[x, y] = set_value;
650 /// Join the true values of 2 bitmaps together 650 }
651 /// </summary> 651 }
652 /// <param name="bitmap_base"></param> 652 }
653 /// <param name="bitmap_add"></param> 653 return land_bitmap;
654 /// <returns></returns> 654 }
655 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 655
656 { 656 /// <summary>
657 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 657 /// Join the true values of 2 bitmaps together
658 { 658 /// </summary>
659 //Throw an exception - The bitmap is not 64x64 659 /// <param name="bitmap_base"></param>
660 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 660 /// <param name="bitmap_add"></param>
661 } 661 /// <returns></returns>
662 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 662 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
663 { 663 {
664 //Throw an exception - The bitmap is not 64x64 664 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
665 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); 665 {
666 } 666 //Throw an exception - The bitmap is not 64x64
667 667 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
668 int x, y; 668 }
669 for (y = 0; y < 64; y++) 669 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
670 { 670 {
671 for (x = 0; x < 64; x++) 671 //Throw an exception - The bitmap is not 64x64
672 { 672 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
673 if (bitmap_add[x, y]) 673 }
674 { 674
675 bitmap_base[x, y] = true; 675 int x, y;
676 } 676 for (y = 0; y < 64; y++)
677 } 677 {
678 } 678 for (x = 0; x < 64; x++)
679 return bitmap_base; 679 {
680 } 680 if (bitmap_add[x, y])
681 681 {
682 /// <summary> 682 bitmap_base[x, y] = true;
683 /// Converts the land bitmap to a packet friendly byte array 683 }
684 /// </summary> 684 }
685 /// <returns></returns> 685 }
686 private byte[] ConvertLandBitmapToBytes() 686 return bitmap_base;
687 { 687 }
688 byte[] tempConvertArr = new byte[512]; 688
689 byte tempByte = 0; 689 /// <summary>
690 int x, y, i, byteNum = 0; 690 /// Converts the land bitmap to a packet friendly byte array
691 i = 0; 691 /// </summary>
692 for (y = 0; y < 64; y++) 692 /// <returns></returns>
693 { 693 private byte[] ConvertLandBitmapToBytes()
694 for (x = 0; x < 64; x++) 694 {
695 { 695 byte[] tempConvertArr = new byte[512];
696 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 696 byte tempByte = 0;
697 if (i % 8 == 0) 697 int x, y, i, byteNum = 0;
698 { 698 i = 0;
699 tempConvertArr[byteNum] = tempByte; 699 for (y = 0; y < 64; y++)
700 tempByte = (byte) 0; 700 {
701 i = 0; 701 for (x = 0; x < 64; x++)
702 byteNum++; 702 {
703 } 703 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
704 } 704 if (i % 8 == 0)
705 } 705 {
706 return tempConvertArr; 706 tempConvertArr[byteNum] = tempByte;
707 } 707 tempByte = (byte) 0;
708 708 i = 0;
709 private bool[,] ConvertBytesToLandBitmap() 709 byteNum++;
710 { 710 }
711 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; 711 }
712 tempConvertMap.Initialize(); 712 }
713 byte tempByte = 0; 713 return tempConvertArr;
714 int x = 0, y = 0, i = 0, bitNum = 0; 714 }
715 for (i = 0; i < 512; i++) 715
716 { 716 private bool[,] ConvertBytesToLandBitmap()
717 tempByte = LandData.Bitmap[i]; 717 {
718 for (bitNum = 0; bitNum < 8; bitNum++) 718 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax];
719 { 719 tempConvertMap.Initialize();
720 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 720 byte tempByte = 0;
721 tempConvertMap[x, y] = bit; 721 int x = 0, y = 0, i = 0, bitNum = 0;
722 x++; 722 for (i = 0; i < 512; i++)
723 if (x > 63) 723 {
724 { 724 tempByte = LandData.Bitmap[i];
725 x = 0; 725 for (bitNum = 0; bitNum < 8; bitNum++)
726 y++; 726 {
727 } 727 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
728 } 728 tempConvertMap[x, y] = bit;
729 } 729 x++;
730 return tempConvertMap; 730 if (x > 63)
731 } 731 {
732 732 x = 0;
733 #endregion 733 y++;
734 734 }
735 #region Object Select and Object Owner Listing 735 }
736 736 }
737 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client) 737 return tempConvertMap;
738 { 738 }
739 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) 739
740 { 740 #endregion
741 List<uint> resultLocalIDs = new List<uint>(); 741
742 try 742 #region Object Select and Object Owner Listing
743 { 743
744 lock (primsOverMe) 744 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
745 { 745 {
746 foreach (SceneObjectGroup obj in primsOverMe) 746 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
747 { 747 {
748 if (obj.LocalId > 0) 748 List<uint> resultLocalIDs = new List<uint>();
749 { 749 try
750 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) 750 {
751 { 751 lock (primsOverMe)
752 resultLocalIDs.Add(obj.LocalId); 752 {
753 } 753 foreach (SceneObjectGroup obj in primsOverMe)
754 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) 754 {
755 { 755 if (obj.LocalId > 0)
756 resultLocalIDs.Add(obj.LocalId); 756 {
757 } 757 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID)
758 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && 758 {
759 obj.OwnerID != remote_client.AgentId) 759 resultLocalIDs.Add(obj.LocalId);
760 { 760 }
761 resultLocalIDs.Add(obj.LocalId); 761 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero)
762 } 762 {
763 else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) 763 resultLocalIDs.Add(obj.LocalId);
764 { 764 }
765 resultLocalIDs.Add(obj.LocalId); 765 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
766 } 766 obj.OwnerID != remote_client.AgentId)
767 } 767 {
768 } 768 resultLocalIDs.Add(obj.LocalId);
769 } 769 }
770 } catch (InvalidOperationException) 770 else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID))
771 { 771 {
772 m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); 772 resultLocalIDs.Add(obj.LocalId);
773 } 773 }
774 774 }
775 remote_client.SendForceClientSelectObjects(resultLocalIDs); 775 }
776 } 776 }
777 } 777 } catch (InvalidOperationException)
778 778 {
779 /// <summary> 779 m_log.Error("[LAND]: Unable to force select the parcel objects. Arr.");
780 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes 780 }
781 /// aggreagete details such as the number of prims. 781
782 /// 782 remote_client.SendForceClientSelectObjects(resultLocalIDs);
783 /// </summary> 783 }
784 /// <param name="remote_client"> 784 }
785 /// A <see cref="IClientAPI"/> 785
786 /// </param> 786 /// <summary>
787 public void SendLandObjectOwners(IClientAPI remote_client) 787 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
788 { 788 /// aggreagete details such as the number of prims.
789 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) 789 ///
790 { 790 /// </summary>
791 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>(); 791 /// <param name="remote_client">
792 List<UUID> groups = new List<UUID>(); 792 /// A <see cref="IClientAPI"/>
793 793 /// </param>
794 lock (primsOverMe) 794 public void SendLandObjectOwners(IClientAPI remote_client)
795 { 795 {
796 try 796 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
797 { 797 {
798 798 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
799 foreach (SceneObjectGroup obj in primsOverMe) 799 List<UUID> groups = new List<UUID>();
800 { 800
801 try 801 lock (primsOverMe)
802 { 802 {
803 if (!primCount.ContainsKey(obj.OwnerID)) 803 try
804 { 804 {
805 primCount.Add(obj.OwnerID, 0); 805
806 } 806 foreach (SceneObjectGroup obj in primsOverMe)
807 } 807 {
808 catch (NullReferenceException) 808 try
809 { 809 {
810 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); 810 if (!primCount.ContainsKey(obj.OwnerID))
811 } 811 {
812 try 812 primCount.Add(obj.OwnerID, 0);
813 { 813 }
814 primCount[obj.OwnerID] += obj.PrimCount; 814 }
815 } 815 catch (NullReferenceException)
816 catch (KeyNotFoundException) 816 {
817 { 817 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
818 m_log.Error("[LAND]: Unable to match a prim with it's owner."); 818 }
819 } 819 try
820 if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) 820 {
821 groups.Add(obj.OwnerID); 821 primCount[obj.OwnerID] += obj.PrimCount;
822 } 822 }
823 } 823 catch (KeyNotFoundException)
824 catch (InvalidOperationException) 824 {
825 { 825 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
826 m_log.Error("[LAND]: Unable to Enumerate Land object arr."); 826 }
827 } 827 if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID)))
828 } 828 groups.Add(obj.OwnerID);
829 829 }
830 remote_client.SendLandObjectOwners(LandData, groups, primCount); 830 }
831 } 831 catch (InvalidOperationException)
832 } 832 {
833 833 m_log.Error("[LAND]: Unable to Enumerate Land object arr.");
834 public Dictionary<UUID, int> GetLandObjectOwners() 834 }
835 { 835 }
836 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>(); 836
837 lock (primsOverMe) 837 remote_client.SendLandObjectOwners(LandData, groups, primCount);
838 { 838 }
839 try 839 }
840 { 840
841 841 public Dictionary<UUID, int> GetLandObjectOwners()
842 foreach (SceneObjectGroup obj in primsOverMe) 842 {
843 { 843 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>();
844 if (!ownersAndCount.ContainsKey(obj.OwnerID)) 844 lock (primsOverMe)
845 { 845 {
846 ownersAndCount.Add(obj.OwnerID, 0); 846 try
847 } 847 {
848 ownersAndCount[obj.OwnerID] += obj.PrimCount; 848
849 } 849 foreach (SceneObjectGroup obj in primsOverMe)
850 } 850 {
851 catch (InvalidOperationException) 851 if (!ownersAndCount.ContainsKey(obj.OwnerID))
852 { 852 {
853 m_log.Error("[LAND]: Unable to enumerate land owners. arr."); 853 ownersAndCount.Add(obj.OwnerID, 0);
854 } 854 }
855 855 ownersAndCount[obj.OwnerID] += obj.PrimCount;
856 } 856 }
857 return ownersAndCount; 857 }
858 } 858 catch (InvalidOperationException)
859 859 {
860 #endregion 860 m_log.Error("[LAND]: Unable to enumerate land owners. arr.");
861 861 }
862 #region Object Returning 862
863 863 }
864 public void ReturnObject(SceneObjectGroup obj) 864 return ownersAndCount;
865 { 865 }
866 SceneObjectGroup[] objs = new SceneObjectGroup[1]; 866
867 objs[0] = obj; 867 #endregion
868 m_scene.returnObjects(objs, obj.OwnerID); 868
869 } 869 #region Object Returning
870 870
871 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) 871 public void ReturnObject(SceneObjectGroup obj)
872 { 872 {
873 Dictionary<UUID,List<SceneObjectGroup>> returns = 873 SceneObjectGroup[] objs = new SceneObjectGroup[1];
874 new Dictionary<UUID,List<SceneObjectGroup>>(); 874 objs[0] = obj;
875 875 m_scene.returnObjects(objs, obj.OwnerID);
876 lock (primsOverMe) 876 }
877 { 877
878 if (type == (uint)ObjectReturnType.Owner) 878 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client)
879 { 879 {
880 foreach (SceneObjectGroup obj in primsOverMe) 880 Dictionary<UUID,List<SceneObjectGroup>> returns =
881 { 881 new Dictionary<UUID,List<SceneObjectGroup>>();
882 if (obj.OwnerID == m_landData.OwnerID) 882
883 { 883 lock (primsOverMe)
884 if (!returns.ContainsKey(obj.OwnerID)) 884 {
885 returns[obj.OwnerID] = 885 if (type == (uint)ObjectReturnType.Owner)
886 new List<SceneObjectGroup>(); 886 {
887 returns[obj.OwnerID].Add(obj); 887 foreach (SceneObjectGroup obj in primsOverMe)
888 } 888 {
889 } 889 if (obj.OwnerID == m_landData.OwnerID)
890 } 890 {
891 else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) 891 if (!returns.ContainsKey(obj.OwnerID))
892 { 892 returns[obj.OwnerID] =
893 foreach (SceneObjectGroup obj in primsOverMe) 893 new List<SceneObjectGroup>();
894 { 894 returns[obj.OwnerID].Add(obj);
895 if (obj.GroupID == m_landData.GroupID) 895 }
896 { 896 }
897 if (!returns.ContainsKey(obj.OwnerID)) 897 }
898 returns[obj.OwnerID] = 898 else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero)
899 new List<SceneObjectGroup>(); 899 {
900 returns[obj.OwnerID].Add(obj); 900 foreach (SceneObjectGroup obj in primsOverMe)
901 } 901 {
902 } 902 if (obj.GroupID == m_landData.GroupID)
903 } 903 {
904 else if (type == (uint)ObjectReturnType.Other) 904 if (!returns.ContainsKey(obj.OwnerID))
905 { 905 returns[obj.OwnerID] =
906 foreach (SceneObjectGroup obj in primsOverMe) 906 new List<SceneObjectGroup>();
907 { 907 returns[obj.OwnerID].Add(obj);
908 if (obj.OwnerID != m_landData.OwnerID && 908 }
909 (obj.GroupID != m_landData.GroupID || 909 }
910 m_landData.GroupID == UUID.Zero)) 910 }
911 { 911 else if (type == (uint)ObjectReturnType.Other)
912 if (!returns.ContainsKey(obj.OwnerID)) 912 {
913 returns[obj.OwnerID] = 913 foreach (SceneObjectGroup obj in primsOverMe)
914 new List<SceneObjectGroup>(); 914 {
915 returns[obj.OwnerID].Add(obj); 915 if (obj.OwnerID != m_landData.OwnerID &&
916 } 916 (obj.GroupID != m_landData.GroupID ||
917 } 917 m_landData.GroupID == UUID.Zero))
918 } 918 {
919 else if (type == (uint)ObjectReturnType.List) 919 if (!returns.ContainsKey(obj.OwnerID))
920 { 920 returns[obj.OwnerID] =
921 List<UUID> ownerlist = new List<UUID>(owners); 921 new List<SceneObjectGroup>();
922 922 returns[obj.OwnerID].Add(obj);
923 foreach (SceneObjectGroup obj in primsOverMe) 923 }
924 { 924 }
925 if (ownerlist.Contains(obj.OwnerID)) 925 }
926 { 926 else if (type == (uint)ObjectReturnType.List)
927 if (!returns.ContainsKey(obj.OwnerID)) 927 {
928 returns[obj.OwnerID] = 928 List<UUID> ownerlist = new List<UUID>(owners);
929 new List<SceneObjectGroup>(); 929
930 returns[obj.OwnerID].Add(obj); 930 foreach (SceneObjectGroup obj in primsOverMe)
931 } 931 {
932 } 932 if (ownerlist.Contains(obj.OwnerID))
933 } 933 {
934 } 934 if (!returns.ContainsKey(obj.OwnerID))
935 935 returns[obj.OwnerID] =
936 foreach (List<SceneObjectGroup> ol in returns.Values) 936 new List<SceneObjectGroup>();
937 { 937 returns[obj.OwnerID].Add(obj);
938 if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) 938 }
939 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); 939 }
940 } 940 }
941 } 941 }
942 942
943 #endregion 943 foreach (List<SceneObjectGroup> ol in returns.Values)
944 944 {
945 #region Object Adding/Removing from Parcel 945 if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol))
946 946 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId);
947 public void ResetLandPrimCounts() 947 }
948 { 948 }
949 LandData.GroupPrims = 0; 949
950 LandData.OwnerPrims = 0; 950 #endregion
951 LandData.OtherPrims = 0; 951
952 LandData.SelectedPrims = 0; 952 #region Object Adding/Removing from Parcel
953 953
954 954 public void ResetLandPrimCounts()
955 lock (primsOverMe) 955 {
956 primsOverMe.Clear(); 956 LandData.GroupPrims = 0;
957 } 957 LandData.OwnerPrims = 0;
958 958 LandData.OtherPrims = 0;
959 public void AddPrimToCount(SceneObjectGroup obj) 959 LandData.SelectedPrims = 0;
960 { 960
961 961
962 UUID prim_owner = obj.OwnerID; 962 lock (primsOverMe)
963 int prim_count = obj.PrimCount; 963 primsOverMe.Clear();
964 964 }
965 if (obj.IsSelected) 965
966 { 966 public void AddPrimToCount(SceneObjectGroup obj)
967 LandData.SelectedPrims += prim_count; 967 {
968 } 968
969 else 969 UUID prim_owner = obj.OwnerID;
970 { 970 int prim_count = obj.PrimCount;
971 if (prim_owner == LandData.OwnerID) 971
972 { 972 if (obj.IsSelected)
973 LandData.OwnerPrims += prim_count; 973 {
974 } 974 LandData.SelectedPrims += prim_count;
975 else if ((obj.GroupID == LandData.GroupID || 975 }
976 prim_owner == LandData.GroupID) && 976 else
977 LandData.GroupID != UUID.Zero) 977 {
978 { 978 if (prim_owner == LandData.OwnerID)
979 LandData.GroupPrims += prim_count; 979 {
980 } 980 LandData.OwnerPrims += prim_count;
981 else 981 }
982 { 982 else if ((obj.GroupID == LandData.GroupID ||
983 LandData.OtherPrims += prim_count; 983 prim_owner == LandData.GroupID) &&
984 } 984 LandData.GroupID != UUID.Zero)
985 } 985 {
986 986 LandData.GroupPrims += prim_count;
987 lock (primsOverMe) 987 }
988 primsOverMe.Add(obj); 988 else
989 } 989 {
990 990 LandData.OtherPrims += prim_count;
991 public void RemovePrimFromCount(SceneObjectGroup obj) 991 }
992 { 992 }
993 lock (primsOverMe) 993
994 { 994 lock (primsOverMe)
995 if (primsOverMe.Contains(obj)) 995 primsOverMe.Add(obj);
996 { 996 }
997 UUID prim_owner = obj.OwnerID; 997
998 int prim_count = obj.PrimCount; 998 public void RemovePrimFromCount(SceneObjectGroup obj)
999 999 {
1000 if (prim_owner == LandData.OwnerID) 1000 lock (primsOverMe)
1001 { 1001 {
1002 LandData.OwnerPrims -= prim_count; 1002 if (primsOverMe.Contains(obj))
1003 } 1003 {
1004 else if (obj.GroupID == LandData.GroupID || 1004 UUID prim_owner = obj.OwnerID;
1005 prim_owner == LandData.GroupID) 1005 int prim_count = obj.PrimCount;
1006 { 1006
1007 LandData.GroupPrims -= prim_count; 1007 if (prim_owner == LandData.OwnerID)
1008 } 1008 {
1009 else 1009 LandData.OwnerPrims -= prim_count;
1010 { 1010 }
1011 LandData.OtherPrims -= prim_count; 1011 else if (obj.GroupID == LandData.GroupID ||
1012 } 1012 prim_owner == LandData.GroupID)
1013 1013 {
1014 primsOverMe.Remove(obj); 1014 LandData.GroupPrims -= prim_count;
1015 } 1015 }
1016 } 1016 else
1017 } 1017 {
1018 1018 LandData.OtherPrims -= prim_count;
1019 #endregion 1019 }
1020 1020
1021 #endregion 1021 primsOverMe.Remove(obj);
1022 1022 }
1023 #endregion 1023 }
1024 1024 }
1025 /// <summary> 1025
1026 /// Set the media url for this land parcel 1026 #endregion
1027 /// </summary> 1027
1028 /// <param name="url"></param> 1028 #endregion
1029 public void SetMediaUrl(string url) 1029
1030 { 1030 #endregion
1031 LandData.MediaURL = url; 1031
1032 SendLandUpdateToAvatarsOverMe(); 1032 /// <summary>
1033 } 1033 /// Set the media url for this land parcel
1034 1034 /// </summary>
1035 /// <summary> 1035 /// <param name="url"></param>
1036 /// Set the music url for this land parcel 1036 public void SetMediaUrl(string url)
1037 /// </summary> 1037 {
1038 /// <param name="url"></param> 1038 LandData.MediaURL = url;
1039 public void SetMusicUrl(string url) 1039 SendLandUpdateToAvatarsOverMe();
1040 { 1040 }
1041 LandData.MusicURL = url; 1041
1042 SendLandUpdateToAvatarsOverMe(); 1042 /// <summary>
1043 } 1043 /// Set the music url for this land parcel
1044 } 1044 /// </summary>
1045} 1045 /// <param name="url"></param>
1046 public void SetMusicUrl(string url)
1047 {
1048 LandData.MusicURL = url;
1049 SendLandUpdateToAvatarsOverMe();
1050 }
1051 }
1052}
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 62abd4c..8ce6daf 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
128 group.SetOwnerId(remoteClient.AgentId); 128 group.SetOwnerId(remoteClient.AgentId);
129 group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); 129 group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
130 130
131 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); 131 List<SceneObjectPart> partList = null;
132
133 lock (group.Children)
134 partList = new List<SceneObjectPart>(group.Children.Values);
132 135
133 if (m_scene.Permissions.PropagatePermissions()) 136 if (m_scene.Permissions.PropagatePermissions())
134 { 137 {
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
index b96d95a..57eff8a 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs
@@ -227,8 +227,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
227 { 227 {
228 SceneObjectGroup mapdot = (SceneObjectGroup)obj; 228 SceneObjectGroup mapdot = (SceneObjectGroup)obj;
229 Color mapdotspot = Color.Gray; // Default color when prim color is white 229 Color mapdotspot = Color.Gray; // Default color when prim color is white
230 // Loop over prim in group 230
231 foreach (SceneObjectPart part in mapdot.Children.Values) 231 // Loop over prim in group
232 List<SceneObjectPart> partList = null;
233 lock (mapdot.Children)
234 partList = new List<SceneObjectPart>(mapdot.Children.Values);
235
236 foreach (SceneObjectPart part in partList)
232 { 237 {
233 if (part == null) 238 if (part == null)
234 continue; 239 continue;
diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
index c489972..3c39f9e 100644
--- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
+++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs
@@ -142,9 +142,18 @@ namespace OpenSim.Region.DataSnapshot.Providers
142 node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString(); 142 node.InnerText = m_scene.RegionInfo.RegionSettings.RegionUUID.ToString();
143 xmlobject.AppendChild(node); 143 xmlobject.AppendChild(node);
144 144
145 node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", ""); 145 if (land != null && land.LandData != null)
146 node.InnerText = land.LandData.GlobalID.ToString(); 146 {
147 xmlobject.AppendChild(node); 147 node = nodeFactory.CreateNode(XmlNodeType.Element, "parceluuid", "");
148 node.InnerText = land.LandData.GlobalID.ToString();
149 xmlobject.AppendChild(node);
150 }
151 else
152 {
153 // Something is wrong with this object. Let's not list it.
154 m_log.WarnFormat("[DATASNAPSHOT]: Bad data for object {0} ({1}) in region {2}", obj.Name, obj.UUID, m_scene.RegionInfo.RegionName);
155 continue;
156 }
148 157
149 node = nodeFactory.CreateNode(XmlNodeType.Element, "location", ""); 158 node = nodeFactory.CreateNode(XmlNodeType.Element, "location", "");
150 Vector3 loc = obj.AbsolutePosition; 159 Vector3 loc = obj.AbsolutePosition;
diff --git a/OpenSim/Region/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/DataSnapshot/SnapshotStore.cs
index 70cb205..aa3d2ff 100644
--- a/OpenSim/Region/DataSnapshot/SnapshotStore.cs
+++ b/OpenSim/Region/DataSnapshot/SnapshotStore.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Text; 32using System.Text;
33using System.Text.RegularExpressions;
33using System.Xml; 34using System.Xml;
34using log4net; 35using log4net;
35using OpenSim.Region.DataSnapshot.Interfaces; 36using OpenSim.Region.DataSnapshot.Interfaces;
@@ -98,13 +99,21 @@ namespace OpenSim.Region.DataSnapshot
98 { 99 {
99 String path = DataFileNameFragment(provider.GetParentScene, provider.Name); 100 String path = DataFileNameFragment(provider.GetParentScene, provider.Name);
100 101
101 using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) 102 try
102 { 103 {
103 snapXWriter.Formatting = Formatting.Indented; 104 using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default))
104 snapXWriter.WriteStartDocument(); 105 {
105 data.WriteTo(snapXWriter); 106 snapXWriter.Formatting = Formatting.Indented;
106 snapXWriter.WriteEndDocument(); 107 snapXWriter.WriteStartDocument();
108 data.WriteTo(snapXWriter);
109 snapXWriter.WriteEndDocument();
110 }
111 }
112 catch (Exception e)
113 {
114 m_log.WarnFormat("[DATASNAPSHOT]: Exception on writing to file {0}: {1}", path, e.Message);
107 } 115 }
116
108 } 117 }
109 118
110 //mark provider as not stale, parent scene as stale 119 //mark provider as not stale, parent scene as stale
@@ -185,12 +194,19 @@ namespace OpenSim.Region.DataSnapshot
185 //save snapshot 194 //save snapshot
186 String path = DataFileNameScene(scene); 195 String path = DataFileNameScene(scene);
187 196
188 using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default)) 197 try
198 {
199 using (XmlTextWriter snapXWriter = new XmlTextWriter(path, Encoding.Default))
200 {
201 snapXWriter.Formatting = Formatting.Indented;
202 snapXWriter.WriteStartDocument();
203 regionElement.WriteTo(snapXWriter);
204 snapXWriter.WriteEndDocument();
205 }
206 }
207 catch (Exception e)
189 { 208 {
190 snapXWriter.Formatting = Formatting.Indented; 209 m_log.WarnFormat("[DATASNAPSHOT]: Exception on writing to file {0}: {1}", path, e.Message);
191 snapXWriter.WriteStartDocument();
192 regionElement.WriteTo(snapXWriter);
193 snapXWriter.WriteEndDocument();
194 } 210 }
195 211
196 m_scenes[scene] = false; 212 m_scenes[scene] = false;
@@ -206,15 +222,23 @@ namespace OpenSim.Region.DataSnapshot
206 #region Helpers 222 #region Helpers
207 private string DataFileNameFragment(Scene scene, String fragmentName) 223 private string DataFileNameFragment(Scene scene, String fragmentName)
208 { 224 {
209 return Path.Combine(m_directory, Path.ChangeExtension(scene.RegionInfo.RegionName + "_" + fragmentName, "xml")); 225 return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName + "_" + fragmentName), "xml"));
210 } 226 }
211 227
212 private string DataFileNameScene(Scene scene) 228 private string DataFileNameScene(Scene scene)
213 { 229 {
214 return Path.Combine(m_directory, Path.ChangeExtension(scene.RegionInfo.RegionName, "xml")); 230 return Path.Combine(m_directory, Path.ChangeExtension(Sanitize(scene.RegionInfo.RegionName), "xml"));
215 //return (m_snapsDir + Path.DirectorySeparatorChar + scene.RegionInfo.RegionName + ".xml"); 231 //return (m_snapsDir + Path.DirectorySeparatorChar + scene.RegionInfo.RegionName + ".xml");
216 } 232 }
217 233
234 private static string Sanitize(string name)
235 {
236 string invalidChars = Regex.Escape(new string(Path.GetInvalidFileNameChars()));
237 string invalidReStr = string.Format(@"[{0}]", invalidChars);
238 string newname = Regex.Replace(name, invalidReStr, "_");
239 return newname.Replace('.', '_');
240 }
241
218 private XmlNode MakeRegionNode(Scene scene, XmlDocument basedoc) 242 private XmlNode MakeRegionNode(Scene scene, XmlDocument basedoc)
219 { 243 {
220 XmlNode docElement = basedoc.CreateNode(XmlNodeType.Element, "region", ""); 244 XmlNode docElement = basedoc.CreateNode(XmlNodeType.Element, "region", "");
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 9fe6d96..59c035f 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -136,5 +136,13 @@ namespace OpenSim.Region.Framework.Interfaces
136 /// A <see cref="IClientAPI"/> 136 /// A <see cref="IClientAPI"/>
137 /// </param> 137 /// </param>
138 void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); 138 void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient);
139
140 /// <summary>
141 /// Update the position of an attachment
142 /// </summary>
143 /// <param name="client"></param>
144 /// <param name="sog"></param>
145 /// <param name="pos"></param>
146 void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos);
139 } 147 }
140} 148}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 1e2f60b..f5cd528 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
29using System.Collections; 29using System.Collections;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes;
32 33
33namespace OpenSim.Region.Framework.Interfaces 34namespace OpenSim.Region.Framework.Interfaces
34{ 35{
@@ -155,6 +156,17 @@ namespace OpenSim.Region.Framework.Interfaces
155 /// If no inventory item has that name then an empty list is returned. 156 /// If no inventory item has that name then an empty list is returned.
156 /// </returns> 157 /// </returns>
157 IList<TaskInventoryItem> GetInventoryItems(string name); 158 IList<TaskInventoryItem> GetInventoryItems(string name);
159
160 /// <summary>
161 /// Get the scene object referenced by an inventory item.
162 /// </summary>
163 ///
164 /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have
165 /// been adjusted to reflect the part and item from which it originates.
166 ///
167 /// <param name="item"></param>
168 /// <returns>The scene object. Null if the scene object asset couldn't be found</returns>
169 SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item);
158 170
159 /// <summary> 171 /// <summary>
160 /// Update an existing inventory item. 172 /// Update an existing inventory item.
diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
index e093f0a..81e4952 100644
--- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
@@ -28,6 +28,7 @@
28using System.Net; 28using System.Net;
29using OpenMetaverse; 29using OpenMetaverse;
30using OpenMetaverse.Packets; 30using OpenMetaverse.Packets;
31using OpenMetaverse.Messages.Linden;
31using OpenMetaverse.StructuredData; 32using OpenMetaverse.StructuredData;
32 33
33namespace OpenSim.Region.Framework.Interfaces 34namespace OpenSim.Region.Framework.Interfaces
@@ -54,7 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces
54 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); 55 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
55 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 56 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat,
56 bool isModerator, bool textMute); 57 bool isModerator, bool textMute);
57 void ParcelProperties(ParcelPropertiesPacket parcelPropertiesPacket, UUID avatarID); 58 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
58 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); 59 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID);
59 } 60 }
60} 61}
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 145f9ed..3a3ec2b 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -31,7 +31,7 @@ namespace OpenSim.Region.Framework.Scenes
31 31
32 public class Prioritizer 32 public class Prioritizer
33 { 33 {
34 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 34// private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
35 35
36 /// <summary> 36 /// <summary>
37 /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the 37 /// 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
75 break; 75 break;
76 default: 76 default:
77 throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); 77 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
78 break;
79 } 78 }
80 79
81 // Adjust priority so that root prims are sent to the viewer first. This is especially important for 80 // Adjust priority so that root prims are sent to the viewer first. This is especially important for
@@ -122,9 +121,16 @@ namespace OpenSim.Region.Framework.Scenes
122 // Use group position for child prims 121 // Use group position for child prims
123 Vector3 entityPos; 122 Vector3 entityPos;
124 if (entity is SceneObjectPart) 123 if (entity is SceneObjectPart)
125 entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; 124 {
125 // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene
126 // before its scheduled update was triggered
127 //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
128 entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition;
129 }
126 else 130 else
131 {
127 entityPos = entity.AbsolutePosition; 132 entityPos = entity.AbsolutePosition;
133 }
128 134
129 return Vector3.DistanceSquared(presencePos, entityPos); 135 return Vector3.DistanceSquared(presencePos, entityPos);
130 } 136 }
@@ -157,7 +163,9 @@ namespace OpenSim.Region.Framework.Scenes
157 } 163 }
158 } 164 }
159 else 165 else
166 {
160 entityPos = entity.AbsolutePosition; 167 entityPos = entity.AbsolutePosition;
168 }
161 169
162 if (!presence.IsChildAgent) 170 if (!presence.IsChildAgent)
163 { 171 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index ab18c93..8760c84 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes
122 else 122 else
123 { 123 {
124 m_log.WarnFormat( 124 m_log.WarnFormat(
125 "[AGENT INVENTORY]: Agent {1} could not add item {2} {3}", 125 "[AGENT INVENTORY]: Agent {0} could not add item {1} {2}",
126 AgentID, item.Name, item.ID); 126 AgentID, item.Name, item.ID);
127 127
128 return; 128 return;
@@ -984,7 +984,6 @@ namespace OpenSim.Region.Framework.Scenes
984 984
985 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 985 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
986 { 986 {
987 Console.WriteLine("CreateAgentInventoryItemFromTask");
988 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId); 987 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId);
989 988
990 if (null == taskItem) 989 if (null == taskItem)
@@ -1055,7 +1054,10 @@ namespace OpenSim.Region.Framework.Scenes
1055 /// <param name="itemID"></param> 1054 /// <param name="itemID"></param>
1056 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId) 1055 public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId)
1057 { 1056 {
1058 m_log.Info("Adding task inventory"); 1057 m_log.DebugFormat(
1058 "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}",
1059 itemId, part.Name, folderId, remoteClient.Name);
1060
1059 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId); 1061 InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId);
1060 1062
1061 if (agentItem == null) 1063 if (agentItem == null)
@@ -1121,7 +1123,11 @@ namespace OpenSim.Region.Framework.Scenes
1121 /// <see>MoveTaskInventoryItem</see> 1123 /// <see>MoveTaskInventoryItem</see>
1122 /// </summary> 1124 /// </summary>
1123 /// <param name="remoteClient"></param> 1125 /// <param name="remoteClient"></param>
1124 /// <param name="folderID"></param> 1126 /// <param name="folderID">
1127 /// The user inventory folder to move (or copy) the item to. If null, then the most
1128 /// suitable system folder is used (e.g. the Objects folder for objects). If there is no suitable folder, then
1129 /// the item is placed in the user's root inventory folder
1130 /// </param>
1125 /// <param name="part"></param> 1131 /// <param name="part"></param>
1126 /// <param name="itemID"></param> 1132 /// <param name="itemID"></param>
1127 public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId) 1133 public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId)
@@ -1846,53 +1852,6 @@ namespace OpenSim.Region.Framework.Scenes
1846 } 1852 }
1847 } 1853 }
1848 1854
1849 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
1850 {
1851 SceneObjectGroup objectGroup = grp;
1852 if (objectGroup != null)
1853 {
1854 if (!grp.HasGroupChanged)
1855 {
1856 m_log.InfoFormat("[ATTACHMENT]: Save request for {0} which is unchanged", grp.UUID);
1857 return;
1858 }
1859
1860 m_log.InfoFormat(
1861 "[ATTACHMENT]: Updating asset for attachment {0}, attachpoint {1}",
1862 grp.UUID, grp.GetAttachmentPoint());
1863
1864 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
1865
1866 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
1867 item = InventoryService.GetItem(item);
1868
1869 if (item != null)
1870 {
1871 AssetBase asset = CreateAsset(
1872 objectGroup.GetPartName(objectGroup.LocalId),
1873 objectGroup.GetPartDescription(objectGroup.LocalId),
1874 (sbyte)AssetType.Object,
1875 Utils.StringToBytes(sceneObjectXml),
1876 remoteClient.AgentId);
1877 AssetService.Store(asset);
1878
1879 item.AssetID = asset.FullID;
1880 item.Description = asset.Description;
1881 item.Name = asset.Name;
1882 item.AssetType = asset.Type;
1883 item.InvType = (int)InventoryType.Object;
1884
1885 InventoryService.UpdateItem(item);
1886
1887 // this gets called when the agent loggs off!
1888 if (remoteClient != null)
1889 {
1890 remoteClient.SendInventoryItemCreateUpdate(item, 0);
1891 }
1892 }
1893 }
1894 }
1895
1896 public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) 1855 public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID)
1897 { 1856 {
1898 itemID = UUID.Zero; 1857 itemID = UUID.Zero;
@@ -1998,7 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes
1998 remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 1957 remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
1999 RezSelected, RemoveItem, fromTaskID, false); 1958 RezSelected, RemoveItem, fromTaskID, false);
2000 } 1959 }
2001 1960
2002 /// <summary> 1961 /// <summary>
2003 /// Rez an object into the scene from a prim's inventory. 1962 /// Rez an object into the scene from a prim's inventory.
2004 /// </summary> 1963 /// </summary>
@@ -2013,95 +1972,32 @@ namespace OpenSim.Region.Framework.Scenes
2013 SceneObjectPart sourcePart, TaskInventoryItem item, 1972 SceneObjectPart sourcePart, TaskInventoryItem item,
2014 Vector3 pos, Quaternion rot, Vector3 vel, int param) 1973 Vector3 pos, Quaternion rot, Vector3 vel, int param)
2015 { 1974 {
2016 // Rez object 1975 if (null == item)
2017 if (item != null) 1976 return null;
2018 { 1977
2019 UUID ownerID = item.OwnerID; 1978 SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item);
2020 1979
2021 AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); 1980 if (null == group)
2022 1981 return null;
2023 if (rezAsset != null) 1982
2024 { 1983 if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos))
2025 string xmlData = Utils.BytesToString(rezAsset.Data); 1984 return null;
2026 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
2027
2028 if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos))
2029 {
2030 return null;
2031 }
2032 group.ResetIDs();
2033
2034 AddNewSceneObject(group, true);
2035
2036 // we set it's position in world.
2037 group.AbsolutePosition = pos;
2038
2039 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
2040
2041 // Since renaming the item in the inventory does not affect the name stored
2042 // in the serialization, transfer the correct name from the inventory to the
2043 // object itself before we rez.
2044 rootPart.Name = item.Name;
2045 rootPart.Description = item.Description;
2046
2047 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
2048
2049 group.SetGroup(sourcePart.GroupID, null);
2050
2051 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
2052 {
2053 if (Permissions.PropagatePermissions())
2054 {
2055 foreach (SceneObjectPart part in partList)
2056 {
2057 part.EveryoneMask = item.EveryonePermissions;
2058 part.NextOwnerMask = item.NextPermissions;
2059 }
2060 group.ApplyNextOwnerPermissions();
2061 }
2062 }
2063
2064 foreach (SceneObjectPart part in partList)
2065 {
2066 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
2067 {
2068 part.LastOwnerID = part.OwnerID;
2069 part.OwnerID = item.OwnerID;
2070 part.Inventory.ChangeInventoryOwner(item.OwnerID);
2071 }
2072 part.EveryoneMask = item.EveryonePermissions;
2073 part.NextOwnerMask = item.NextPermissions;
2074 }
2075
2076 rootPart.TrimPermissions();
2077
2078 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
2079 {
2080 group.ClearPartAttachmentData();
2081 }
2082
2083 group.UpdateGroupRotationR(rot);
2084
2085 //group.ApplyPhysics(m_physicalPrim);
2086 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
2087 {
2088 group.RootPart.ApplyImpulse((vel * group.GetMass()), false);
2089 group.Velocity = vel;
2090 rootPart.ScheduleFullUpdate();
2091 }
2092 group.CreateScriptInstances(param, true, DefaultScriptEngine, 2);
2093 rootPart.ScheduleFullUpdate();
2094 1985
2095 if (!Permissions.BypassPermissions()) 1986 if (!Permissions.BypassPermissions())
2096 { 1987 {
2097 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1988 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
2098 sourcePart.Inventory.RemoveInventoryItem(item.ItemID); 1989 sourcePart.Inventory.RemoveInventoryItem(item.ItemID);
2099 }
2100 return rootPart.ParentGroup;
2101 }
2102 } 1990 }
2103 1991
2104 return null; 1992 AddNewSceneObject(group, true, pos, rot, vel);
1993
1994 // We can only call this after adding the scene object, since the scene object references the scene
1995 // to find out if scripts should be activated at all.
1996 group.CreateScriptInstances(param, true, DefaultScriptEngine, 2);
1997
1998 group.ScheduleGroupForFullUpdate();
1999
2000 return group;
2105 } 2001 }
2106 2002
2107 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) 2003 public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId)
@@ -2161,7 +2057,11 @@ namespace OpenSim.Region.Framework.Scenes
2161 sog.SetGroup(groupID, remoteClient); 2057 sog.SetGroup(groupID, remoteClient);
2162 sog.ScheduleGroupForFullUpdate(); 2058 sog.ScheduleGroupForFullUpdate();
2163 2059
2164 foreach (SceneObjectPart child in sog.Children.Values) 2060 List<SceneObjectPart> partList = null;
2061 lock (sog.Children)
2062 partList = new List<SceneObjectPart>(sog.Children.Values);
2063
2064 foreach (SceneObjectPart child in partList)
2165 child.Inventory.ChangeInventoryOwner(ownerID); 2065 child.Inventory.ChangeInventoryOwner(ownerID);
2166 } 2066 }
2167 else 2067 else
@@ -2171,8 +2071,12 @@ namespace OpenSim.Region.Framework.Scenes
2171 2071
2172 if (sog.GroupID != groupID) 2072 if (sog.GroupID != groupID)
2173 continue; 2073 continue;
2074
2075 List<SceneObjectPart> partList = null;
2076 lock (sog.Children)
2077 partList = new List<SceneObjectPart>(sog.Children.Values);
2174 2078
2175 foreach (SceneObjectPart child in sog.Children.Values) 2079 foreach (SceneObjectPart child in partList)
2176 { 2080 {
2177 child.LastOwnerID = child.OwnerID; 2081 child.LastOwnerID = child.OwnerID;
2178 child.Inventory.ChangeInventoryOwner(groupID); 2082 child.Inventory.ChangeInventoryOwner(groupID);
@@ -2180,8 +2084,7 @@ namespace OpenSim.Region.Framework.Scenes
2180 2084
2181 sog.SetOwnerId(groupID); 2085 sog.SetOwnerId(groupID);
2182 sog.ApplyNextOwnerPermissions(); 2086 sog.ApplyNextOwnerPermissions();
2183 } 2087 }
2184
2185 } 2088 }
2186 2089
2187 foreach (uint localID in localIDs) 2090 foreach (uint localID in localIDs)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index e25b1f1..c511774 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -156,21 +156,30 @@ namespace OpenSim.Region.Framework.Scenes
156 } 156 }
157 break; 157 break;
158 } 158 }
159 else 159 else
160 { 160 {
161 // We also need to check the children of this prim as they 161 // We also need to check the children of this prim as they
162 // can be selected as well and send property information 162 // can be selected as well and send property information
163 bool foundPrim = false; 163 bool foundPrim = false;
164 foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) 164
165 { 165 SceneObjectGroup sog = ent as SceneObjectGroup;
166 if (child.Value.LocalId == primLocalID) 166
167 { 167 List<SceneObjectPart> partList = null;
168 child.Value.GetProperties(remoteClient); 168 lock (sog.Children)
169 foundPrim = true; 169 partList = new List<SceneObjectPart>(sog.Children.Values);
170 break; 170
171 } 171 foreach (SceneObjectPart part in partList)
172 } 172 {
173 if (foundPrim) break; 173 if (part.LocalId == primLocalID)
174 {
175 part.GetProperties(remoteClient);
176 foundPrim = true;
177 break;
178 }
179 }
180
181 if (foundPrim)
182 break;
174 } 183 }
175 } 184 }
176 } 185 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 736b696..9fea2a0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -42,7 +42,6 @@ using OpenMetaverse.Imaging;
42using OpenSim.Framework; 42using OpenSim.Framework;
43using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
44using OpenSim.Framework.Communications; 44using OpenSim.Framework.Communications;
45
46using OpenSim.Framework.Console; 45using OpenSim.Framework.Console;
47using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes.Scripting; 47using OpenSim.Region.Framework.Scenes.Scripting;
@@ -399,6 +398,7 @@ namespace OpenSim.Region.Framework.Scenes
399 private bool m_firstHeartbeat = true; 398 private bool m_firstHeartbeat = true;
400 399
401 private object m_deleting_scene_object = new object(); 400 private object m_deleting_scene_object = new object();
401 private object m_cleaningAttachments = new object();
402 402
403 // the minimum time that must elapse before a changed object will be considered for persisted 403 // the minimum time that must elapse before a changed object will be considered for persisted
404 public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; 404 public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
@@ -1790,8 +1790,9 @@ namespace OpenSim.Region.Framework.Scenes
1790 1790
1791 if (group.RootPart == null) 1791 if (group.RootPart == null)
1792 { 1792 {
1793 m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", 1793 m_log.ErrorFormat(
1794 group.Children == null ? 0 : group.Children.Count); 1794 "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children",
1795 group.Children == null ? 0 : group.PrimCount);
1795 } 1796 }
1796 1797
1797 AddRestoredSceneObject(group, true, true); 1798 AddRestoredSceneObject(group, true, true);
@@ -2050,7 +2051,24 @@ namespace OpenSim.Region.Framework.Scenes
2050 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 2051 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
2051 { 2052 {
2052 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); 2053 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates);
2053 } 2054 }
2055
2056 /// <summary>
2057 /// Add a newly created object to the scene.
2058 /// </summary>
2059 ///
2060 /// This method does not send updates to the client - callers need to handle this themselves.
2061 /// <param name="sceneObject"></param>
2062 /// <param name="attachToBackup"></param>
2063 /// <param name="pos">Position of the object</param>
2064 /// <param name="rot">Rotation of the object</param>
2065 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
2066 /// <returns></returns>
2067 public bool AddNewSceneObject(
2068 SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
2069 {
2070 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel);
2071 }
2054 2072
2055 /// <summary> 2073 /// <summary>
2056 /// Delete every object from the scene. This does not include attachments worn by avatars. 2074 /// Delete every object from the scene. This does not include attachments worn by avatars.
@@ -2113,7 +2131,11 @@ namespace OpenSim.Region.Framework.Scenes
2113 group.RemoveScriptInstances(true); 2131 group.RemoveScriptInstances(true);
2114 } 2132 }
2115 2133
2116 foreach (SceneObjectPart part in group.Children.Values) 2134 List<SceneObjectPart> partList = null;
2135 lock (group.Children)
2136 partList = new List<SceneObjectPart>(group.Children.Values);
2137
2138 foreach (SceneObjectPart part in partList)
2117 { 2139 {
2118 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) 2140 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
2119 { 2141 {
@@ -2125,6 +2147,7 @@ namespace OpenSim.Region.Framework.Scenes
2125 part.PhysActor = null; 2147 part.PhysActor = null;
2126 } 2148 }
2127 } 2149 }
2150
2128// if (rootPart.PhysActor != null) 2151// if (rootPart.PhysActor != null)
2129// { 2152// {
2130// PhysicsScene.RemovePrim(rootPart.PhysActor); 2153// PhysicsScene.RemovePrim(rootPart.PhysActor);
@@ -2481,14 +2504,16 @@ namespace OpenSim.Region.Framework.Scenes
2481 2504
2482 // Force allocation of new LocalId 2505 // Force allocation of new LocalId
2483 // 2506 //
2484 foreach (SceneObjectPart p in sceneObject.Children.Values) 2507 lock (sceneObject.Children)
2485 p.LocalId = 0; 2508 {
2509 foreach (SceneObjectPart p in sceneObject.Children.Values)
2510 p.LocalId = 0;
2511 }
2486 2512
2487 if (sceneObject.IsAttachmentCheckFull()) // Attachment 2513 if (sceneObject.IsAttachmentCheckFull()) // Attachment
2488 { 2514 {
2489 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); 2515 sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
2490 sceneObject.RootPart.AddFlag(PrimFlags.Phantom); 2516 sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
2491
2492 2517
2493 // Don't sent a full update here because this will cause full updates to be sent twice for 2518 // Don't sent a full update here because this will cause full updates to be sent twice for
2494 // attachments on region crossings, resulting in viewer glitches. 2519 // attachments on region crossings, resulting in viewer glitches.
@@ -2502,7 +2527,6 @@ namespace OpenSim.Region.Framework.Scenes
2502 2527
2503 if (sp != null) 2528 if (sp != null)
2504 { 2529 {
2505
2506 SceneObjectGroup grp = sceneObject; 2530 SceneObjectGroup grp = sceneObject;
2507 2531
2508 m_log.DebugFormat( 2532 m_log.DebugFormat(
@@ -3210,6 +3234,7 @@ namespace OpenSim.Region.Framework.Scenes
3210 m_log.Debug("[Scene] Beginning OnRemovePresence"); 3234 m_log.Debug("[Scene] Beginning OnRemovePresence");
3211 m_eventManager.TriggerOnRemovePresence(agentID); 3235 m_eventManager.TriggerOnRemovePresence(agentID);
3212 m_log.Debug("[Scene] Finished OnRemovePresence"); 3236 m_log.Debug("[Scene] Finished OnRemovePresence");
3237
3213 ForEachClient( 3238 ForEachClient(
3214 delegate(IClientAPI client) 3239 delegate(IClientAPI client)
3215 { 3240 {
@@ -3245,6 +3270,7 @@ namespace OpenSim.Region.Framework.Scenes
3245 } 3270 }
3246 m_log.Debug("[Scene] Done. Firing RemoveCircuit"); 3271 m_log.Debug("[Scene] Done. Firing RemoveCircuit");
3247 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3272 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3273 CleanDroppedAttachments();
3248 m_log.Debug("[Scene] The avatar has left the building"); 3274 m_log.Debug("[Scene] The avatar has left the building");
3249 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3275 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3250 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); 3276 //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -3443,6 +3469,8 @@ namespace OpenSim.Region.Framework.Scenes
3443 3469
3444 if (vialogin) 3470 if (vialogin)
3445 { 3471 {
3472 CleanDroppedAttachments();
3473
3446 if (TestBorderCross(agent.startpos, Cardinals.E)) 3474 if (TestBorderCross(agent.startpos, Cardinals.E))
3447 { 3475 {
3448 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); 3476 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E);
@@ -3694,18 +3722,6 @@ namespace OpenSim.Region.Framework.Scenes
3694 return true; 3722 return true;
3695 } 3723 }
3696 3724
3697 private ILandObject GetParcelAtPoint(float x, float y)
3698 {
3699 foreach (var parcel in AllParcels())
3700 {
3701 if (parcel.ContainsPoint((int)x,(int)y))
3702 {
3703 return parcel;
3704 }
3705 }
3706 return null;
3707 }
3708
3709 /// <summary> 3725 /// <summary>
3710 /// Update an AgentCircuitData object with new information 3726 /// Update an AgentCircuitData object with new information
3711 /// </summary> 3727 /// </summary>
@@ -5041,5 +5057,45 @@ namespace OpenSim.Region.Framework.Scenes
5041 throw new Exception(error); 5057 throw new Exception(error);
5042 } 5058 }
5043 } 5059 }
5060
5061 public void CleanDroppedAttachments()
5062 {
5063 List<SceneObjectGroup> objectsToDelete =
5064 new List<SceneObjectGroup>();
5065
5066 lock (m_cleaningAttachments)
5067 {
5068 ForEachSOG(delegate (SceneObjectGroup grp)
5069 {
5070 if (grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5071 {
5072 UUID agentID = grp.OwnerID;
5073 if (agentID == UUID.Zero)
5074 {
5075 objectsToDelete.Add(grp);
5076 return;
5077 }
5078
5079 ScenePresence sp = GetScenePresence(agentID);
5080 if (sp == null)
5081 {
5082 objectsToDelete.Add(grp);
5083 return;
5084 }
5085 }
5086 });
5087 }
5088
5089 if (objectsToDelete.Count > 0)
5090 {
5091 m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count);
5092 foreach (SceneObjectGroup grp in objectsToDelete)
5093 {
5094 m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5095 DeleteSceneObject(grp, true);
5096 }
5097 m_log.Debug("[SCENE]: Finished dropped attachment deletion");
5098 }
5099 }
5044 } 5100 }
5045} 5101}
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 59e4037..1293d5d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes
70 /// <summary> 70 /// <summary>
71 /// A user will arrive shortly, set up appropriate credentials so it can connect 71 /// A user will arrive shortly, set up appropriate credentials so it can connect
72 /// </summary> 72 /// </summary>
73 public event ExpectUserDelegate OnExpectUser; 73// public event ExpectUserDelegate OnExpectUser;
74 74
75 /// <summary> 75 /// <summary>
76 /// A Prim will arrive shortly 76 /// A Prim will arrive shortly
@@ -80,7 +80,7 @@ namespace OpenSim.Region.Framework.Scenes
80 /// <summary> 80 /// <summary>
81 /// A new prim has arrived 81 /// A new prim has arrived
82 /// </summary> 82 /// </summary>
83 public event PrimCrossing OnPrimCrossingIntoRegion; 83// public event PrimCrossing OnPrimCrossingIntoRegion;
84 84
85 ///// <summary> 85 ///// <summary>
86 ///// A New Region is up and available 86 ///// A New Region is up and available
@@ -90,7 +90,7 @@ namespace OpenSim.Region.Framework.Scenes
90 /// <summary> 90 /// <summary>
91 /// We have a child agent for this avatar and we're getting a status update about it 91 /// We have a child agent for this avatar and we're getting a status update about it
92 /// </summary> 92 /// </summary>
93 public event ChildAgentUpdate OnChildAgentUpdate; 93// public event ChildAgentUpdate OnChildAgentUpdate;
94 //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; 94 //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar;
95 95
96 /// <summary> 96 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 94ec534..b86a564 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Scenes
104 104
105 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); 105 protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>();
106 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); 106 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>();
107 private readonly Object m_dictionary_lock = new Object();
108 107
109 private Object m_updateLock = new Object(); 108 private Object m_updateLock = new Object();
110 109
@@ -150,11 +149,10 @@ namespace OpenSim.Region.Framework.Scenes
150 m_scenePresencesLock.ExitWriteLock(); 149 m_scenePresencesLock.ExitWriteLock();
151 } 150 }
152 151
153 lock (m_dictionary_lock) 152 lock (SceneObjectGroupsByFullID)
154 {
155 SceneObjectGroupsByFullID.Clear(); 153 SceneObjectGroupsByFullID.Clear();
154 lock (SceneObjectGroupsByLocalID)
156 SceneObjectGroupsByLocalID.Clear(); 155 SceneObjectGroupsByLocalID.Clear();
157 }
158 156
159 Entities.Clear(); 157 Entities.Clear();
160 } 158 }
@@ -314,6 +312,42 @@ namespace OpenSim.Region.Framework.Scenes
314 312
315 return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); 313 return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
316 } 314 }
315
316 /// <summary>
317 /// Add a newly created object to the scene.
318 /// </summary>
319 ///
320 /// This method does not send updates to the client - callers need to handle this themselves.
321 /// <param name="sceneObject"></param>
322 /// <param name="attachToBackup"></param>
323 /// <param name="pos">Position of the object</param>
324 /// <param name="rot">Rotation of the object</param>
325 /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
326 /// <returns></returns>
327 public bool AddNewSceneObject(
328 SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel)
329 {
330 AddNewSceneObject(sceneObject, true, false);
331
332 // we set it's position in world.
333 sceneObject.AbsolutePosition = pos;
334
335 if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim)
336 {
337 sceneObject.ClearPartAttachmentData();
338 }
339
340 sceneObject.UpdateGroupRotationR(rot);
341
342 //group.ApplyPhysics(m_physicalPrim);
343 if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero)
344 {
345 sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false);
346 sceneObject.Velocity = vel;
347 }
348
349 return true;
350 }
317 351
318 /// <summary> 352 /// <summary>
319 /// Add an object to the scene. This will both update the scene, and send information about the 353 /// Add an object to the scene. This will both update the scene, and send information about the
@@ -350,50 +384,53 @@ namespace OpenSim.Region.Framework.Scenes
350// "[SCENE GRAPH]: Adding object {0} {1} to region {2}", 384// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
351// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); 385// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
352 386
353 if (m_parentScene.m_clampPrimSize) 387 lock (sceneObject.Children)
354 { 388 {
355 foreach (SceneObjectPart part in sceneObject.Children.Values) 389 if (m_parentScene.m_clampPrimSize)
356 { 390 {
357 Vector3 scale = part.Shape.Scale; 391 foreach (SceneObjectPart part in sceneObject.Children.Values)
358 392 {
359 if (scale.X > m_parentScene.m_maxNonphys) 393 Vector3 scale = part.Shape.Scale;
360 scale.X = m_parentScene.m_maxNonphys; 394
361 if (scale.Y > m_parentScene.m_maxNonphys) 395 if (scale.X > m_parentScene.m_maxNonphys)
362 scale.Y = m_parentScene.m_maxNonphys; 396 scale.X = m_parentScene.m_maxNonphys;
363 if (scale.Z > m_parentScene.m_maxNonphys) 397 if (scale.Y > m_parentScene.m_maxNonphys)
364 scale.Z = m_parentScene.m_maxNonphys; 398 scale.Y = m_parentScene.m_maxNonphys;
365 399 if (scale.Z > m_parentScene.m_maxNonphys)
366 part.Shape.Scale = scale; 400 scale.Z = m_parentScene.m_maxNonphys;
401
402 part.Shape.Scale = scale;
403 }
367 } 404 }
405
406 m_numPrim += sceneObject.Children.Count;
368 } 407 }
369 408
370 sceneObject.AttachToScene(m_parentScene); 409 sceneObject.AttachToScene(m_parentScene);
371 410
372 if (sendClientUpdates) 411 if (sendClientUpdates)
373 sceneObject.ScheduleGroupForFullUpdate(); 412 sceneObject.ScheduleGroupForFullUpdate();
374 413
375 Entities.Add(sceneObject); 414 Entities.Add(sceneObject);
376 m_numPrim += sceneObject.Children.Count;
377 415
378 if (attachToBackup) 416 if (attachToBackup)
379 {
380 sceneObject.AttachToBackup(); 417 sceneObject.AttachToBackup();
381 }
382 418
383 if (OnObjectCreate != null) 419 if (OnObjectCreate != null)
384 {
385 OnObjectCreate(sceneObject); 420 OnObjectCreate(sceneObject);
386 }
387 421
388 lock (m_dictionary_lock) 422 lock (SceneObjectGroupsByFullID)
389 { 423 {
390 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 424 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
391 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
392 foreach (SceneObjectPart part in sceneObject.Children.Values) 425 foreach (SceneObjectPart part in sceneObject.Children.Values)
393 {
394 SceneObjectGroupsByFullID[part.UUID] = sceneObject; 426 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
427 }
428
429 lock (SceneObjectGroupsByLocalID)
430 {
431 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
432 foreach (SceneObjectPart part in sceneObject.Children.Values)
395 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 433 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
396 }
397 } 434 }
398 } 435 }
399 436
@@ -408,24 +445,32 @@ namespace OpenSim.Region.Framework.Scenes
408 { 445 {
409 if (Entities.ContainsKey(uuid)) 446 if (Entities.ContainsKey(uuid))
410 { 447 {
448 SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid];
449
411 if (!resultOfObjectLinked) 450 if (!resultOfObjectLinked)
412 { 451 {
413 m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; 452 m_numPrim -= grp.PrimCount;
414 453
415 if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 454 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
416 { 455 RemovePhysicalPrim(grp.PrimCount);
417 RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count);
418 }
419 } 456 }
420 457
421 if (OnObjectRemove != null) 458 if (OnObjectRemove != null)
422 OnObjectRemove(Entities[uuid]); 459 OnObjectRemove(Entities[uuid]);
423 460
424 lock (m_dictionary_lock) 461 lock (SceneObjectGroupsByFullID)
425 { 462 {
426 SceneObjectGroupsByFullID.Remove(uuid); 463 foreach (SceneObjectPart part in grp.Children.Values)
427 SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); 464 SceneObjectGroupsByFullID.Remove(part.UUID);
465 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
428 } 466 }
467 lock (SceneObjectGroupsByLocalID)
468 {
469 foreach (SceneObjectPart part in grp.Children.Values)
470 SceneObjectGroupsByLocalID.Remove(part.LocalId);
471 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
472 }
473
429 Entities.Remove(uuid); 474 Entities.Remove(uuid);
430 //SceneObjectGroup part; 475 //SceneObjectGroup part;
431 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 476 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
@@ -884,7 +929,9 @@ namespace OpenSim.Region.Framework.Scenes
884 { 929 {
885 if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) 930 if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog))
886 { 931 {
887 return sog; 932 if (sog.HasChildPrim(localID))
933 return sog;
934 SceneObjectGroupsByLocalID.Remove(localID);
888 } 935 }
889 } 936 }
890 937
@@ -920,7 +967,13 @@ namespace OpenSim.Region.Framework.Scenes
920 { 967 {
921 if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) 968 if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog))
922 { 969 {
923 return sog; 970 lock (sog.Children)
971 {
972 if (sog.Children.ContainsKey(fullID))
973 return sog;
974 }
975
976 SceneObjectGroupsByFullID.Remove(fullID);
924 } 977 }
925 } 978 }
926 979
@@ -1087,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes
1087 /// <param name="action"></param> 1140 /// <param name="action"></param>
1088 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1141 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1089 { 1142 {
1090 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1143 List<EntityBase> objlist = Entities.GetAllByType<SceneObjectGroup>();
1091 foreach (SceneObjectGroup obj in objlist) 1144 foreach (EntityBase ent in objlist)
1092 { 1145 {
1146 SceneObjectGroup obj = (SceneObjectGroup)ent;
1147
1093 try 1148 try
1094 { 1149 {
1095 action(obj); 1150 action(obj);
@@ -1293,37 +1348,21 @@ namespace OpenSim.Region.Framework.Scenes
1293 /// <param name="localID"></param> 1348 /// <param name="localID"></param>
1294 /// <param name="pos"></param> 1349 /// <param name="pos"></param>
1295 /// <param name="remoteClient"></param> 1350 /// <param name="remoteClient"></param>
1296 protected internal void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) 1351 public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient)
1297 { 1352 {
1298 SceneObjectGroup group = GetGroupByPrim(localID); 1353 SceneObjectGroup group = GetGroupByPrim(localID);
1354
1299 if (group != null) 1355 if (group != null)
1300 { 1356 {
1301
1302 // Vector3 oldPos = group.AbsolutePosition;
1303 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1357 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1304 { 1358 {
1305 1359 if (m_parentScene.AttachmentsModule != null)
1306 // If this is an attachment, then we need to save the modified 1360 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos);
1307 // object back into the avatar's inventory. First we save the
1308 // attachment point information, then we update the relative
1309 // positioning (which caused this method to get driven in the
1310 // first place. Then we have to mark the object as NOT an
1311 // attachment. This is necessary in order to correctly save
1312 // and retrieve GroupPosition information for the attachment.
1313 // Then we save the asset back into the appropriate inventory
1314 // entry. Finally, we restore the object's attachment status.
1315
1316 byte attachmentPoint = group.GetAttachmentPoint();
1317 group.UpdateGroupPosition(pos);
1318 group.RootPart.IsAttachment = false;
1319 group.AbsolutePosition = group.RootPart.AttachedPos;
1320 m_parentScene.UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID);
1321 group.SetAttachmentPoint(attachmentPoint);
1322
1323 } 1361 }
1324 else 1362 else
1325 { 1363 {
1326 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) 1364 if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId)
1365 && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos))
1327 { 1366 {
1328 group.UpdateGroupPosition(pos); 1367 group.UpdateGroupPosition(pos);
1329 } 1368 }
@@ -1332,14 +1371,19 @@ namespace OpenSim.Region.Framework.Scenes
1332 } 1371 }
1333 1372
1334 /// <summary> 1373 /// <summary>
1335 /// 1374 /// Update the texture entry of the given prim.
1336 /// </summary> 1375 /// </summary>
1376 ///
1377 /// A texture entry is an object that contains details of all the textures of the prim's face. In this case,
1378 /// the texture is given in its byte serialized form.
1379 ///
1337 /// <param name="localID"></param> 1380 /// <param name="localID"></param>
1338 /// <param name="texture"></param> 1381 /// <param name="texture"></param>
1339 /// <param name="remoteClient"></param> 1382 /// <param name="remoteClient"></param>
1340 protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) 1383 protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient)
1341 { 1384 {
1342 SceneObjectGroup group = GetGroupByPrim(localID); 1385 SceneObjectGroup group = GetGroupByPrim(localID);
1386
1343 if (group != null) 1387 if (group != null)
1344 { 1388 {
1345 if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) 1389 if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId))
@@ -1630,7 +1674,7 @@ namespace OpenSim.Region.Framework.Scenes
1630 { 1674 {
1631 if (part != null) 1675 if (part != null)
1632 { 1676 {
1633 if (part.ParentGroup.Children.Count != 1) // Skip single 1677 if (part.ParentGroup.PrimCount != 1) // Skip single
1634 { 1678 {
1635 if (part.LinkNum < 2) // Root 1679 if (part.LinkNum < 2) // Root
1636 rootParts.Add(part); 1680 rootParts.Add(part);
@@ -1669,8 +1713,15 @@ namespace OpenSim.Region.Framework.Scenes
1669 // However, editing linked parts and unlinking may be different 1713 // However, editing linked parts and unlinking may be different
1670 // 1714 //
1671 SceneObjectGroup group = root.ParentGroup; 1715 SceneObjectGroup group = root.ParentGroup;
1672 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); 1716
1673 int numChildren = group.Children.Count; 1717 List<SceneObjectPart> newSet = null;
1718 int numChildren = -1;
1719
1720 lock (group.Children)
1721 {
1722 newSet = new List<SceneObjectPart>(group.Children.Values);
1723 numChildren = group.PrimCount;
1724 }
1674 1725
1675 // If there are prims left in a link set, but the root is 1726 // If there are prims left in a link set, but the root is
1676 // slated for unlink, we need to do this 1727 // slated for unlink, we need to do this
@@ -1722,8 +1773,6 @@ namespace OpenSim.Region.Framework.Scenes
1722 SceneObjectPart newRoot = newSet[0]; 1773 SceneObjectPart newRoot = newSet[0];
1723 newSet.RemoveAt(0); 1774 newSet.RemoveAt(0);
1724 1775
1725 List<uint> linkIDs = new List<uint>();
1726
1727 foreach (SceneObjectPart newChild in newSet) 1776 foreach (SceneObjectPart newChild in newSet)
1728 newChild.UpdateFlag = 0; 1777 newChild.UpdateFlag = 0;
1729 1778
@@ -1760,12 +1809,17 @@ namespace OpenSim.Region.Framework.Scenes
1760 { 1809 {
1761 if (ent is SceneObjectGroup) 1810 if (ent is SceneObjectGroup)
1762 { 1811 {
1763 foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) 1812 SceneObjectGroup sog = ent as SceneObjectGroup;
1813
1814 lock (sog.Children)
1764 { 1815 {
1765 if (subent.Value.LocalId == localID) 1816 foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children)
1766 { 1817 {
1767 objid = subent.Key; 1818 if (subent.Value.LocalId == localID)
1768 obj = subent.Value; 1819 {
1820 objid = subent.Key;
1821 obj = subent.Value;
1822 }
1769 } 1823 }
1770 } 1824 }
1771 } 1825 }
@@ -1830,7 +1884,8 @@ namespace OpenSim.Region.Framework.Scenes
1830 SceneObjectGroup original = GetGroupByPrim(originalPrimID); 1884 SceneObjectGroup original = GetGroupByPrim(originalPrimID);
1831 if (original != null) 1885 if (original != null)
1832 { 1886 {
1833 if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) 1887 if (m_parentScene.Permissions.CanDuplicateObject(
1888 original.PrimCount, original.UUID, AgentID, original.AbsolutePosition))
1834 { 1889 {
1835 SceneObjectGroup copy = original.Copy(true); 1890 SceneObjectGroup copy = original.Copy(true);
1836 copy.AbsolutePosition = copy.AbsolutePosition + offset; 1891 copy.AbsolutePosition = copy.AbsolutePosition + offset;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 9b66fad..5a586d4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -360,7 +360,7 @@ namespace OpenSim.Region.Framework.Scenes
360 /// </summary> 360 /// </summary>
361 public int PrimCount 361 public int PrimCount
362 { 362 {
363 get { return m_parts.Count; } 363 get { lock (m_parts) { return m_parts.Count; } }
364 } 364 }
365 365
366 protected Quaternion m_rotation = Quaternion.Identity; 366 protected Quaternion m_rotation = Quaternion.Identity;
@@ -398,6 +398,9 @@ namespace OpenSim.Region.Framework.Scenes
398 398
399 /// <value> 399 /// <value>
400 /// The parts of this scene object group. You must lock this property before using it. 400 /// The parts of this scene object group. You must lock this property before using it.
401 /// If you're doing anything other than reading values, please take a copy of the values rather than locking
402 /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock
403 /// If you want to know the number of children, consider using the PrimCount property instead
401 /// </value> 404 /// </value>
402 public Dictionary<UUID, SceneObjectPart> Children 405 public Dictionary<UUID, SceneObjectPart> Children
403 { 406 {
@@ -521,7 +524,16 @@ namespace OpenSim.Region.Framework.Scenes
521 public override UUID UUID 524 public override UUID UUID
522 { 525 {
523 get { return m_rootPart.UUID; } 526 get { return m_rootPart.UUID; }
524 set { m_rootPart.UUID = value; } 527 set
528 {
529 m_rootPart.UUID = value;
530
531 lock (m_parts)
532 {
533 m_parts.Remove(m_rootPart.UUID);
534 m_parts.Add(m_rootPart.UUID, m_rootPart);
535 }
536 }
525 } 537 }
526 538
527 public UUID OwnerID 539 public UUID OwnerID
@@ -742,21 +754,23 @@ namespace OpenSim.Region.Framework.Scenes
742 if (m_rootPart.LocalId == 0) 754 if (m_rootPart.LocalId == 0)
743 m_rootPart.LocalId = m_scene.AllocateLocalId(); 755 m_rootPart.LocalId = m_scene.AllocateLocalId();
744 756
745 // No need to lock here since the object isn't yet in a scene 757 lock (m_parts)
746 foreach (SceneObjectPart part in m_parts.Values)
747 { 758 {
748 if (Object.ReferenceEquals(part, m_rootPart)) 759 foreach (SceneObjectPart part in m_parts.Values)
749 {
750 continue;
751 }
752
753 if (part.LocalId == 0)
754 { 760 {
755 part.LocalId = m_scene.AllocateLocalId(); 761 if (Object.ReferenceEquals(part, m_rootPart))
762 {
763 continue;
764 }
765
766 if (part.LocalId == 0)
767 {
768 part.LocalId = m_scene.AllocateLocalId();
769 }
770
771 part.ParentID = m_rootPart.LocalId;
772 //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);
756 } 773 }
757
758 part.ParentID = m_rootPart.LocalId;
759 //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);
760 } 774 }
761 775
762 ApplyPhysics(m_scene.m_physicalPrim); 776 ApplyPhysics(m_scene.m_physicalPrim);
@@ -1238,9 +1252,12 @@ namespace OpenSim.Region.Framework.Scenes
1238 m_rootPart.AttachedAvatar = agentID; 1252 m_rootPart.AttachedAvatar = agentID;
1239 1253
1240 //Anakin Lohner bug #3839 1254 //Anakin Lohner bug #3839
1241 foreach (SceneObjectPart p in m_parts.Values) 1255 lock (m_parts)
1242 { 1256 {
1243 p.AttachedAvatar = agentID; 1257 foreach (SceneObjectPart p in m_parts.Values)
1258 {
1259 p.AttachedAvatar = agentID;
1260 }
1244 } 1261 }
1245 1262
1246 if (m_rootPart.PhysActor != null) 1263 if (m_rootPart.PhysActor != null)
@@ -1308,10 +1325,14 @@ namespace OpenSim.Region.Framework.Scenes
1308 1325
1309 AbsolutePosition = detachedpos; 1326 AbsolutePosition = detachedpos;
1310 m_rootPart.AttachedAvatar = UUID.Zero; 1327 m_rootPart.AttachedAvatar = UUID.Zero;
1311 //Anakin Lohner bug #3839 1328
1312 foreach (SceneObjectPart p in m_parts.Values) 1329 //Anakin Lohner bug #3839
1330 lock (m_parts)
1313 { 1331 {
1314 p.AttachedAvatar = UUID.Zero; 1332 foreach (SceneObjectPart p in m_parts.Values)
1333 {
1334 p.AttachedAvatar = UUID.Zero;
1335 }
1315 } 1336 }
1316 1337
1317 m_rootPart.SetParentLocalId(0); 1338 m_rootPart.SetParentLocalId(0);
@@ -1337,10 +1358,14 @@ namespace OpenSim.Region.Framework.Scenes
1337 } 1358 }
1338 1359
1339 m_rootPart.AttachedAvatar = UUID.Zero; 1360 m_rootPart.AttachedAvatar = UUID.Zero;
1361
1340 //Anakin Lohner bug #3839 1362 //Anakin Lohner bug #3839
1341 foreach (SceneObjectPart p in m_parts.Values) 1363 lock (m_parts)
1342 { 1364 {
1343 p.AttachedAvatar = UUID.Zero; 1365 foreach (SceneObjectPart p in m_parts.Values)
1366 {
1367 p.AttachedAvatar = UUID.Zero;
1368 }
1344 } 1369 }
1345 1370
1346 m_rootPart.SetParentLocalId(0); 1371 m_rootPart.SetParentLocalId(0);
@@ -1406,9 +1431,8 @@ namespace OpenSim.Region.Framework.Scenes
1406 part.ParentID = 0; 1431 part.ParentID = 0;
1407 part.LinkNum = 0; 1432 part.LinkNum = 0;
1408 1433
1409 // No locking required since the SOG should not be in the scene yet - one can't change root parts after 1434 lock (m_parts)
1410 // the scene object has been attached to the scene 1435 m_parts.Add(m_rootPart.UUID, m_rootPart);
1411 m_parts.Add(m_rootPart.UUID, m_rootPart);
1412 } 1436 }
1413 1437
1414 /// <summary> 1438 /// <summary>
@@ -1928,14 +1952,14 @@ namespace OpenSim.Region.Framework.Scenes
1928 } 1952 }
1929 1953
1930 /// <summary> 1954 /// <summary>
1931 /// 1955 /// Copy the given part as the root part of this scene object.
1932 /// </summary> 1956 /// </summary>
1933 /// <param name="part"></param> 1957 /// <param name="part"></param>
1934 /// <param name="cAgentID"></param> 1958 /// <param name="cAgentID"></param>
1935 /// <param name="cGroupID"></param> 1959 /// <param name="cGroupID"></param>
1936 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1960 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1937 { 1961 {
1938 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); 1962 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1939 } 1963 }
1940 1964
1941 public void ScriptSetPhysicsStatus(bool UsePhysics) 1965 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -2234,14 +2258,15 @@ namespace OpenSim.Region.Framework.Scenes
2234 /// </summary> 2258 /// </summary>
2235 public void ResetIDs() 2259 public void ResetIDs()
2236 { 2260 {
2237 // As this is only ever called for prims which are not currently part of the scene (and hence 2261 lock (m_parts)
2238 // not accessible by clients), there should be no need to lock
2239 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
2240 m_parts.Clear();
2241 foreach (SceneObjectPart part in partsList)
2242 { 2262 {
2243 part.ResetIDs(part.LinkNum); // Don't change link nums 2263 List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values);
2244 m_parts.Add(part.UUID, part); 2264 m_parts.Clear();
2265 foreach (SceneObjectPart part in partsList)
2266 {
2267 part.ResetIDs(part.LinkNum); // Don't change link nums
2268 m_parts.Add(part.UUID, part);
2269 }
2245 } 2270 }
2246 } 2271 }
2247 2272
@@ -2283,29 +2308,29 @@ namespace OpenSim.Region.Framework.Scenes
2283 // return; 2308 // return;
2284 2309
2285 lockPartsForRead(true); 2310 lockPartsForRead(true);
2286 {
2287 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
2288 2311
2289 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) 2312 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
2290 {
2291 m_rootPart.UpdateFlag = 1;
2292 lastPhysGroupPos = AbsolutePosition;
2293 }
2294 2313
2295 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) 2314 if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
2296 { 2315 {
2297 m_rootPart.UpdateFlag = 1; 2316 m_rootPart.UpdateFlag = 1;
2298 lastPhysGroupRot = GroupRotation; 2317 lastPhysGroupPos = AbsolutePosition;
2299 } 2318 }
2300 2319
2301 foreach (SceneObjectPart part in m_parts.Values) 2320 if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
2302 { 2321 {
2303 if (!IsSelected) 2322 m_rootPart.UpdateFlag = 1;
2304 part.UpdateLookAt(); 2323 lastPhysGroupRot = GroupRotation;
2324 }
2305 2325
2306 part.SendScheduledUpdates(); 2326 List<SceneObjectPart> partList = null;
2307 2327 partList = new List<SceneObjectPart>(m_parts.Values);
2308 } 2328
2329 foreach (SceneObjectPart part in partList)
2330 {
2331 if (!IsSelected)
2332 part.UpdateLookAt();
2333 part.SendScheduledUpdates();
2309 } 2334 }
2310 lockPartsForRead(false); 2335 lockPartsForRead(false);
2311 } 2336 }
@@ -2479,10 +2504,15 @@ namespace OpenSim.Region.Framework.Scenes
2479 public SceneObjectPart GetChildPart(UUID primID) 2504 public SceneObjectPart GetChildPart(UUID primID)
2480 { 2505 {
2481 SceneObjectPart childPart = null; 2506 SceneObjectPart childPart = null;
2482 if (m_parts.ContainsKey(primID)) 2507
2508 lock (m_parts)
2483 { 2509 {
2484 childPart = m_parts[primID]; 2510 if (m_parts.ContainsKey(primID))
2511 {
2512 childPart = m_parts[primID];
2513 }
2485 } 2514 }
2515
2486 return childPart; 2516 return childPart;
2487 } 2517 }
2488 2518
@@ -2519,9 +2549,10 @@ namespace OpenSim.Region.Framework.Scenes
2519 /// <returns></returns> 2549 /// <returns></returns>
2520 public bool HasChildPrim(UUID primID) 2550 public bool HasChildPrim(UUID primID)
2521 { 2551 {
2522 if (m_parts.ContainsKey(primID)) 2552 lock (m_parts)
2523 { 2553 {
2524 return true; 2554 if (m_parts.ContainsKey(primID))
2555 return true;
2525 } 2556 }
2526 2557
2527 return false; 2558 return false;
@@ -3132,9 +3163,12 @@ namespace OpenSim.Region.Framework.Scenes
3132 public void UpdatePermissions(UUID AgentID, byte field, uint localID, 3163 public void UpdatePermissions(UUID AgentID, byte field, uint localID,
3133 uint mask, byte addRemTF) 3164 uint mask, byte addRemTF)
3134 { 3165 {
3135 foreach (SceneObjectPart part in m_parts.Values) 3166 List<SceneObjectPart> partList = null;
3136 part.UpdatePermissions(AgentID, field, localID, mask, 3167 lock (m_parts)
3137 addRemTF); 3168 partList = new List<SceneObjectPart>(m_parts.Values);
3169
3170 foreach (SceneObjectPart part in partList)
3171 part.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
3138 3172
3139 HasGroupChanged = true; 3173 HasGroupChanged = true;
3140 } 3174 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 9e52b00..eefe8bb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4756,20 +4756,8 @@ namespace OpenSim.Region.Framework.Scenes
4756 if (ParentGroup == null || ParentGroup.IsDeleted) 4756 if (ParentGroup == null || ParentGroup.IsDeleted)
4757 return; 4757 return;
4758 4758
4759 Vector3 lPos = OffsetPosition; 4759 if (IsAttachment && ParentGroup.RootPart != this)
4760 4760 return;
4761 if (IsAttachment)
4762 {
4763 if (ParentGroup.RootPart != this)
4764 return;
4765
4766 lPos = ParentGroup.RootPart.AttachedPos;
4767 }
4768 else
4769 {
4770 if (ParentGroup.RootPart == this)
4771 lPos = AbsolutePosition;
4772 }
4773 4761
4774 // Causes this thread to dig into the Client Thread Data. 4762 // Causes this thread to dig into the Client Thread Data.
4775 // Remember your locking here! 4763 // Remember your locking here!
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 8b4f0ed..c5994b2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -37,6 +37,7 @@ using log4net;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes.Scripting; 39using OpenSim.Region.Framework.Scenes.Scripting;
40using OpenSim.Region.Framework.Scenes.Serialization;
40 41
41namespace OpenSim.Region.Framework.Scenes 42namespace OpenSim.Region.Framework.Scenes
42{ 43{
@@ -722,6 +723,70 @@ namespace OpenSim.Region.Framework.Scenes
722 return items; 723 return items;
723 } 724 }
724 725
726 public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item)
727 {
728 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
729
730 if (null == rezAsset)
731 {
732 m_log.WarnFormat(
733 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
734 item.AssetID, item.Name, m_part.Name);
735 return null;
736 }
737
738 string xmlData = Utils.BytesToString(rezAsset.Data);
739 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
740
741 group.ResetIDs();
742
743 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
744
745 // Since renaming the item in the inventory does not affect the name stored
746 // in the serialization, transfer the correct name from the inventory to the
747 // object itself before we rez.
748 rootPart.Name = item.Name;
749 rootPart.Description = item.Description;
750
751 List<SceneObjectPart> partList = null;
752
753 lock (group.Children)
754 partList = new List<SceneObjectPart>(group.Children.Values);
755
756 group.SetGroup(m_part.GroupID, null);
757
758 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
759 {
760 if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
761 {
762 foreach (SceneObjectPart part in partList)
763 {
764 part.EveryoneMask = item.EveryonePermissions;
765 part.NextOwnerMask = item.NextPermissions;
766 }
767
768 group.ApplyNextOwnerPermissions();
769 }
770 }
771
772 foreach (SceneObjectPart part in partList)
773 {
774 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0)
775 {
776 part.LastOwnerID = part.OwnerID;
777 part.OwnerID = item.OwnerID;
778 part.Inventory.ChangeInventoryOwner(item.OwnerID);
779 }
780
781 part.EveryoneMask = item.EveryonePermissions;
782 part.NextOwnerMask = item.NextPermissions;
783 }
784
785 rootPart.TrimPermissions();
786
787 return group;
788 }
789
725 /// <summary> 790 /// <summary>
726 /// Update an existing inventory item. 791 /// Update an existing inventory item.
727 /// </summary> 792 /// </summary>
@@ -1197,6 +1262,5 @@ namespace OpenSim.Region.Framework.Scenes
1197 1262
1198 Items.LockItemsForRead(false); 1263 Items.LockItemsForRead(false);
1199 } 1264 }
1200
1201 } 1265 }
1202} 1266} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 02e60f8..cd80eb0 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2668,15 +2668,15 @@ namespace OpenSim.Region.Framework.Scenes
2668 { 2668 {
2669 m_perfMonMS = Util.EnvironmentTickCount(); 2669 m_perfMonMS = Util.EnvironmentTickCount();
2670 2670
2671 PhysicsActor actor = m_physicsActor;
2672 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero;
2673
2674 Vector3 pos = m_pos; 2671 Vector3 pos = m_pos;
2675 pos.Z += m_appearance.HipOffset; 2672 pos.Z += m_appearance.HipOffset;
2676 2673
2677 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); 2674 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2678 2675
2679 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); 2676 remoteClient.SendPrimUpdate(
2677 this,
2678 PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
2679 | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
2680 2680
2681 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2681 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2682 m_scene.StatsReporter.AddAgentUpdates(1); 2682 m_scene.StatsReporter.AddAgentUpdates(1);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index fc66c85..3e2a2af 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
134 sop.Text = RandomName(); 134 sop.Text = RandomName();
135 sop.SitName = RandomName(); 135 sop.SitName = RandomName();
136 sop.TouchName = RandomName(); 136 sop.TouchName = RandomName();
137 sop.ObjectFlags |= (uint)PrimFlags.Phantom; 137 sop.Flags |= PrimFlags.Phantom;
138 138
139 SceneObjectGroup sog = new SceneObjectGroup(sop); 139 SceneObjectGroup sog = new SceneObjectGroup(sop);
140 scene.AddNewSceneObject(sog, false); 140 scene.AddNewSceneObject(sog, false);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
new file mode 100644
index 0000000..da8199d
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs
@@ -0,0 +1,143 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using Timer=System.Timers.Timer;
35using Nini.Config;
36using NUnit.Framework;
37using NUnit.Framework.SyntaxHelpers;
38using OpenMetaverse;
39using OpenMetaverse.Assets;
40using OpenSim.Framework;
41using OpenSim.Framework.Communications;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
45using OpenSim.Region.CoreModules.World.Serialiser;
46using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
47using OpenSim.Services.Interfaces;
48using OpenSim.Tests.Common;
49using OpenSim.Tests.Common.Mock;
50using OpenSim.Tests.Common.Setup;
51
52namespace OpenSim.Region.Framework.Tests
53{
54 [TestFixture]
55 public class TaskInventoryTests
56 {
57 protected UserAccount CreateUser(Scene scene)
58 {
59 string userFirstName = "Jock";
60 string userLastName = "Stirrup";
61 string userPassword = "troll";
62 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
63 return UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword);
64 }
65
66 protected SceneObjectGroup CreateSO1(Scene scene, UUID ownerId)
67 {
68 string part1Name = "part1";
69 UUID part1Id = UUID.Parse("10000000-0000-0000-0000-000000000000");
70 SceneObjectPart part1
71 = new SceneObjectPart(ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
72 { Name = part1Name, UUID = part1Id };
73 return new SceneObjectGroup(part1);
74 }
75
76 protected TaskInventoryItem CreateSOItem1(Scene scene, SceneObjectPart part)
77 {
78 AssetNotecard nc = new AssetNotecard("Hello World!");
79 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
80 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
81 AssetBase ncAsset
82 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
83 scene.AssetService.Store(ncAsset);
84 TaskInventoryItem ncItem
85 = new TaskInventoryItem
86 { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid,
87 Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard };
88 part.Inventory.AddInventoryItem(ncItem, true);
89
90 return ncItem;
91 }
92
93 /// <summary>
94 /// Test MoveTaskInventoryItem where the item has no parent folder assigned.
95 /// </summary>
96 /// This should place it in the most suitable user folder.
97 [Test]
98 public void TestMoveTaskInventoryItem()
99 {
100 TestHelper.InMethod();
101// log4net.Config.XmlConfigurator.Configure();
102
103 Scene scene = SceneSetupHelpers.SetupScene("inventory");
104 UserAccount user1 = CreateUser(scene);
105 SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID);
106 SceneObjectPart sop1 = sog1.RootPart;
107 TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1);
108 InventoryFolderBase folder
109 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0];
110
111 // Perform test
112 scene.MoveTaskInventoryItem(user1.PrincipalID, folder.ID, sop1, sopItem1.ItemID);
113
114 InventoryItemBase ncUserItem
115 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Objects/ncItem");
116 Assert.That(ncUserItem, Is.Not.Null, "Objects/ncItem was not found");
117 }
118
119 /// <summary>
120 /// Test MoveTaskInventoryItem where the item has no parent folder assigned.
121 /// </summary>
122 /// This should place it in the most suitable user folder.
123 [Test]
124 public void TestMoveTaskInventoryItemNoParent()
125 {
126 TestHelper.InMethod();
127// log4net.Config.XmlConfigurator.Configure();
128
129 Scene scene = SceneSetupHelpers.SetupScene("inventory");
130 UserAccount user1 = CreateUser(scene);
131 SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID);
132 SceneObjectPart sop1 = sog1.RootPart;
133 TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1);
134
135 // Perform test
136 scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID);
137
138 InventoryItemBase ncUserItem
139 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Notecards/ncItem");
140 Assert.That(ncUserItem, Is.Not.Null, "Notecards/ncItem was not found");
141 }
142 }
143} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
index 56656fc..de1e01c 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
@@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
121 continue; 121 continue;
122 temp = (SceneObjectGroup) currObj; 122 temp = (SceneObjectGroup) currObj;
123 123
124 if (m_CMEntityHash.ContainsKey(temp.UUID)) 124 lock (temp.Children)
125 { 125 {
126 foreach (SceneObjectPart part in temp.Children.Values) 126 if (m_CMEntityHash.ContainsKey(temp.UUID))
127 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) 127 {
128 foreach (SceneObjectPart part in temp.Children.Values)
129 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
130 missingList.Add(part);
131 }
132 else //Entire group is missing from revision. (and is a new part in region)
133 {
134 foreach (SceneObjectPart part in temp.Children.Values)
128 missingList.Add(part); 135 missingList.Add(part);
129 } 136 }
130 else //Entire group is missing from revision. (and is a new part in region)
131 {
132 foreach (SceneObjectPart part in temp.Children.Values)
133 missingList.Add(part);
134 } 137 }
135 } 138 }
136 return missingList; 139 return missingList;
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
index 0dc78c0..e5fcb54 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) 167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
168 { 168 {
169 // Deal with new parts not revisioned that have been deleted. 169 // Deal with new parts not revisioned that have been deleted.
170 foreach (SceneObjectPart part in group.Children.Values) 170 lock (group.Children)
171 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) 171 {
172 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); 172 foreach (SceneObjectPart part in group.Children.Values)
173 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
174 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
175 }
173 } 176 }
174 177
175 /// <summary> 178 /// <summary>
@@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
207 { 210 {
208 temp = SceneObjectSerializer.FromXml2Format(xml); 211 temp = SceneObjectSerializer.FromXml2Format(xml);
209 temp.SetScene(scene); 212 temp.SetScene(scene);
210 foreach (SceneObjectPart part in temp.Children.Values) 213
211 part.RegionHandle = scene.RegionInfo.RegionHandle; 214 lock (temp.Children)
215 {
216 foreach (SceneObjectPart part in temp.Children.Values)
217 part.RegionHandle = scene.RegionInfo.RegionHandle;
218 }
219
212 ReplacementList.Add(temp.UUID, (EntityBase)temp); 220 ReplacementList.Add(temp.UUID, (EntityBase)temp);
213 } 221 }
214 catch (Exception e) 222 catch (Exception e)
@@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
338 System.Collections.ArrayList auraList = new System.Collections.ArrayList(); 346 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
339 if (group == null) 347 if (group == null)
340 return null; 348 return null;
341 foreach (SceneObjectPart part in group.Children.Values) 349
350 lock (group.Children)
342 { 351 {
343 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) 352 foreach (SceneObjectPart part in group.Children.Values)
344 { 353 {
345 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); 354 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
346 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); 355 {
347 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); 356 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
357 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
358 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
359 }
348 } 360 }
349 } 361 }
362
350 return auraList; 363 return auraList;
351 } 364 }
352 365
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
index 46fbd39..f75f40a 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
@@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); 186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
187 187
188 // Deal with new parts not revisioned that have been deleted. 188 // Deal with new parts not revisioned that have been deleted.
189 foreach (SceneObjectPart part in group.Children.Values) 189 lock (group.Children)
190 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) 190 {
191 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); 191 foreach (SceneObjectPart part in group.Children.Values)
192 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
193 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
194 }
192 } 195 }
193 196
194 public void SendMetaEntitiesToNewClient(IClientAPI client) 197 public void SendMetaEntitiesToNewClient(IClientAPI client)
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
index ada6701..2730eee 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
132 // if group is not contained in scene's list 132 // if group is not contained in scene's list
133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) 133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
134 { 134 {
135 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) 135 lock (m_UnchangedEntity.Children)
136 { 136 {
137 // if scene list no longer contains this part, display translucent part and mark with red aura 137 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
138 if (!ContainsKey(sceneEntityList, part.UUID))
139 { 138 {
140 // if already displaying a red aura over part, make sure its red 139 // if scene list no longer contains this part, display translucent part and mark with red aura
141 if (m_AuraEntities.ContainsKey(part.UUID)) 140 if (!ContainsKey(sceneEntityList, part.UUID))
142 {
143 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
144 }
145 else
146 { 141 {
147 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, 142 // if already displaying a red aura over part, make sure its red
148 part.GetWorldPosition(), 143 if (m_AuraEntities.ContainsKey(part.UUID))
149 MetaEntity.TRANSLUCENT, 144 {
150 new Vector3(254,0,0), 145 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
151 part.Scale 146 }
152 ); 147 else
153 m_AuraEntities.Add(part.UUID, auraGroup); 148 {
149 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
150 part.GetWorldPosition(),
151 MetaEntity.TRANSLUCENT,
152 new Vector3(254,0,0),
153 part.Scale
154 );
155 m_AuraEntities.Add(part.UUID, auraGroup);
156 }
157 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
158 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
154 } 159 }
155 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); 160 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
156 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
157 } 161 }
158 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
159 } 162 }
160 163
161 // a deleted part has no where to point a beam particle system, 164 // a deleted part has no where to point a beam particle system,
@@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
180 /// </summary> 183 /// </summary>
181 public bool HasChildPrim(UUID uuid) 184 public bool HasChildPrim(UUID uuid)
182 { 185 {
183 if (m_UnchangedEntity.Children.ContainsKey(uuid)) 186 lock (m_UnchangedEntity.Children)
184 return true; 187 if (m_UnchangedEntity.Children.ContainsKey(uuid))
188 return true;
189
185 return false; 190 return false;
186 } 191 }
187 192
@@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
190 /// </summary> 195 /// </summary>
191 public bool HasChildPrim(uint localID) 196 public bool HasChildPrim(uint localID)
192 { 197 {
193 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) 198 lock (m_UnchangedEntity.Children)
194 if (part.LocalId == localID) 199 {
195 return true; 200 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
201 if (part.LocalId == localID)
202 return true;
203 }
204
196 return false; 205 return false;
197 } 206 }
198 207
@@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
228 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user 237 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
229 // had originally saved. 238 // had originally saved.
230 // m_Entity will NOT necessarily be the same entity as the user had saved. 239 // m_Entity will NOT necessarily be the same entity as the user had saved.
231 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) 240 lock (m_UnchangedEntity.Children)
232 { 241 {
233 //This is the part that we use to show changes. 242 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
234 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
235 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
236 { 243 {
237 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; 244 //This is the part that we use to show changes.
238 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); 245 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
239 if (differences != Diff.NONE) 246 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
240 metaEntityPart.Text = "CHANGE: " + differences.ToString();
241 if (differences != 0)
242 { 247 {
243 // Root Part that has been modified 248 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
244 if ((differences&Diff.POSITION) > 0) 249 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
250 if (differences != Diff.NONE)
251 metaEntityPart.Text = "CHANGE: " + differences.ToString();
252 if (differences != 0)
253 {
254 // Root Part that has been modified
255 if ((differences&Diff.POSITION) > 0)
256 {
257 // If the position of any part has changed, make sure the RootPart of the
258 // meta entity is pointing with a beam particle system
259 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
260 {
261 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
262 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
263 }
264 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
265 m_UnchangedEntity.RootPart.GetWorldPosition(),
266 MetaEntity.TRANSLUCENT,
267 sceneEntityPart,
268 new Vector3(0,0,254)
269 );
270 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
271 }
272
273 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
274 {
275 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
276 m_AuraEntities.Remove(UnchangedPart.UUID);
277 }
278 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
279 UnchangedPart.GetWorldPosition(),
280 MetaEntity.TRANSLUCENT,
281 new Vector3(0,0,254),
282 UnchangedPart.Scale
283 );
284 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
285 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
286
287 DiffersFromSceneGroup = true;
288 }
289 else // no differences between scene part and meta part
245 { 290 {
246 // If the position of any part has changed, make sure the RootPart of the
247 // meta entity is pointing with a beam particle system
248 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) 291 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
249 { 292 {
250 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); 293 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
251 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); 294 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
252 } 295 }
253 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, 296 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
254 m_UnchangedEntity.RootPart.GetWorldPosition(), 297 {
255 MetaEntity.TRANSLUCENT, 298 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
256 sceneEntityPart, 299 m_AuraEntities.Remove(UnchangedPart.UUID);
257 new Vector3(0,0,254) 300 }
258 ); 301 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
259 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
260 } 302 }
261 303 }
304 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
305 {
262 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) 306 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
263 { 307 {
264 m_AuraEntities[UnchangedPart.UUID].HideFromAll(); 308 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
@@ -267,48 +311,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
267 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, 311 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
268 UnchangedPart.GetWorldPosition(), 312 UnchangedPart.GetWorldPosition(),
269 MetaEntity.TRANSLUCENT, 313 MetaEntity.TRANSLUCENT,
270 new Vector3(0,0,254), 314 new Vector3(254,0,0),
271 UnchangedPart.Scale 315 UnchangedPart.Scale
272 ); 316 );
273 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); 317 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
274 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); 318 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
275 319
276 DiffersFromSceneGroup = true; 320 DiffersFromSceneGroup = true;
277 } 321 }
278 else // no differences between scene part and meta part
279 {
280 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
281 {
282 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
283 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
284 }
285 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
286 {
287 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
288 m_AuraEntities.Remove(UnchangedPart.UUID);
289 }
290 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
291 }
292 }
293 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
294 {
295 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
296 {
297 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
298 m_AuraEntities.Remove(UnchangedPart.UUID);
299 }
300 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
301 UnchangedPart.GetWorldPosition(),
302 MetaEntity.TRANSLUCENT,
303 new Vector3(254,0,0),
304 UnchangedPart.Scale
305 );
306 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
307 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
308
309 DiffersFromSceneGroup = true;
310 } 322 }
311 } 323 }
324
312 return changed; 325 return changed;
313 } 326 }
314 327
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
index 841ee00..796f437 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
@@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
150 { 150 {
151 //make new uuids 151 //make new uuids
152 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); 152 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
153 foreach (SceneObjectPart part in m_Entity.Children.Values) 153
154 lock (m_Entity.Children)
154 { 155 {
155 part.ResetIDs(part.LinkNum); 156 foreach (SceneObjectPart part in m_Entity.Children.Values)
156 parts.Add(part.UUID, part); 157 {
158 part.ResetIDs(part.LinkNum);
159 parts.Add(part.UUID, part);
160 }
161
162 //finalize
163 m_Entity.RootPart.PhysActor = null;
164 m_Entity.Children = parts;
157 } 165 }
158
159 //finalize
160 m_Entity.RootPart.PhysActor = null;
161 m_Entity.Children = parts;
162 } 166 }
163 167
164 #endregion Protected Methods 168 #endregion Protected Methods
@@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
173 //This deletes the group without removing from any databases. 177 //This deletes the group without removing from any databases.
174 //This is important because we are not IN any database. 178 //This is important because we are not IN any database.
175 //m_Entity.FakeDeleteGroup(); 179 //m_Entity.FakeDeleteGroup();
176 foreach (SceneObjectPart part in m_Entity.Children.Values) 180 lock (m_Entity.Children)
177 client.SendKillObject(m_Entity.RegionHandle, part.LocalId); 181 {
182 foreach (SceneObjectPart part in m_Entity.Children.Values)
183 client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
184 }
178 } 185 }
179 186
180 /// <summary> 187 /// <summary>
@@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
182 /// </summary> 189 /// </summary>
183 public virtual void HideFromAll() 190 public virtual void HideFromAll()
184 { 191 {
185 foreach (SceneObjectPart part in m_Entity.Children.Values) 192 lock (m_Entity.Children)
186 { 193 {
187 m_Entity.Scene.ForEachClient( 194 foreach (SceneObjectPart part in m_Entity.Children.Values)
188 delegate(IClientAPI controller) 195 {
189 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } 196 m_Entity.Scene.ForEachClient(
190 ); 197 delegate(IClientAPI controller)
198 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
199 );
200 }
191 } 201 }
192 } 202 }
193 203
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
index 96cccb7..c439e3e 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs
@@ -185,14 +185,21 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
185 get 185 get
186 { 186 {
187 SceneObjectPart my = GetSOP(); 187 SceneObjectPart my = GetSOP();
188 int total = my.ParentGroup.Children.Count; 188 IObject[] rets = null;
189 189
190 IObject[] rets = new IObject[total]; 190 int total = my.ParentGroup.PrimCount;
191
192 rets = new IObject[total];
191 193
192 int i = 0; 194 int i = 0;
193 foreach (KeyValuePair<UUID, SceneObjectPart> pair in my.ParentGroup.Children) 195
196 List<SceneObjectPart> partList = null;
197 lock (my.ParentGroup.Children)
198 partList = new List<SceneObjectPart>(my.ParentGroup.Children.Values);
199
200 foreach (SceneObjectPart part in partList)
194 { 201 {
195 rets[i++] = new SOPObject(m_rootScene, pair.Value.LocalId, m_security); 202 rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security);
196 } 203 }
197 204
198 return rets; 205 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 94b9d40..512957d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -293,7 +293,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
293 { 293 {
294 case ScriptBaseClass.LINK_SET: 294 case ScriptBaseClass.LINK_SET:
295 if (m_host.ParentGroup != null) 295 if (m_host.ParentGroup != null)
296 return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); 296 {
297 lock (m_host.ParentGroup.Children)
298 return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
299 }
297 return ret; 300 return ret;
298 301
299 case ScriptBaseClass.LINK_ROOT: 302 case ScriptBaseClass.LINK_ROOT:
@@ -308,7 +311,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
308 case ScriptBaseClass.LINK_ALL_OTHERS: 311 case ScriptBaseClass.LINK_ALL_OTHERS:
309 if (m_host.ParentGroup == null) 312 if (m_host.ParentGroup == null)
310 return new List<SceneObjectPart>(); 313 return new List<SceneObjectPart>();
311 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); 314
315 lock (m_host.ParentGroup.Children)
316 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
317
312 if (ret.Contains(m_host)) 318 if (ret.Contains(m_host))
313 ret.Remove(m_host); 319 ret.Remove(m_host);
314 return ret; 320 return ret;
@@ -316,7 +322,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 case ScriptBaseClass.LINK_ALL_CHILDREN: 322 case ScriptBaseClass.LINK_ALL_CHILDREN:
317 if (m_host.ParentGroup == null) 323 if (m_host.ParentGroup == null)
318 return new List<SceneObjectPart>(); 324 return new List<SceneObjectPart>();
319 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values); 325
326 lock (m_host.ParentGroup.Children)
327 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
328
320 if (ret.Contains(m_host.ParentGroup.RootPart)) 329 if (ret.Contains(m_host.ParentGroup.RootPart))
321 ret.Remove(m_host.ParentGroup.RootPart); 330 ret.Remove(m_host.ParentGroup.RootPart);
322 return ret; 331 return ret;
@@ -1272,12 +1281,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1272 if (group == null) 1281 if (group == null)
1273 return; 1282 return;
1274 bool allow = true; 1283 bool allow = true;
1275 foreach (SceneObjectPart part in group.Children.Values) 1284
1285 lock (group.Children)
1276 { 1286 {
1277 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1287 foreach (SceneObjectPart part in group.Children.Values)
1278 { 1288 {
1279 allow = false; 1289 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
1280 break; 1290 {
1291 allow = false;
1292 break;
1293 }
1281 } 1294 }
1282 } 1295 }
1283 1296
@@ -2120,7 +2133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2120 2133
2121 if (part.ParentGroup.RootPart == part) 2134 if (part.ParentGroup.RootPart == part)
2122 { 2135 {
2123 if ((targetPos.z < ground) && disable_underground_movement) 2136 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
2124 targetPos.z = ground; 2137 targetPos.z = ground;
2125 SceneObjectGroup parent = part.ParentGroup; 2138 SceneObjectGroup parent = part.ParentGroup;
2126 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2139 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
@@ -2152,18 +2165,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2152 protected LSL_Vector GetPartLocalPos(SceneObjectPart part) 2165 protected LSL_Vector GetPartLocalPos(SceneObjectPart part)
2153 { 2166 {
2154 m_host.AddScriptLPS(1); 2167 m_host.AddScriptLPS(1);
2155 if (part.ParentID != 0) 2168 if (part.ParentID == 0)
2156 {
2157 return new LSL_Vector(part.OffsetPosition.X,
2158 part.OffsetPosition.Y,
2159 part.OffsetPosition.Z);
2160 }
2161 else
2162 { 2169 {
2163 return new LSL_Vector(part.AbsolutePosition.X, 2170 return new LSL_Vector(part.AbsolutePosition.X,
2164 part.AbsolutePosition.Y, 2171 part.AbsolutePosition.Y,
2165 part.AbsolutePosition.Z); 2172 part.AbsolutePosition.Z);
2166 } 2173 }
2174 else
2175 {
2176 if (m_host.IsRoot)
2177 {
2178 return new LSL_Vector(m_host.AttachedPos.X,
2179 m_host.AttachedPos.Y,
2180 m_host.AttachedPos.Z);
2181 }
2182 else
2183 {
2184 return new LSL_Vector(part.OffsetPosition.X,
2185 part.OffsetPosition.Y,
2186 part.OffsetPosition.Z);
2187 }
2188 }
2167 } 2189 }
2168 2190
2169 public void llSetRot(LSL_Rotation rot) 2191 public void llSetRot(LSL_Rotation rot)
@@ -3748,7 +3770,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 { 3770 {
3749 m_host.AddScriptLPS(1); 3771 m_host.AddScriptLPS(1);
3750 3772
3751 if (m_host.ParentGroup.Children.Count > 1) 3773 if (m_host.ParentGroup.PrimCount > 1)
3752 { 3774 {
3753 return m_host.LinkNum; 3775 return m_host.LinkNum;
3754 } 3776 }
@@ -3869,15 +3891,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3869 case ScriptBaseClass.LINK_ALL_OTHERS: 3891 case ScriptBaseClass.LINK_ALL_OTHERS:
3870 case ScriptBaseClass.LINK_ALL_CHILDREN: 3892 case ScriptBaseClass.LINK_ALL_CHILDREN:
3871 case ScriptBaseClass.LINK_THIS: 3893 case ScriptBaseClass.LINK_THIS:
3872 foreach (SceneObjectPart part in parentPrim.Children.Values) 3894 lock (parentPrim.Children)
3873 { 3895 {
3874 if (part.UUID != m_host.UUID) 3896 foreach (SceneObjectPart part in parentPrim.Children.Values)
3875 { 3897 {
3876 childPrim = part; 3898 if (part.UUID != m_host.UUID)
3877 break; 3899 {
3900 childPrim = part;
3901 break;
3902 }
3878 } 3903 }
3904 break;
3879 } 3905 }
3880 break;
3881 default: 3906 default:
3882 childPrim = parentPrim.GetLinkNumPart(linknum); 3907 childPrim = parentPrim.GetLinkNumPart(linknum);
3883 if (childPrim.UUID == m_host.UUID) 3908 if (childPrim.UUID == m_host.UUID)
@@ -3953,26 +3978,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3953 if (parentPrim.RootPart.AttachmentPoint != 0) 3978 if (parentPrim.RootPart.AttachmentPoint != 0)
3954 return; // Fail silently if attached 3979 return; // Fail silently if attached
3955 3980
3956 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3981 lock (parentPrim.Children)
3957 parts.Remove(parentPrim.RootPart);
3958 if (parts.Count > 0)
3959 { 3982 {
3960 try 3983 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3961 { 3984 parts.Remove(parentPrim.RootPart);
3962 parts[0].ParentGroup.areUpdatesSuspended = true; 3985
3963 foreach (SceneObjectPart part in parts) 3986 foreach (SceneObjectPart part in parts)
3964 {
3965 parentPrim.DelinkFromGroup(part.LocalId, true);
3966 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3967 }
3968 }
3969 finally
3970 { 3987 {
3971 parts[0].ParentGroup.areUpdatesSuspended = false; 3988 parentPrim.DelinkFromGroup(part.LocalId, true);
3989 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3972 } 3990 }
3991 parentPrim.HasGroupChanged = true;
3992 parentPrim.ScheduleGroupForFullUpdate();
3973 } 3993 }
3974 parentPrim.HasGroupChanged = true;
3975 parentPrim.ScheduleGroupForFullUpdate();
3976 } 3994 }
3977 3995
3978 public LSL_String llGetLinkKey(int linknum) 3996 public LSL_String llGetLinkKey(int linknum)
@@ -4179,8 +4197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4179 } 4197 }
4180 4198
4181 // destination is an avatar 4199 // destination is an avatar
4182 InventoryItemBase agentItem = 4200 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4183 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4184 4201
4185 if (agentItem == null) 4202 if (agentItem == null)
4186 return; 4203 return;
@@ -4190,7 +4207,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4190 byte[] objBytes = agentItem.ID.GetBytes(); 4207 byte[] objBytes = agentItem.ID.GetBytes();
4191 Array.Copy(objBytes, 0, bucket, 1, 16); 4208 Array.Copy(objBytes, 0, bucket, 1, 16);
4192 4209
4193 Console.WriteLine("Giving inventory");
4194 GridInstantMessage msg = new GridInstantMessage(World, 4210 GridInstantMessage msg = new GridInstantMessage(World,
4195 m_host.UUID, m_host.Name+", an object owned by "+ 4211 m_host.UUID, m_host.Name+", an object owned by "+
4196 resolveName(m_host.OwnerID)+",", destId, 4212 resolveName(m_host.OwnerID)+",", destId,
@@ -4538,7 +4554,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4538 { 4554 {
4539 partItemID = item.ItemID; 4555 partItemID = item.ItemID;
4540 int linkNumber = m_host.LinkNum; 4556 int linkNumber = m_host.LinkNum;
4541 if (m_host.ParentGroup.Children.Count == 1) 4557 if (m_host.ParentGroup.PrimCount == 1)
4542 linkNumber = 0; 4558 linkNumber = 0;
4543 4559
4544 object[] resobj = new object[] 4560 object[] resobj = new object[]
@@ -9595,8 +9611,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9595 // we send to all 9611 // we send to all
9596 landData.MediaID = new UUID(texture); 9612 landData.MediaID = new UUID(texture);
9597 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; 9613 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0;
9598 landData.MediaSize[0] = width; 9614 landData.MediaWidth = width;
9599 landData.MediaSize[1] = height; 9615 landData.MediaHeight = height;
9600 landData.MediaType = mediaType; 9616 landData.MediaType = mediaType;
9601 9617
9602 // do that one last, it will cause a ParcelPropertiesUpdate 9618 // do that one last, it will cause a ParcelPropertiesUpdate
@@ -9682,8 +9698,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 9698 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType));
9683 break; 9699 break;
9684 case ParcelMediaCommandEnum.Size: 9700 case ParcelMediaCommandEnum.Size:
9685 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[0])); 9701 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth));
9686 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[1])); 9702 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight));
9687 break; 9703 break;
9688 default: 9704 default:
9689 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 9705 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index f0384f8..665b39f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -1,507 +1,502 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse; 33using OpenMetaverse;
34using Nini.Config; 34using Nini.Config;
35using OpenSim; 35using OpenSim;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare; 37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared; 40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces; 43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45 45
46using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 46using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
47using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 47using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
48using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 48using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
50using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 50using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
51using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 51using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
52using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 52using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
53 53
54namespace OpenSim.Region.ScriptEngine.Shared.Api 54namespace OpenSim.Region.ScriptEngine.Shared.Api
55{ 55{
56 [Serializable] 56 [Serializable]
57 public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi 57 public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi
58 { 58 {
59 internal IScriptEngine m_ScriptEngine; 59 internal IScriptEngine m_ScriptEngine;
60 internal SceneObjectPart m_host; 60 internal SceneObjectPart m_host;
61 internal uint m_localID; 61 internal uint m_localID;
62 internal UUID m_itemID; 62 internal UUID m_itemID;
63 internal bool m_LSFunctionsEnabled = false; 63 internal bool m_LSFunctionsEnabled = false;
64 internal IScriptModuleComms m_comms = null; 64 internal IScriptModuleComms m_comms = null;
65 65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 { 67 {
68 m_ScriptEngine = ScriptEngine; 68 m_ScriptEngine = ScriptEngine;
69 m_host = host; 69 m_host = host;
70 m_localID = localID; 70 m_localID = localID;
71 m_itemID = itemID; 71 m_itemID = itemID;
72 72
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 74 m_LSFunctionsEnabled = true;
75 75
76 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) 76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
77 m_LSFunctionsEnabled = true; 77 if (m_comms == null)
78 78 m_LSFunctionsEnabled = false;
79 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); 79 }
80 if (m_comms == null) 80
81 m_LSFunctionsEnabled = false; 81 public override Object InitializeLifetimeService()
82 } 82 {
83 83 ILease lease = (ILease)base.InitializeLifetimeService();
84 public override Object InitializeLifetimeService() 84
85 { 85 if (lease.CurrentState == LeaseState.Initial)
86 ILease lease = (ILease)base.InitializeLifetimeService(); 86 {
87 87 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
88 if (lease.CurrentState == LeaseState.Initial) 88 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
89 { 89 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
90 lease.InitialLeaseTime = TimeSpan.FromMinutes(0); 90 }
91 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); 91 return lease;
92 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); 92 }
93 } 93
94 return lease; 94 public Scene World
95 } 95 {
96 96 get { return m_ScriptEngine.World; }
97 public Scene World 97 }
98 { 98
99 get { return m_ScriptEngine.World; } 99 //
100 } 100 //Dumps an error message on the debug console.
101 101 //
102 // 102
103 //Dumps an error message on the debug console. 103 internal void LSShoutError(string message)
104 // 104 {
105 105 if (message.Length > 1023)
106 internal void LSShoutError(string message) 106 message = message.Substring(0, 1023);
107 { 107
108 if (message.Length > 1023) 108 World.SimChat(Utils.StringToBytes(message),
109 message = message.Substring(0, 1023); 109 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
110 110
111 World.SimChat(Utils.StringToBytes(message), 111 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
112 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); 112 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
113 113 }
114 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 114
115 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 115 /// <summary>
116 } 116 /// Get the current Windlight scene
117 117 /// </summary>
118 /// <summary> 118 /// <returns>List of windlight parameters</returns>
119 /// Get the current Windlight scene 119 public LSL_List lsGetWindlightScene(LSL_List rules)
120 /// </summary> 120 {
121 /// <returns>List of windlight parameters</returns> 121 if (!m_LSFunctionsEnabled)
122 public LSL_List lsGetWindlightScene(LSL_List rules) 122 {
123 { 123 LSShoutError("LightShare functions are not enabled.");
124 if (!m_LSFunctionsEnabled) 124 return new LSL_List();
125 { 125 }
126 LSShoutError("LightShare functions are not enabled."); 126 m_host.AddScriptLPS(1);
127 return new LSL_List(); 127 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
128 } 128
129 m_host.AddScriptLPS(1); 129 LSL_List values = new LSL_List();
130 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; 130 int idx = 0;
131 131 while (idx < rules.Length)
132 LSL_List values = new LSL_List(); 132 {
133 int idx = 0; 133 uint rule = (uint)rules.GetLSLIntegerItem(idx);
134 while (idx < rules.Length) 134 LSL_List toadd = new LSL_List();
135 { 135
136 uint rule = (uint)rules.GetLSLIntegerItem(idx); 136 switch (rule)
137 LSL_List toadd = new LSL_List(); 137 {
138 138 case (int)ScriptBaseClass.WL_AMBIENT:
139 switch (rule) 139 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
140 { 140 break;
141 case (int)ScriptBaseClass.WL_AMBIENT: 141 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
142 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); 142 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
143 break; 143 break;
144 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: 144 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
145 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); 145 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
146 break; 146 break;
147 case (int)ScriptBaseClass.WL_BLUE_DENSITY: 147 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
148 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); 148 toadd.Add(new LSL_Float(wl.blurMultiplier));
149 break; 149 break;
150 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: 150 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
151 toadd.Add(new LSL_Float(wl.blurMultiplier)); 151 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
152 break; 152 break;
153 case (int)ScriptBaseClass.WL_CLOUD_COLOR: 153 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
154 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); 154 toadd.Add(new LSL_Float(wl.cloudCoverage));
155 break; 155 break;
156 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: 156 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
157 toadd.Add(new LSL_Float(wl.cloudCoverage)); 157 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
158 break; 158 break;
159 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 159 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
160 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); 160 toadd.Add(new LSL_Float(wl.cloudScale));
161 break; 161 break;
162 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 162 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
163 toadd.Add(new LSL_Float(wl.cloudScale)); 163 toadd.Add(new LSL_Float(wl.cloudScrollX));
164 break; 164 break;
165 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: 165 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
166 toadd.Add(new LSL_Float(wl.cloudScrollX)); 166 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
167 break; 167 break;
168 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: 168 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
169 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); 169 toadd.Add(new LSL_Float(wl.cloudScrollY));
170 break; 170 break;
171 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: 171 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
172 toadd.Add(new LSL_Float(wl.cloudScrollY)); 172 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
173 break; 173 break;
174 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: 174 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
175 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); 175 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
176 break; 176 break;
177 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 177 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
178 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); 178 toadd.Add(new LSL_Float(wl.densityMultiplier));
179 break; 179 break;
180 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 180 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
181 toadd.Add(new LSL_Float(wl.densityMultiplier)); 181 toadd.Add(new LSL_Float(wl.distanceMultiplier));
182 break; 182 break;
183 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: 183 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
184 toadd.Add(new LSL_Float(wl.distanceMultiplier)); 184 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
185 break; 185 break;
186 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: 186 case (int)ScriptBaseClass.WL_EAST_ANGLE:
187 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); 187 toadd.Add(new LSL_Float(wl.eastAngle));
188 break; 188 break;
189 case (int)ScriptBaseClass.WL_EAST_ANGLE: 189 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
190 toadd.Add(new LSL_Float(wl.eastAngle)); 190 toadd.Add(new LSL_Float(wl.fresnelOffset));
191 break; 191 break;
192 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: 192 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
193 toadd.Add(new LSL_Float(wl.fresnelOffset)); 193 toadd.Add(new LSL_Float(wl.fresnelScale));
194 break; 194 break;
195 case (int)ScriptBaseClass.WL_FRESNEL_SCALE: 195 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
196 toadd.Add(new LSL_Float(wl.fresnelScale)); 196 toadd.Add(new LSL_Float(wl.hazeDensity));
197 break; 197 break;
198 case (int)ScriptBaseClass.WL_HAZE_DENSITY: 198 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
199 toadd.Add(new LSL_Float(wl.hazeDensity)); 199 toadd.Add(new LSL_Float(wl.hazeHorizon));
200 break; 200 break;
201 case (int)ScriptBaseClass.WL_HAZE_HORIZON: 201 case (int)ScriptBaseClass.WL_HORIZON:
202 toadd.Add(new LSL_Float(wl.hazeHorizon)); 202 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
203 break; 203 break;
204 case (int)ScriptBaseClass.WL_HORIZON: 204 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
205 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); 205 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
206 break; 206 break;
207 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: 207 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
208 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); 208 toadd.Add(new LSL_Integer(wl.maxAltitude));
209 break; 209 break;
210 case (int)ScriptBaseClass.WL_MAX_ALTITUDE: 210 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
211 toadd.Add(new LSL_Integer(wl.maxAltitude)); 211 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
212 break; 212 break;
213 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: 213 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
214 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); 214 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
215 break; 215 break;
216 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 216 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
217 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); 217 toadd.Add(new LSL_Float(wl.refractScaleAbove));
218 break; 218 break;
219 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 219 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
220 toadd.Add(new LSL_Float(wl.refractScaleAbove)); 220 toadd.Add(new LSL_Float(wl.refractScaleBelow));
221 break; 221 break;
222 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: 222 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
223 toadd.Add(new LSL_Float(wl.refractScaleBelow)); 223 toadd.Add(new LSL_Float(wl.sceneGamma));
224 break; 224 break;
225 case (int)ScriptBaseClass.WL_SCENE_GAMMA: 225 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
226 toadd.Add(new LSL_Float(wl.sceneGamma)); 226 toadd.Add(new LSL_Float(wl.starBrightness));
227 break; 227 break;
228 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: 228 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
229 toadd.Add(new LSL_Float(wl.starBrightness)); 229 toadd.Add(new LSL_Float(wl.sunGlowFocus));
230 break; 230 break;
231 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: 231 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
232 toadd.Add(new LSL_Float(wl.sunGlowFocus)); 232 toadd.Add(new LSL_Float(wl.sunGlowSize));
233 break; 233 break;
234 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: 234 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
235 toadd.Add(new LSL_Float(wl.sunGlowSize)); 235 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
236 break; 236 break;
237 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 237 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
238 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); 238 toadd.Add(new LSL_Float(wl.underwaterFogModifier));
239 break; 239 break;
240 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: 240 case (int)ScriptBaseClass.WL_WATER_COLOR:
241 toadd.Add(new LSL_Float(wl.underwaterFogModifier)); 241 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
242 break; 242 break;
243 case (int)ScriptBaseClass.WL_WATER_COLOR: 243 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
244 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); 244 toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
245 break; 245 break;
246 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 246 }
247 toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); 247
248 break; 248 if (toadd.Length > 0)
249 } 249 {
250 250 values.Add(rule);
251 if (toadd.Length > 0) 251 values.Add(toadd.Data[0]);
252 { 252 }
253 values.Add(new LSL_Integer(rule)); 253 idx++;
254 values.Add(toadd.Data[0]); 254 }
255 } 255
256 idx++; 256 return values;
257 } 257 }
258 258
259 259 private RegionLightShareData getWindlightProfileFromRules(LSL_List rules)
260 return values; 260 {
261 261 RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
262 } 262
263 263// LSL_List values = new LSL_List();
264 private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) 264 int idx = 0;
265 { 265 while (idx < rules.Length)
266 RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); 266 {
267 267 uint rule = (uint)rules.GetLSLIntegerItem(idx);
268 LSL_List values = new LSL_List(); 268 LSL_Types.Quaternion iQ;
269 int idx = 0; 269 LSL_Types.Vector3 iV;
270 while (idx < rules.Length) 270 switch (rule)
271 { 271 {
272 uint rule = (uint)rules.GetLSLIntegerItem(idx); 272 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION:
273 LSL_Types.Quaternion iQ; 273 idx++;
274 LSL_Types.Vector3 iV; 274 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx);
275 switch (rule) 275 break;
276 { 276 case (int)ScriptBaseClass.WL_AMBIENT:
277 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: 277 idx++;
278 idx++; 278 iQ = rules.GetQuaternionItem(idx);
279 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); 279 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
280 break; 280 break;
281 case (int)ScriptBaseClass.WL_AMBIENT: 281 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
282 idx++; 282 idx++;
283 iQ = rules.GetQuaternionItem(idx); 283 iV = rules.GetVector3Item(idx);
284 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 284 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
285 break; 285 break;
286 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: 286 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
287 idx++; 287 idx++;
288 iV = rules.GetVector3Item(idx); 288 iQ = rules.GetQuaternionItem(idx);
289 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); 289 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
290 break; 290 break;
291 case (int)ScriptBaseClass.WL_BLUE_DENSITY: 291 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
292 idx++; 292 idx++;
293 iQ = rules.GetQuaternionItem(idx); 293 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
294 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 294 break;
295 break; 295 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
296 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: 296 idx++;
297 idx++; 297 iQ = rules.GetQuaternionItem(idx);
298 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); 298 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
299 break; 299 break;
300 case (int)ScriptBaseClass.WL_CLOUD_COLOR: 300 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
301 idx++; 301 idx++;
302 iQ = rules.GetQuaternionItem(idx); 302 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
303 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 303 break;
304 break; 304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
305 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: 305 idx++;
306 idx++; 306 iV = rules.GetVector3Item(idx);
307 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); 307 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
308 break; 308 break;
309 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 309 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
310 idx++; 310 idx++;
311 iV = rules.GetVector3Item(idx); 311 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
312 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 312 break;
313 break; 313 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
314 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 314 idx++;
315 idx++; 315 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
316 wl.cloudScale = (float)rules.GetLSLFloatItem(idx); 316 break;
317 break; 317 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
318 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: 318 idx++;
319 idx++; 319 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
320 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); 320 break;
321 break; 321 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
322 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: 322 idx++;
323 idx++; 323 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
324 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 324 break;
325 break; 325 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
326 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: 326 idx++;
327 idx++; 327 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
328 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); 328 break;
329 break; 329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
330 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: 330 idx++;
331 idx++; 331 iV = rules.GetVector3Item(idx);
332 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 332 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
333 break; 333 break;
334 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
335 idx++; 335 idx++;
336 iV = rules.GetVector3Item(idx); 336 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
337 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 337 break;
338 break; 338 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
339 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 339 idx++;
340 idx++; 340 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
341 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); 341 break;
342 break; 342 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
343 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: 343 idx++;
344 idx++; 344 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
345 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); 345 break;
346 break; 346 case (int)ScriptBaseClass.WL_EAST_ANGLE:
347 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: 347 idx++;
348 idx++; 348 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
349 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 349 break;
350 break; 350 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
351 case (int)ScriptBaseClass.WL_EAST_ANGLE: 351 idx++;
352 idx++; 352 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
353 wl.eastAngle = (float)rules.GetLSLFloatItem(idx); 353 break;
354 break; 354 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
355 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: 355 idx++;
356 idx++; 356 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
357 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); 357 break;
358 break; 358 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
359 case (int)ScriptBaseClass.WL_FRESNEL_SCALE: 359 idx++;
360 idx++; 360 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
361 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); 361 break;
362 break; 362 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
363 case (int)ScriptBaseClass.WL_HAZE_DENSITY: 363 idx++;
364 idx++; 364 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
365 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); 365 break;
366 break; 366 case (int)ScriptBaseClass.WL_HORIZON:
367 case (int)ScriptBaseClass.WL_HAZE_HORIZON: 367 idx++;
368 idx++; 368 iQ = rules.GetQuaternionItem(idx);
369 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); 369 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
370 break; 370 break;
371 case (int)ScriptBaseClass.WL_HORIZON: 371 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
372 idx++; 372 idx++;
373 iQ = rules.GetQuaternionItem(idx); 373 iV = rules.GetVector3Item(idx);
374 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 374 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
375 break; 375 break;
376 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: 376 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
377 idx++; 377 idx++;
378 iV = rules.GetVector3Item(idx); 378 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
379 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); 379 break;
380 break; 380 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
381 case (int)ScriptBaseClass.WL_MAX_ALTITUDE: 381 idx++;
382 idx++; 382 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
383 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; 383 break;
384 break; 384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
385 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: 385 idx++;
386 idx++; 386 iV = rules.GetVector3Item(idx);
387 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); 387 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
388 break; 388 break;
389 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
390 idx++; 390 idx++;
391 iV = rules.GetVector3Item(idx); 391 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
392 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 392 break;
393 break; 393 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
394 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 394 idx++;
395 idx++; 395 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
396 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); 396 break;
397 break; 397 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
398 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: 398 idx++;
399 idx++; 399 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
400 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); 400 break;
401 break; 401 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
402 case (int)ScriptBaseClass.WL_SCENE_GAMMA: 402 idx++;
403 idx++; 403 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
404 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); 404 break;
405 break; 405 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
406 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: 406 idx++;
407 idx++; 407 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
408 wl.starBrightness = (float)rules.GetLSLFloatItem(idx); 408 break;
409 break; 409 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
410 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: 410 idx++;
411 idx++; 411 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
412 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); 412 break;
413 break; 413 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
414 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: 414 idx++;
415 idx++; 415 iQ = rules.GetQuaternionItem(idx);
416 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); 416 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
417 break; 417 break;
418 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 418 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
419 idx++; 419 idx++;
420 iQ = rules.GetQuaternionItem(idx); 420 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
421 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 421 break;
422 break; 422 case (int)ScriptBaseClass.WL_WATER_COLOR:
423 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: 423 idx++;
424 idx++; 424 iV = rules.GetVector3Item(idx);
425 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); 425 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
426 break; 426 break;
427 case (int)ScriptBaseClass.WL_WATER_COLOR: 427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
428 idx++; 428 idx++;
429 iV = rules.GetVector3Item(idx); 429 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
430 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 430 break;
431 break; 431 }
432 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 432 idx++;
433 idx++; 433 }
434 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); 434 return wl;
435 break; 435 }
436 } 436 /// <summary>
437 idx++; 437 /// Set the current Windlight scene
438 } 438 /// </summary>
439 return wl; 439 /// <param name="rules"></param>
440 } 440 /// <returns>success: true or false</returns>
441 /// <summary> 441 public int lsSetWindlightScene(LSL_List rules)
442 /// Set the current Windlight scene 442 {
443 /// </summary> 443 if (!m_LSFunctionsEnabled)
444 /// <param name="rules"></param> 444 {
445 /// <returns>success: true or false</returns> 445 LSShoutError("LightShare functions are not enabled.");
446 public int lsSetWindlightScene(LSL_List rules) 446 return 0;
447 { 447 }
448 if (!m_LSFunctionsEnabled) 448 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
449 { 449 {
450 LSShoutError("LightShare functions are not enabled."); 450 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
451 return 0; 451 return 0;
452 } 452 }
453 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 453 int success = 0;
454 { 454 m_host.AddScriptLPS(1);
455 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 455 if (LightShareModule.EnableWindlight)
456 return 0; 456 {
457 } 457 RegionLightShareData wl = getWindlightProfileFromRules(rules);
458 int success = 0; 458 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
459 m_host.AddScriptLPS(1); 459 success = 1;
460 if (LightShareModule.EnableWindlight) 460 }
461 { 461 else
462 RegionLightShareData wl = getWindlightProfileFromRules(rules); 462 {
463 m_host.ParentGroup.Scene.StoreWindlightProfile(wl); 463 LSShoutError("Windlight module is disabled");
464 success = 1; 464 return 0;
465 } 465 }
466 else 466 return success;
467 { 467 }
468 LSShoutError("Windlight module is disabled"); 468 /// <summary>
469 return 0; 469 /// Set the current Windlight scene to a target avatar
470 } 470 /// </summary>
471 return success; 471 /// <param name="rules"></param>
472 } 472 /// <returns>success: true or false</returns>
473 /// <summary> 473 public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
474 /// Set the current Windlight scene to a target avatar 474 {
475 /// </summary> 475 if (!m_LSFunctionsEnabled)
476 /// <param name="rules"></param> 476 {
477 /// <returns>success: true or false</returns> 477 LSShoutError("LightShare functions are not enabled.");
478 public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) 478 return 0;
479 { 479 }
480 if (!m_LSFunctionsEnabled) 480 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
481 { 481 {
482 LSShoutError("LightShare functions are not enabled."); 482 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
483 return 0; 483 return 0;
484 } 484 }
485 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 485 int success = 0;
486 { 486 m_host.AddScriptLPS(1);
487 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 487 if (LightShareModule.EnableWindlight)
488 return 0; 488 {
489 } 489 RegionLightShareData wl = getWindlightProfileFromRules(rules);
490 int success = 0; 490 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
491 m_host.AddScriptLPS(1); 491 success = 1;
492 if (LightShareModule.EnableWindlight) 492 }
493 { 493 else
494 RegionLightShareData wl = getWindlightProfileFromRules(rules); 494 {
495 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); 495 LSShoutError("Windlight module is disabled");
496 success = 1; 496 return 0;
497 } 497 }
498 else 498 return success;
499 { 499 }
500 LSShoutError("Windlight module is disabled"); 500
501 return 0; 501 }
502 } 502}
503 return success;
504 }
505
506 }
507}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 4855d64..41501f2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -209,12 +209,15 @@ namespace OpenSim.Region.ScriptEngine.Shared
209 else 209 else
210 Type = 0x02; // Passive 210 Type = 0x02; // Passive
211 211
212 foreach (SceneObjectPart p in part.ParentGroup.Children.Values) 212 lock (part.ParentGroup.Children)
213 { 213 {
214 if (p.Inventory.ContainsScripts()) 214 foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
215 { 215 {
216 Type |= 0x08; // Scripted 216 if (p.Inventory.ContainsScripts())
217 break; 217 {
218 Type |= 0x08; // Scripted
219 break;
220 }
218 } 221 }
219 } 222 }
220 223
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0f274f3..e5e8a56 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1373,7 +1373,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1373 { 1373 {
1374 sdoc.LoadXml(xml); 1374 sdoc.LoadXml(xml);
1375 } 1375 }
1376 catch (System.Xml.XmlException e) 1376 catch (System.Xml.XmlException)
1377 { 1377 {
1378 loadedState = false; 1378 loadedState = false;
1379 } 1379 }