aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJonathan Freedman2010-12-05 11:49:15 -0800
committerJonathan Freedman2010-12-05 11:49:15 -0800
commit45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a (patch)
tree0351fb2c756a46d522fe41798c3969e020a3258d /OpenSim/Region
parentMerge branch 'master-core' into mantis5110 (diff)
parentMerge branch 'master' of /var/git/opensim/ (diff)
downloadopensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.zip
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.gz
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.bz2
opensim-SC_OLD-45cd2e3ef93cc8ab880cb5b1742e33d441e7d01a.tar.xz
Merge branch 'master-core' into mantis5110
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs6
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs4
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs32
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs15
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs22
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs130
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs166
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs43
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs125
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs13
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs28
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs64
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs16
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs83
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs263
-rw-r--r--OpenSim/Region/Examples/SimpleModule/RegionModule.cs11
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRestartModule.cs39
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs1
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs84
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs275
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs164
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs40
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs9
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs86
-rw-r--r--OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs91
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs17
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs24
45 files changed, 1456 insertions, 701 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 6127c2d..ae2d836 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -265,10 +265,10 @@ namespace OpenSim
265 LoadOar); 265 LoadOar);
266 266
267 m_console.Commands.AddCommand("region", false, "save oar", 267 m_console.Commands.AddCommand("region", false, "save oar",
268 "save oar [-v|--version=N] [-p|--profile=url] [<OAR path>]", 268 "save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
269 "Save a region's data to an OAR archive.", 269 "Save a region's data to an OAR archive.",
270 "-v|--version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 270 "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
271 + "-p|--profile=url adds the url of the profile service to the saved user information" + Environment.NewLine 271 + "-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine
272 + "The OAR path must be a filesystem path." 272 + "The OAR path must be a filesystem path."
273 + " If this is not given then the oar is saved to region.oar in the current directory.", 273 + " If this is not given then the oar is saved to region.oar in the current directory.",
274 SaveOar); 274 SaveOar);
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 904a50c..1652b82 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -352,13 +352,13 @@ namespace OpenSim
352 m_moduleLoader.InitialiseSharedModules(scene); 352 m_moduleLoader.InitialiseSharedModules(scene);
353 353
354 // Use this in the future, the line above will be deprecated soon 354 // Use this in the future, the line above will be deprecated soon
355 m_log.Info("[MODULES]: Loading Region's modules (new style)"); 355 m_log.Info("[REGIONMODULES]: Loading Region's modules (new style)");
356 IRegionModulesController controller; 356 IRegionModulesController controller;
357 if (ApplicationRegistry.TryGet(out controller)) 357 if (ApplicationRegistry.TryGet(out controller))
358 { 358 {
359 controller.AddRegionToModules(scene); 359 controller.AddRegionToModules(scene);
360 } 360 }
361 else m_log.Error("[MODULES]: The new RegionModulesController is missing..."); 361 else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing...");
362 362
363 scene.SetModuleInterfaces(); 363 scene.SetModuleInterfaces();
364 364
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 7851c4d..f125822 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3562,24 +3562,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3562 EntityUpdate update; 3562 EntityUpdate update;
3563 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) 3563 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3564 { 3564 {
3565 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3566 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3567 // safety measure.
3568 //
3569 // Receiving updates after kills results in undeleteable prims that persist until relog and
3570 // currently occurs because prims can be deleted before all queued updates are sent.
3571 if (m_killRecord.Contains(update.Entity.LocalId))
3572 {
3573// m_log.WarnFormat(
3574// "[CLIENT]: Preventing full update for prim with local id {0} after client for user {1} told it was deleted",
3575// update.Entity.LocalId, Name);
3576 continue;
3577 }
3578
3579 if (update.Entity is SceneObjectPart) 3565 if (update.Entity is SceneObjectPart)
3580 { 3566 {
3581 SceneObjectPart part = (SceneObjectPart)update.Entity; 3567 SceneObjectPart part = (SceneObjectPart)update.Entity;
3582 3568
3569 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3570 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3571 // safety measure.
3572 //
3573 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3574 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3575 // updates and kills on different threads with different scheduling strategies, hence this protection.
3576 //
3577 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3578 // after the root prim has been deleted.
3579 if (m_killRecord.Contains(part.LocalId))
3580 {
3581 // m_log.WarnFormat(
3582 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3583 // part.LocalId, Name);
3584 continue;
3585 }
3586
3583 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3587 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3584 { 3588 {
3585 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3589 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index c4db5da..e02783a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -399,7 +399,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
399 return data; 399 return data;
400 } 400 }
401 401
402 public bool EnqueueOutgoing(OutgoingPacket packet) 402 /// <summary>
403 /// Queue an outgoing packet if appropriate.
404 /// </summary>
405 /// <param name="packet"></param>
406 /// <param name="forceQueue">Always queue the packet if at all possible.</param>
407 /// <returns>
408 /// true if the packet has been queued,
409 /// false if the packet has not been queued and should be sent immediately.
410 /// </returns>
411 public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
403 { 412 {
404 int category = (int)packet.Category; 413 int category = (int)packet.Category;
405 414
@@ -408,14 +417,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
408 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 417 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
409 TokenBucket bucket = m_throttleCategories[category]; 418 TokenBucket bucket = m_throttleCategories[category];
410 419
411 if (bucket.RemoveTokens(packet.Buffer.DataLength)) 420 if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength))
412 { 421 {
413 // Enough tokens were removed from the bucket, the packet will not be queued 422 // Enough tokens were removed from the bucket, the packet will not be queued
414 return false; 423 return false;
415 } 424 }
416 else 425 else
417 { 426 {
418 // Not enough tokens in the bucket, queue this packet 427 // Force queue specified or not enough tokens in the bucket, queue this packet
419 queue.Enqueue(packet); 428 queue.Enqueue(packet);
420 return true; 429 return true;
421 } 430 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index dcfe615..149ae9e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -312,6 +312,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
312 } 312 }
313 } 313 }
314 314
315 /// <summary>
316 /// Start the process of sending a packet to the client.
317 /// </summary>
318 /// <param name="udpClient"></param>
319 /// <param name="packet"></param>
320 /// <param name="category"></param>
321 /// <param name="allowSplitting"></param>
315 public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting) 322 public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
316 { 323 {
317 // CoarseLocationUpdate packets cannot be split in an automated way 324 // CoarseLocationUpdate packets cannot be split in an automated way
@@ -339,6 +346,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339 } 346 }
340 } 347 }
341 348
349 /// <summary>
350 /// Start the process of sending a packet to the client.
351 /// </summary>
352 /// <param name="udpClient"></param>
353 /// <param name="data"></param>
354 /// <param name="type"></param>
355 /// <param name="category"></param>
342 public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category) 356 public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category)
343 { 357 {
344 int dataLength = data.Length; 358 int dataLength = data.Length;
@@ -396,7 +410,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
396 410
397 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); 411 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category);
398 412
399 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 413 // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
414 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
415 // packet so that it isn't sent before a queued update packet.
416 bool requestQueue = type == PacketType.KillObject;
417 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
400 SendPacketFinal(outgoingPacket); 418 SendPacketFinal(outgoingPacket);
401 419
402 #endregion Queue or Send 420 #endregion Queue or Send
@@ -489,7 +507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
489 //Interlocked.Increment(ref Stats.ResentPackets); 507 //Interlocked.Increment(ref Stats.ResentPackets);
490 508
491 // Requeue or resend the packet 509 // Requeue or resend the packet
492 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) 510 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
493 SendPacketFinal(outgoingPacket); 511 SendPacketFinal(outgoingPacket);
494 } 512 }
495 } 513 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 3d6e7f3..c66a4ea 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -41,19 +41,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
41 /// </summary> 41 /// </summary>
42 public class AgentAssetTransactions 42 public class AgentAssetTransactions
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType);
45 46
46 // Fields 47 // Fields
47 private bool m_dumpAssetsToFile; 48 private bool m_dumpAssetsToFile;
48 public AssetTransactionModule Manager; 49 private Scene m_Scene;
49 public UUID UserID; 50 public UUID UserID;
50 public Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>(); 51 public Dictionary<UUID, AssetXferUploader> XferUploaders =
52 new Dictionary<UUID, AssetXferUploader>();
51 53
52 // Methods 54 // Methods
53 public AgentAssetTransactions(UUID agentID, AssetTransactionModule manager, bool dumpAssetsToFile) 55 public AgentAssetTransactions(UUID agentID, Scene scene,
56 bool dumpAssetsToFile)
54 { 57 {
58 m_Scene = scene;
55 UserID = agentID; 59 UserID = agentID;
56 Manager = manager;
57 m_dumpAssetsToFile = dumpAssetsToFile; 60 m_dumpAssetsToFile = dumpAssetsToFile;
58 } 61 }
59 62
@@ -61,7 +64,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
61 { 64 {
62 if (!XferUploaders.ContainsKey(transactionID)) 65 if (!XferUploaders.ContainsKey(transactionID))
63 { 66 {
64 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); 67 AssetXferUploader uploader = new AssetXferUploader(m_Scene,
68 m_dumpAssetsToFile);
65 69
66 lock (XferUploaders) 70 lock (XferUploaders)
67 { 71 {
@@ -88,22 +92,25 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
88 } 92 }
89 } 93 }
90 94
91 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 95 public void RequestCreateInventoryItem(IClientAPI remoteClient,
92 uint callbackID, string description, string name, sbyte invType, 96 UUID transactionID, UUID folderID, uint callbackID,
93 sbyte type, byte wearableType, uint nextOwnerMask) 97 string description, string name, sbyte invType,
98 sbyte type, byte wearableType, uint nextOwnerMask)
94 { 99 {
95 if (XferUploaders.ContainsKey(transactionID)) 100 if (XferUploaders.ContainsKey(transactionID))
96 { 101 {
97 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, 102 XferUploaders[transactionID].RequestCreateInventoryItem(
98 callbackID, description, name, invType, type, 103 remoteClient, transactionID, folderID,
99 wearableType, nextOwnerMask); 104 callbackID, description, name, invType, type,
105 wearableType, nextOwnerMask);
100 } 106 }
101 } 107 }
102 108
103 109
104 110
105 /// <summary> 111 /// <summary>
106 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. 112 /// Get an uploaded asset. If the data is successfully retrieved,
113 /// the transaction will be removed.
107 /// </summary> 114 /// </summary>
108 /// <param name="transactionID"></param> 115 /// <param name="transactionID"></param>
109 /// <returns>The asset if the upload has completed, null if it has not.</returns> 116 /// <returns>The asset if the upload has completed, null if it has not.</returns>
@@ -125,105 +132,56 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
125 return null; 132 return null;
126 } 133 }
127 134
128 //private void CreateItemFromUpload(AssetBase asset, IClientAPI ourClient, UUID inventoryFolderID, uint nextPerms, uint wearableType) 135 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
129 //{ 136 SceneObjectPart part, UUID transactionID,
130 // Manager.MyScene.CommsManager.AssetCache.AddAsset(asset); 137 TaskInventoryItem item)
131 // CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
132 // ourClient.AgentId);
133
134 // if (userInfo != null)
135 // {
136 // InventoryItemBase item = new InventoryItemBase();
137 // item.Owner = ourClient.AgentId;
138 // item.Creator = ourClient.AgentId;
139 // item.ID = UUID.Random();
140 // item.AssetID = asset.FullID;
141 // item.Description = asset.Description;
142 // item.Name = asset.Name;
143 // item.AssetType = asset.Type;
144 // item.InvType = asset.Type;
145 // item.Folder = inventoryFolderID;
146 // item.BasePermissions = 0x7fffffff;
147 // item.CurrentPermissions = 0x7fffffff;
148 // item.EveryOnePermissions = 0;
149 // item.NextPermissions = nextPerms;
150 // item.Flags = wearableType;
151 // item.CreationDate = Util.UnixTimeSinceEpoch();
152
153 // userInfo.AddItem(item);
154 // ourClient.SendInventoryItemCreateUpdate(item);
155 // }
156 // else
157 // {
158 // m_log.ErrorFormat(
159 // "[ASSET TRANSACTIONS]: Could not find user {0} for inventory item creation",
160 // ourClient.AgentId);
161 // }
162 //}
163
164 public void RequestUpdateTaskInventoryItem(
165 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
166 { 138 {
167 if (XferUploaders.ContainsKey(transactionID)) 139 if (XferUploaders.ContainsKey(transactionID))
168 { 140 {
169 AssetBase asset = XferUploaders[transactionID].GetAssetData(); 141 AssetBase asset = GetTransactionAsset(transactionID);
142
143 // Only legacy viewers use this, and they prefer CAPS, which
144 // we have, so this really never runs.
145 // Allow it, but only for "safe" types.
146 if ((InventoryType)item.InvType != InventoryType.Notecard &&
147 (InventoryType)item.InvType != InventoryType.LSL)
148 return;
149
170 if (asset != null) 150 if (asset != null)
171 { 151 {
172 m_log.DebugFormat( 152 asset.FullID = UUID.Random();
173 "[ASSET TRANSACTIONS]: Updating task item {0} in {1} with asset in transaction {2}",
174 item.Name, part.Name, transactionID);
175
176 asset.Name = item.Name; 153 asset.Name = item.Name;
177 asset.Description = item.Description; 154 asset.Description = item.Description;
178 asset.Type = (sbyte)item.Type; 155 asset.Type = (sbyte)item.Type;
179 item.AssetID = asset.FullID; 156 item.AssetID = asset.FullID;
180 157
181 Manager.MyScene.AssetService.Store(asset); 158 m_Scene.AssetService.Store(asset);
182 159
183 if (part.Inventory.UpdateInventoryItem(item)) 160 part.Inventory.UpdateInventoryItem(item);
184 {
185 if ((InventoryType)item.InvType == InventoryType.Notecard)
186 remoteClient.SendAgentAlertMessage("Notecard saved", false);
187 else if ((InventoryType)item.InvType == InventoryType.LSL)
188 remoteClient.SendAgentAlertMessage("Script saved", false);
189 else
190 remoteClient.SendAgentAlertMessage("Item saved", false);
191
192 part.GetProperties(remoteClient);
193 }
194 } 161 }
195 } 162 }
196 } 163 }
197 164
198 165 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
199 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, 166 UUID transactionID, InventoryItemBase item)
200 InventoryItemBase item)
201 { 167 {
202 if (XferUploaders.ContainsKey(transactionID)) 168 if (XferUploaders.ContainsKey(transactionID))
203 { 169 {
204 UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId); 170 AssetBase asset = GetTransactionAsset(transactionID);
205 171
206 AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString()); 172 if (asset != null)
207
208 if (asset == null)
209 {
210 asset = GetTransactionAsset(transactionID);
211 }
212
213 if (asset != null && asset.FullID == assetID)
214 { 173 {
215 // Assets never get updated, new ones get created
216 asset.FullID = UUID.Random(); 174 asset.FullID = UUID.Random();
217 asset.Name = item.Name; 175 asset.Name = item.Name;
218 asset.Description = item.Description; 176 asset.Description = item.Description;
219 asset.Type = (sbyte)item.AssetType; 177 asset.Type = (sbyte)item.AssetType;
220 item.AssetID = asset.FullID; 178 item.AssetID = asset.FullID;
221 179
222 Manager.MyScene.AssetService.Store(asset); 180 m_Scene.AssetService.Store(asset);
223 }
224 181
225 IInventoryService invService = Manager.MyScene.InventoryService; 182 IInventoryService invService = m_Scene.InventoryService;
226 invService.UpdateItem(item); 183 invService.UpdateItem(item);
184 }
227 } 185 }
228 } 186 }
229 } 187 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index ae31050..82558de 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -34,22 +34,19 @@ using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37using Mono.Addins;
37 38
38namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 39namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
39{ 40{
40 public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions 41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetTransactionModule")]
42 public class AssetTransactionModule : INonSharedRegionModule,
43 IAgentAssetTransactions
41 { 44 {
42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45// private static readonly ILog m_log = LogManager.GetLogger(
46// MethodBase.GetCurrentMethod().DeclaringType);
43 47
44 private readonly Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 48 protected Scene m_Scene;
45 private bool m_dumpAssetsToFile = false; 49 private bool m_dumpAssetsToFile = false;
46 private Scene m_scene = null;
47
48 [Obsolete]
49 public Scene MyScene
50 {
51 get{ return m_scene;}
52 }
53 50
54 /// <summary> 51 /// <summary>
55 /// Each agent has its own singleton collection of transactions 52 /// Each agent has its own singleton collection of transactions
@@ -57,33 +54,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
57 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions = 54 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
58 new Dictionary<UUID, AgentAssetTransactions>(); 55 new Dictionary<UUID, AgentAssetTransactions>();
59 56
57 #region IRegionModule Members
60 58
61 public AssetTransactionModule() 59 public void Initialise(IConfigSource config)
62 { 60 {
63 //m_log.Debug("creating AgentAssetTransactionModule");
64 } 61 }
65 62
66 #region IRegionModule Members 63 public void AddRegion(Scene scene)
67
68 public void Initialise(Scene scene, IConfigSource config)
69 { 64 {
70 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 65 m_Scene = scene;
71 { 66 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
72 // m_log.Debug("initialising AgentAssetTransactionModule"); 67 scene.EventManager.OnNewClient += NewClient;
73 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 68 }
74 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
75
76 scene.EventManager.OnNewClient += NewClient;
77 }
78 69
79 // EVIL HACK! 70 public void RegionLoaded(Scene scene)
80 // This needs killing! 71 {
81 //
82 if (m_scene == null)
83 m_scene = scene;
84 } 72 }
85 73
86 public void PostInitialise() 74 public void RemoveRegion(Scene scene)
87 { 75 {
88 } 76 }
89 77
@@ -96,9 +84,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
96 get { return "AgentTransactionModule"; } 84 get { return "AgentTransactionModule"; }
97 } 85 }
98 86
99 public bool IsSharedModule 87 public Type ReplaceableInterface
100 { 88 {
101 get { return true; } 89 get { return typeof(IAgentAssetTransactions); }
102 } 90 }
103 91
104 #endregion 92 #endregion
@@ -111,8 +99,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
111 99
112 #region AgentAssetTransactions 100 #region AgentAssetTransactions
113 /// <summary> 101 /// <summary>
114 /// Get the collection of asset transactions for the given user. If one does not already exist, it 102 /// Get the collection of asset transactions for the given user.
115 /// is created. 103 /// If one does not already exist, it is created.
116 /// </summary> 104 /// </summary>
117 /// <param name="userID"></param> 105 /// <param name="userID"></param>
118 /// <returns></returns> 106 /// <returns></returns>
@@ -122,7 +110,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
122 { 110 {
123 if (!AgentTransactions.ContainsKey(userID)) 111 if (!AgentTransactions.ContainsKey(userID))
124 { 112 {
125 AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); 113 AgentAssetTransactions transactions =
114 new AgentAssetTransactions(userID, m_Scene,
115 m_dumpAssetsToFile);
116
126 AgentTransactions.Add(userID, transactions); 117 AgentTransactions.Add(userID, transactions);
127 } 118 }
128 119
@@ -131,8 +122,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
131 } 122 }
132 123
133 /// <summary> 124 /// <summary>
134 /// Remove the given agent asset transactions. This should be called when a client is departing 125 /// Remove the given agent asset transactions. This should be called
135 /// from a scene (and hence won't be making any more transactions here). 126 /// when a client is departing from a scene (and hence won't be making
127 /// any more transactions here).
136 /// </summary> 128 /// </summary>
137 /// <param name="userID"></param> 129 /// <param name="userID"></param>
138 public void RemoveAgentAssetTransactions(UUID userID) 130 public void RemoveAgentAssetTransactions(UUID userID)
@@ -146,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
146 } 138 }
147 139
148 /// <summary> 140 /// <summary>
149 /// Create an inventory item from data that has been received through a transaction. 141 /// Create an inventory item from data that has been received through
150 /// 142 /// a transaction.
151 /// This is called when new clothing or body parts are created. It may also be called in other 143 /// This is called when new clothing or body parts are created.
152 /// situations. 144 /// It may also be called in other situations.
153 /// </summary> 145 /// </summary>
154 /// <param name="remoteClient"></param> 146 /// <param name="remoteClient"></param>
155 /// <param name="transactionID"></param> 147 /// <param name="transactionID"></param>
@@ -161,61 +153,72 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
161 /// <param name="type"></param> 153 /// <param name="type"></param>
162 /// <param name="wearableType"></param> 154 /// <param name="wearableType"></param>
163 /// <param name="nextOwnerMask"></param> 155 /// <param name="nextOwnerMask"></param>
164 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, 156 public void HandleItemCreationFromTransaction(IClientAPI remoteClient,
165 uint callbackID, string description, string name, sbyte invType, 157 UUID transactionID, UUID folderID, uint callbackID,
166 sbyte type, byte wearableType, uint nextOwnerMask) 158 string description, string name, sbyte invType,
159 sbyte type, byte wearableType, uint nextOwnerMask)
167 { 160 {
168 // m_log.DebugFormat( 161// m_log.DebugFormat(
169 // "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); 162// "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
170 163
171 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 164 AgentAssetTransactions transactions =
165 GetUserTransactions(remoteClient.AgentId);
172 166
173 transactions.RequestCreateInventoryItem( 167 transactions.RequestCreateInventoryItem(remoteClient, transactionID,
174 remoteClient, transactionID, folderID, callbackID, description, 168 folderID, callbackID, description, name, invType, type,
175 name, invType, type, wearableType, nextOwnerMask); 169 wearableType, nextOwnerMask);
176 } 170 }
177 171
178 /// <summary> 172 /// <summary>
179 /// Update an inventory item with data that has been received through a transaction. 173 /// Update an inventory item with data that has been received through a
174 /// transaction.
180 /// 175 ///
181 /// This is called when clothing or body parts are updated (for instance, with new textures or 176 /// This is called when clothing or body parts are updated (for
182 /// colours). It may also be called in other situations. 177 /// instance, with new textures or colours). It may also be called in
178 /// other situations.
183 /// </summary> 179 /// </summary>
184 /// <param name="remoteClient"></param> 180 /// <param name="remoteClient"></param>
185 /// <param name="transactionID"></param> 181 /// <param name="transactionID"></param>
186 /// <param name="item"></param> 182 /// <param name="item"></param>
187 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID, 183 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient,
188 InventoryItemBase item) 184 UUID transactionID, InventoryItemBase item)
189 { 185 {
190 // m_log.DebugFormat( 186// m_log.DebugFormat(
191 // "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 187// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
192 // item.Name); 188// item.Name);
193 189
194 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 190 AgentAssetTransactions transactions =
191 GetUserTransactions(remoteClient.AgentId);
195 192
196 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); 193 transactions.RequestUpdateInventoryItem(remoteClient,
194 transactionID, item);
197 } 195 }
198 196
199 /// <summary> 197 /// <summary>
200 /// Update a task inventory item with data that has been received through a transaction. 198 /// Update a task inventory item with data that has been received
199 /// through a transaction.
201 /// 200 ///
202 /// This is currently called when, for instance, a notecard in a prim is saved. The data is sent 201 /// This is currently called when, for instance, a notecard in a prim
203 /// up through a single AssetUploadRequest. A subsequent UpdateTaskInventory then references the transaction 202 /// is saved. The data is sent up through a single AssetUploadRequest.
203 /// A subsequent UpdateTaskInventory then references the transaction
204 /// and comes through this method. 204 /// and comes through this method.
205 /// </summary> 205 /// </summary>
206 /// <param name="remoteClient"></param> 206 /// <param name="remoteClient"></param>
207 /// <param name="transactionID"></param> 207 /// <param name="transactionID"></param>
208 /// <param name="item"></param> 208 /// <param name="item"></param>
209 public void HandleTaskItemUpdateFromTransaction( 209 public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
210 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 210 SceneObjectPart part, UUID transactionID,
211 TaskInventoryItem item)
211 { 212 {
212 // m_log.DebugFormat( 213// m_log.DebugFormat(
213 // "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", 214// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
214 // item.Name); 215// item.Name);
215 216
216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 217 AgentAssetTransactions transactions =
218 GetUserTransactions(remoteClient.AgentId);
217 219
218 transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item); 220 transactions.RequestUpdateTaskInventoryItem(remoteClient, part,
221 transactionID, item);
219 } 222 }
220 223
221 /// <summary> 224 /// <summary>
@@ -227,8 +230,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
227 /// <param name="type"></param> 230 /// <param name="type"></param>
228 /// <param name="data"></param></param> 231 /// <param name="data"></param></param>
229 /// <param name="tempFile"></param> 232 /// <param name="tempFile"></param>
230 public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, 233 public void HandleUDPUploadRequest(IClientAPI remoteClient,
231 byte[] data, bool storeLocal, bool tempFile) 234 UUID assetID, UUID transaction, sbyte type, byte[] data,
235 bool storeLocal, bool tempFile)
232 { 236 {
233// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); 237// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
234 238
@@ -251,27 +255,33 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
251 } 255 }
252 } 256 }
253 257
254 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 258 AgentAssetTransactions transactions =
259 GetUserTransactions(remoteClient.AgentId);
260
261 AssetXferUploader uploader =
262 transactions.RequestXferUploader(transaction);
255 263
256 AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
257 if (uploader != null) 264 if (uploader != null)
258 { 265 {
259 uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); 266 uploader.Initialise(remoteClient, assetID, transaction, type,
267 data, storeLocal, tempFile);
260 } 268 }
261 } 269 }
262 270
263 /// <summary> 271 /// <summary>
264 /// Handle asset transfer data packets received in response to the asset upload request in 272 /// Handle asset transfer data packets received in response to the
265 /// HandleUDPUploadRequest() 273 /// asset upload request in HandleUDPUploadRequest()
266 /// </summary> 274 /// </summary>
267 /// <param name="remoteClient"></param> 275 /// <param name="remoteClient"></param>
268 /// <param name="xferID"></param> 276 /// <param name="xferID"></param>
269 /// <param name="packetID"></param> 277 /// <param name="packetID"></param>
270 /// <param name="data"></param> 278 /// <param name="data"></param>
271 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 279 public void HandleXfer(IClientAPI remoteClient, ulong xferID,
280 uint packetID, byte[] data)
272 { 281 {
273 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); 282 //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
274 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 283 AgentAssetTransactions transactions =
284 GetUserTransactions(remoteClient.AgentId);
275 285
276 transactions.HandleXfer(xferID, packetID, data); 286 transactions.HandleXfer(xferID, packetID, data);
277 } 287 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 4609738..a7929ba 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -31,7 +31,7 @@ using System.Reflection;
31using log4net; 31using log4net;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
36 36
37namespace OpenSim.Region.CoreModules.Agent.AssetTransaction 37namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
@@ -50,17 +50,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
50 private bool m_finished = false; 50 private bool m_finished = false;
51 private string m_name = String.Empty; 51 private string m_name = String.Empty;
52 private bool m_storeLocal; 52 private bool m_storeLocal;
53 private AgentAssetTransactions m_userTransactions;
54 private uint nextPerm = 0; 53 private uint nextPerm = 0;
55 private IClientAPI ourClient; 54 private IClientAPI ourClient;
56 private UUID TransactionID = UUID.Zero; 55 private UUID TransactionID = UUID.Zero;
57 private sbyte type = 0; 56 private sbyte type = 0;
58 private byte wearableType = 0; 57 private byte wearableType = 0;
59 public ulong XferID; 58 public ulong XferID;
59 private Scene m_Scene;
60 60
61 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) 61 public AssetXferUploader(Scene scene, bool dumpAssetToFile)
62 { 62 {
63 m_userTransactions = transactions; 63 m_Scene = scene;
64 m_dumpAssetToFile = dumpAssetToFile; 64 m_dumpAssetToFile = dumpAssetToFile;
65 } 65 }
66 66
@@ -108,11 +108,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
108 /// <param name="packetID"></param> 108 /// <param name="packetID"></param>
109 /// <param name="data"></param> 109 /// <param name="data"></param>
110 /// <returns>True if the transfer is complete, false otherwise</returns> 110 /// <returns>True if the transfer is complete, false otherwise</returns>
111 public bool Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, 111 public bool Initialise(IClientAPI remoteClient, UUID assetID,
112 bool storeLocal, bool tempFile) 112 UUID transaction, sbyte type, byte[] data, bool storeLocal,
113 bool tempFile)
113 { 114 {
114 ourClient = remoteClient; 115 ourClient = remoteClient;
115 m_asset = new AssetBase(assetID, "blank", type, remoteClient.AgentId.ToString()); 116 m_asset = new AssetBase(assetID, "blank", type,
117 remoteClient.AgentId.ToString());
116 m_asset.Data = data; 118 m_asset.Data = data;
117 m_asset.Description = "empty"; 119 m_asset.Description = "empty";
118 m_asset.Local = storeLocal; 120 m_asset.Local = storeLocal;
@@ -137,12 +139,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
137 protected void RequestStartXfer() 139 protected void RequestStartXfer()
138 { 140 {
139 XferID = Util.GetNextXferID(); 141 XferID = Util.GetNextXferID();
140 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); 142 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID,
143 0, new byte[0]);
141 } 144 }
142 145
143 protected void SendCompleteMessage() 146 protected void SendCompleteMessage()
144 { 147 {
145 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); 148 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
149 m_asset.FullID);
146 150
147 m_finished = true; 151 m_finished = true;
148 if (m_createItem) 152 if (m_createItem)
@@ -151,18 +155,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
151 } 155 }
152 else if (m_storeLocal) 156 else if (m_storeLocal)
153 { 157 {
154 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 158 m_Scene.AssetService.Store(m_asset);
155 } 159 }
156 160
157 m_log.DebugFormat( 161 m_log.DebugFormat(
158 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID); 162 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
163 m_asset.FullID, TransactionID);
159 164
160 if (m_dumpAssetToFile) 165 if (m_dumpAssetToFile)
161 { 166 {
162 DateTime now = DateTime.Now; 167 DateTime now = DateTime.Now;
163 string filename = 168 string filename =
164 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, 169 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
165 now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type); 170 now.Year, now.Month, now.Day, now.Hour, now.Minute,
171 now.Second, m_asset.Name, m_asset.Type);
166 SaveAssetToFile(filename, m_asset.Data); 172 SaveAssetToFile(filename, m_asset.Data);
167 } 173 }
168 } 174 }
@@ -181,9 +187,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
181 fs.Close(); 187 fs.Close();
182 } 188 }
183 189
184 public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 190 public void RequestCreateInventoryItem(IClientAPI remoteClient,
185 uint callbackID, string description, string name, sbyte invType, 191 UUID transactionID, UUID folderID, uint callbackID,
186 sbyte type, byte wearableType, uint nextOwnerMask) 192 string description, string name, sbyte invType,
193 sbyte type, byte wearableType, uint nextOwnerMask)
187 { 194 {
188 if (TransactionID == transactionID) 195 if (TransactionID == transactionID)
189 { 196 {
@@ -212,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
212 219
213 private void DoCreateItem(uint callbackID) 220 private void DoCreateItem(uint callbackID)
214 { 221 {
215 m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); 222 m_Scene.AssetService.Store(m_asset);
216 223
217 InventoryItemBase item = new InventoryItemBase(); 224 InventoryItemBase item = new InventoryItemBase();
218 item.Owner = ourClient.AgentId; 225 item.Owner = ourClient.AgentId;
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
232 item.Flags = (uint) wearableType; 239 item.Flags = (uint) wearableType;
233 item.CreationDate = Util.UnixTimeSinceEpoch(); 240 item.CreationDate = Util.UnixTimeSinceEpoch();
234 241
235 if (m_userTransactions.Manager.MyScene.AddInventoryItem(item)) 242 if (m_Scene.AddInventoryItem(item))
236 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 243 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
237 else 244 else
238 ourClient.SendAlertMessage("Unable to create inventory item"); 245 ourClient.SendAlertMessage("Unable to create inventory item");
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 0df4585..7d6d191 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -115,8 +115,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
115 115
116 #endregion 116 #endregion
117 117
118 /// <summary>
119 /// Check for the existence of the baked texture assets. Request a rebake
120 /// unless checkonly is true.
121 /// </summary>
122 /// <param name="client"></param>
123 /// <param name="checkonly"></param>
118 public bool ValidateBakedTextureCache(IClientAPI client) 124 public bool ValidateBakedTextureCache(IClientAPI client)
119 { 125 {
126 return ValidateBakedTextureCache(client, true);
127 }
128
129 private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
130 {
120 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 131 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
121 if (sp == null) 132 if (sp == null)
122 { 133 {
@@ -131,15 +142,33 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
131 { 142 {
132 int idx = AvatarAppearance.BAKE_INDICES[i]; 143 int idx = AvatarAppearance.BAKE_INDICES[i];
133 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 144 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
134 if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 145
146 // if there is no texture entry, skip it
147 if (face == null)
135 continue; 148 continue;
136 149
150 // if the texture is one of the "defaults" then skip it
151 // this should probably be more intelligent (skirt texture doesnt matter
152 // if the avatar isnt wearing a skirt) but if any of the main baked
153 // textures is default then the rest should be as well
154 if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
155 continue;
156
137 defonly = false; // found a non-default texture reference 157 defonly = false; // found a non-default texture reference
138 158
139 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 159 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
140 return false; 160 {
161 // the asset didn't exist if we are only checking, then we found a bad
162 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false;
164
165 m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID);
166 client.SendRebakeAvatarTextures(face.TextureID);
167 }
141 } 168 }
142 169
170 m_log.InfoFormat("[AVFACTORY]: complete texture check for {0}",client.AgentId);
171
143 // If we only found default textures, then the appearance is not cached 172 // If we only found default textures, then the appearance is not cached
144 return (defonly ? false : true); 173 return (defonly ? false : true);
145 } 174 }
@@ -158,61 +187,43 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
158 return; 187 return;
159 } 188 }
160 189
161 // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); 190 m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}",client.AgentId);
162 191
192 // TODO: This is probably not necessary any longer, just assume the
193 // textureEntry set implies that the appearance transaction is complete
163 bool changed = false; 194 bool changed = false;
164 195
165 // Process the texture entry transactionally, this doesn't guarantee that Appearance is 196 // Process the texture entry transactionally, this doesn't guarantee that Appearance is
166 // going to be handled correctly but it does serialize the updates to the appearance 197 // going to be handled correctly but it does serialize the updates to the appearance
167 lock (m_setAppearanceLock) 198 lock (m_setAppearanceLock)
168 { 199 {
169 if (textureEntry != null)
170 {
171 changed = sp.Appearance.SetTextureEntries(textureEntry);
172
173 // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
174
175 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
176 {
177 int idx = AvatarAppearance.BAKE_INDICES[i];
178 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
179 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
180 Util.FireAndForget(delegate(object o) {
181 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
182 client.SendRebakeAvatarTextures(face.TextureID);
183 });
184 }
185
186 // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
187 }
188
189 // Process the visual params, this may change height as well 200 // Process the visual params, this may change height as well
190 if (visualParams != null) 201 if (visualParams != null)
191 { 202 {
192 if (sp.Appearance.SetVisualParams(visualParams)) 203 changed = sp.Appearance.SetVisualParams(visualParams);
193 { 204 if (sp.Appearance.AvatarHeight > 0)
194 changed = true; 205 sp.SetHeight(sp.Appearance.AvatarHeight);
195 if (sp.Appearance.AvatarHeight > 0)
196 sp.SetHeight(sp.Appearance.AvatarHeight);
197 }
198 } 206 }
199 207
200 // Send the appearance back to the avatar, not clear that this is needed 208 // Process the baked texture array
201 sp.ControllingClient.SendAvatarDataImmediate(sp); 209 if (textureEntry != null)
202 // AvatarAppearance avp = sp.Appearance; 210 {
203 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); 211 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
212
213 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}",client.AgentId);
214 Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
204 215
205 } 216 // This appears to be set only in the final stage of the appearance
206 217 // update transaction. In theory, we should be able to do an immediate
218 // appearance send and save here.
207 219
208 // If something changed in the appearance then queue an appearance save 220 QueueAppearanceSave(client.AgentId);
209 if (changed) 221 QueueAppearanceSend(client.AgentId);
210 QueueAppearanceSave(client.AgentId); 222 }
211 223
212 // And always queue up an appearance update to send out 224 }
213 QueueAppearanceSend(client.AgentId);
214 225
215 // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); 226 // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
216 } 227 }
217 228
218 /// <summary> 229 /// <summary>
@@ -235,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
235 246
236 #region UpdateAppearanceTimer 247 #region UpdateAppearanceTimer
237 248
249 /// <summary>
250 /// Queue up a request to send appearance, makes it possible to
251 /// accumulate changes without sending out each one separately.
252 /// </summary>
238 public void QueueAppearanceSend(UUID agentid) 253 public void QueueAppearanceSend(UUID agentid)
239 { 254 {
240 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); 255 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
@@ -274,21 +289,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
274 289
275 // Send the appearance to everyone in the scene 290 // Send the appearance to everyone in the scene
276 sp.SendAppearanceToAllOtherAgents(); 291 sp.SendAppearanceToAllOtherAgents();
277 // sp.ControllingClient.SendAvatarDataImmediate(sp);
278
279 // Send the appearance back to the avatar
280 // AvatarAppearance avp = sp.Appearance;
281 // sp.ControllingClient.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes());
282 292
283/* 293 // Send animations back to the avatar as well
284// this needs to be fixed, the flag should be on scene presence not the region module 294 sp.Animator.SendAnimPack();
285 // Start the animations if necessary
286 if (!m_startAnimationSet)
287 {
288 sp.Animator.UpdateMovementAnimations();
289 m_startAnimationSet = true;
290 }
291*/
292 } 295 }
293 296
294 private void HandleAppearanceSave(UUID agentid) 297 private void HandleAppearanceSave(UUID agentid)
@@ -374,8 +377,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
374 377
375 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); 378 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
376 379
377 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 380 // we need to clean out the existing textures
381 sp.Appearance.ResetAppearance();
378 382
383 // operate on a copy of the appearance so we don't have to lock anything
384 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
385
379 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 386 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
380 { 387 {
381 if (wear.Type < AvatarWearable.MAX_WEARABLES) 388 if (wear.Type < AvatarWearable.MAX_WEARABLES)
@@ -388,9 +395,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
388 SetAppearanceAssets(sp.UUID, ref avatAppearance); 395 SetAppearanceAssets(sp.UUID, ref avatAppearance);
389 396
390 // could get fancier with the locks here, but in the spirit of "last write wins" 397 // could get fancier with the locks here, but in the spirit of "last write wins"
391 // this should work correctly 398 // this should work correctly, also, we don't need to send the appearance here
399 // since the "iswearing" will trigger a new set of visual param and baked texture changes
400 // when those complete, the new appearance will be sent
392 sp.Appearance = avatAppearance; 401 sp.Appearance = avatAppearance;
393 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); 402 QueueAppearanceSave(client.AgentId);
394 } 403 }
395 404
396 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 405 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 046b05f..acf2c3e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -37,12 +37,11 @@ using System.Xml.Linq;
37using log4net; 37using log4net;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Osp;
42using OpenSim.Framework.Serialization; 40using OpenSim.Framework.Serialization;
43using OpenSim.Framework.Serialization.External; 41using OpenSim.Framework.Serialization.External;
44using OpenSim.Region.CoreModules.World.Archiver; 42using OpenSim.Region.CoreModules.World.Archiver;
45using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
47 46
48namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 47namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
@@ -398,20 +397,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
398 // Don't use the item ID that's in the file 397 // Don't use the item ID that's in the file
399 item.ID = UUID.Random(); 398 item.ID = UUID.Random();
400 399
401 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); 400 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
402 if (UUID.Zero != ospResolvedId) 401 if (UUID.Zero != ospResolvedId) // The user exists in this grid
403 { 402 {
404 item.CreatorIdAsUuid = ospResolvedId; 403 item.CreatorIdAsUuid = ospResolvedId;
405 404
406 // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the 405 // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the
407 // database). Instead, replace with the UUID that we found. 406 // database). Instead, replace with the UUID that we found.
408 item.CreatorId = ospResolvedId.ToString(); 407 item.CreatorId = ospResolvedId.ToString();
408
409 item.CreatorData = string.Empty;
409 } 410 }
410 else 411 else if (item.CreatorData == null || item.CreatorData == String.Empty)
411 { 412 {
412 item.CreatorIdAsUuid = m_userInfo.PrincipalID; 413 item.CreatorIdAsUuid = m_userInfo.PrincipalID;
413 } 414 }
414 415
415 item.Owner = m_userInfo.PrincipalID; 416 item.Owner = m_userInfo.PrincipalID;
416 417
417 // Reset folder ID to the one in which we want to load it 418 // Reset folder ID to the one in which we want to load it
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index d81703a..cab341d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -36,8 +36,6 @@ using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
38using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Communications.Osp;
41using OpenSim.Region.CoreModules.World.Archiver; 39using OpenSim.Region.CoreModules.World.Archiver;
42using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
43using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
@@ -139,20 +137,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
139 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); 137 m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
140 } 138 }
141 139
142 protected void SaveInvItem(InventoryItemBase inventoryItem, string path) 140 protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
143 { 141 {
144 string filename = path + CreateArchiveItemName(inventoryItem); 142 string filename = path + CreateArchiveItemName(inventoryItem);
145 143
146 // Record the creator of this item for user record purposes (which might go away soon) 144 // Record the creator of this item for user record purposes (which might go away soon)
147 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1; 145 m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;
148 146
149 InventoryItemBase saveItem = (InventoryItemBase)inventoryItem.Clone(); 147 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
150 saveItem.CreatorId = OspResolver.MakeOspa(saveItem.CreatorIdAsUuid, m_scene.UserAccountService);
151
152 string serialization = UserInventoryItemSerializer.Serialize(saveItem);
153 m_archiveWriter.WriteFile(filename, serialization); 148 m_archiveWriter.WriteFile(filename, serialization);
154 149
155 m_assetGatherer.GatherAssetUuids(saveItem.AssetID, (AssetType)saveItem.AssetType, m_assetUuids); 150 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
156 } 151 }
157 152
158 /// <summary> 153 /// <summary>
@@ -161,7 +156,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
161 /// <param name="inventoryFolder">The inventory folder to save</param> 156 /// <param name="inventoryFolder">The inventory folder to save</param>
162 /// <param name="path">The path to which the folder should be saved</param> 157 /// <param name="path">The path to which the folder should be saved</param>
163 /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param> 158 /// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param>
164 protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself) 159 protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary<string, object> options, IUserAccountService userAccountService)
165 { 160 {
166 if (saveThisFolderItself) 161 if (saveThisFolderItself)
167 { 162 {
@@ -176,19 +171,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
176 171
177 foreach (InventoryFolderBase childFolder in contents.Folders) 172 foreach (InventoryFolderBase childFolder in contents.Folders)
178 { 173 {
179 SaveInvFolder(childFolder, path, true); 174 SaveInvFolder(childFolder, path, true, options, userAccountService);
180 } 175 }
181 176
182 foreach (InventoryItemBase item in contents.Items) 177 foreach (InventoryItemBase item in contents.Items)
183 { 178 {
184 SaveInvItem(item, path); 179 SaveInvItem(item, path, options, userAccountService);
185 } 180 }
186 } 181 }
187 182
188 /// <summary> 183 /// <summary>
189 /// Execute the inventory write request 184 /// Execute the inventory write request
190 /// </summary> 185 /// </summary>
191 public void Execute() 186 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
192 { 187 {
193 try 188 try
194 { 189 {
@@ -266,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
266 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); 261 m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
267 262
268 //recurse through all dirs getting dirs and files 263 //recurse through all dirs getting dirs and files
269 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly); 264 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
270 } 265 }
271 else if (inventoryItem != null) 266 else if (inventoryItem != null)
272 { 267 {
@@ -274,14 +269,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
274 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", 269 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
275 inventoryItem.Name, inventoryItem.ID, m_invPath); 270 inventoryItem.Name, inventoryItem.ID, m_invPath);
276 271
277 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH); 272 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
278 } 273 }
279 274
280 // Don't put all this profile information into the archive right now. 275 // Don't put all this profile information into the archive right now.
281 //SaveUsers(); 276 //SaveUsers();
282 277
283 new AssetsRequest( 278 new AssetsRequest(
284 new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute(); 279 new AssetsArchiver(m_archiveWriter),
280 m_assetUuids, m_scene.AssetService,
281 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
282 options, ReceivedAllAssets).Execute();
285 } 283 }
286 catch (Exception) 284 catch (Exception)
287 { 285 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 2eaca49..b33c2b1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -75,6 +75,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
75 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 75 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
76 private Scene m_aScene; 76 private Scene m_aScene;
77 77
78 private IUserAccountService m_UserAccountService;
79 protected IUserAccountService UserAccountService
80 {
81 get
82 {
83 if (m_UserAccountService == null)
84 // What a strange thing to do...
85 foreach (Scene s in m_scenes.Values)
86 {
87 m_UserAccountService = s.RequestModuleInterface<IUserAccountService>();
88 break;
89 }
90
91 return m_UserAccountService;
92 }
93 }
94
95
78 public InventoryArchiverModule() {} 96 public InventoryArchiverModule() {}
79 97
80 public InventoryArchiverModule(bool disablePresenceChecks) 98 public InventoryArchiverModule(bool disablePresenceChecks)
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
106 124
107 scene.AddCommand( 125 scene.AddCommand(
108 this, "save iar", 126 this, "save iar",
109 "save iar <first> <last> <inventory path> <password> [<IAR path>]", 127 "save iar <first> <last> <inventory path> <password> [--p|-profile=<url>] [<IAR path>]",
110 "Save user inventory archive (IAR).", 128 "Save user inventory archive (IAR).",
111 "<first> is the user's first name." + Environment.NewLine 129 "<first> is the user's first name." + Environment.NewLine
112 + "<last> is the user's last name." + Environment.NewLine 130 + "<last> is the user's last name." + Environment.NewLine
113 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine 131 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
132 + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
114 + "<IAR path> is the filesystem path at which to save the IAR." 133 + "<IAR path> is the filesystem path at which to save the IAR."
115 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), 134 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
116 HandleSaveInvConsoleCommand); 135 HandleSaveInvConsoleCommand);
@@ -157,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
157 { 176 {
158 try 177 try
159 { 178 {
160 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(); 179 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService);
161 } 180 }
162 catch (EntryPointNotFoundException e) 181 catch (EntryPointNotFoundException e)
163 { 182 {
@@ -197,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
197 { 216 {
198 try 217 try
199 { 218 {
200 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(); 219 new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService);
201 } 220 }
202 catch (EntryPointNotFoundException e) 221 catch (EntryPointNotFoundException e)
203 { 222 {
@@ -235,14 +254,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
235 if (m_scenes.Count > 0) 254 if (m_scenes.Count > 0)
236 { 255 {
237 UserAccount userInfo = GetUserInfo(firstName, lastName, pass); 256 UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
238 257
239 if (userInfo != null) 258 if (userInfo != null)
240 { 259 {
241 if (CheckPresence(userInfo.PrincipalID)) 260 if (CheckPresence(userInfo.PrincipalID))
242 { 261 {
262
243 InventoryArchiveReadRequest request; 263 InventoryArchiveReadRequest request;
244 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); 264 bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
245 265
246 try 266 try
247 { 267 {
248 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); 268 request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
@@ -256,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
256 276
257 return false; 277 return false;
258 } 278 }
259 279
260 UpdateClientWithLoadedNodes(userInfo, request.Execute()); 280 UpdateClientWithLoadedNodes(userInfo, request.Execute());
261 281
262 return true; 282 return true;
@@ -268,6 +288,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
268 userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID); 288 userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
269 } 289 }
270 } 290 }
291 else
292 m_log.ErrorFormat("[INVENTORY ARCHIVER]: User {0} {1} not found",
293 firstName, lastName);
271 } 294 }
272 295
273 return false; 296 return false;
@@ -368,10 +391,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
368 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) 391 protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
369 { 392 {
370 Guid id = Guid.NewGuid(); 393 Guid id = Guid.NewGuid();
371 394
395 Dictionary<string, object> options = new Dictionary<string, object>();
396
397 OptionSet ops = new OptionSet();
398 //ops.Add("v|version=", delegate(string v) { options["version"] = v; });
399 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
400
401 List<string> mainParams = ops.Parse(cmdparams);
402
372 try 403 try
373 { 404 {
374 if (cmdparams.Length < 6) 405 if (mainParams.Count < 6)
375 { 406 {
376 m_log.Error( 407 m_log.Error(
377 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]"); 408 "[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]");
@@ -379,18 +410,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
379 } 410 }
380 411
381 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); 412 m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
382 413 if (options.ContainsKey("profile"))
383 string firstName = cmdparams[2]; 414 m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -profile option if you want to produce a compatible IAR");
384 string lastName = cmdparams[3]; 415
385 string invPath = cmdparams[4]; 416 string firstName = mainParams[2];
386 string pass = cmdparams[5]; 417 string lastName = mainParams[3];
387 string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); 418 string invPath = mainParams[4];
419 string pass = mainParams[5];
420 string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
388 421
389 m_log.InfoFormat( 422 m_log.InfoFormat(
390 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", 423 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
391 savePath, invPath, firstName, lastName); 424 savePath, invPath, firstName, lastName);
392 425
393 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>()); 426 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
394 } 427 }
395 catch (InventoryArchiverException e) 428 catch (InventoryArchiverException e)
396 { 429 {
@@ -518,5 +551,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
518 551
519 return false; 552 return false;
520 } 553 }
554
521 } 555 }
522} 556}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 938886b2..2747e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -38,7 +38,6 @@ using OpenSim.Framework;
38using OpenSim.Framework.Serialization; 38using OpenSim.Framework.Serialization;
39using OpenSim.Framework.Serialization.External; 39using OpenSim.Framework.Serialization.External;
40using OpenSim.Framework.Communications; 40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Communications.Osp;
42using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; 41using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
43using OpenSim.Region.CoreModules.World.Serialiser; 42using OpenSim.Region.CoreModules.World.Serialiser;
44using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
@@ -96,14 +95,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
96 item1.Name = m_item1Name; 95 item1.Name = m_item1Name;
97 item1.AssetID = UUID.Random(); 96 item1.AssetID = UUID.Random();
98 item1.GroupID = UUID.Random(); 97 item1.GroupID = UUID.Random();
99 item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName); 98 //item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
100 //item1.CreatorId = userUuid.ToString(); 99 //item1.CreatorId = userUuid.ToString();
101 //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; 100 item1.CreatorId = m_ua2.PrincipalID.ToString();
102 item1.Owner = UUID.Zero; 101 item1.Owner = UUID.Zero;
103 102
103 Scene scene = SceneSetupHelpers.SetupScene("Inventory");
104 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
105
104 string item1FileName 106 string item1FileName
105 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); 107 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
106 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); 108 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string, object>(), scene.UserAccountService));
107 tar.Close(); 109 tar.Close();
108 m_iarStream = new MemoryStream(archiveWriteStream.ToArray()); 110 m_iarStream = new MemoryStream(archiveWriteStream.ToArray());
109 } 111 }
@@ -386,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
386 Scene scene = SceneSetupHelpers.SetupScene("inventory"); 388 Scene scene = SceneSetupHelpers.SetupScene("inventory");
387 389
388 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); 390 SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
389 391
390 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); 392 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood");
391 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); 393 UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
392 394
@@ -551,7 +553,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
551 553
552 string item1FileName 554 string item1FileName
553 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); 555 = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
554 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); 556 tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string,object>(), null));
555 tar.Close(); 557 tar.Close();
556 558
557 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 559 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 56aefa5..47548c7 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -876,8 +876,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
876 } 876 }
877 877
878 agent.MakeChildAgent(); 878 agent.MakeChildAgent();
879
879 // now we have a child agent in this region. Request all interesting data about other (root) agents 880 // now we have a child agent in this region. Request all interesting data about other (root) agents
880 agent.SendInitialFullUpdateToAllClients(); 881 agent.SendOtherAgentsAvatarDataToMe();
882 agent.SendOtherAgentsAppearanceToMe();
881 883
882 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); 884 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
883 885
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index ccb892e..81b65c5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -27,8 +27,11 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Reflection; 31using System.Reflection;
31using System.Threading; 32using System.Threading;
33using System.Xml;
34
32using log4net; 35using log4net;
33using OpenMetaverse; 36using OpenMetaverse;
34using OpenSim.Framework; 37using OpenSim.Framework;
@@ -52,14 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
52// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>(); 55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
53 56
54 private Scene m_scene; 57 private Scene m_scene;
58 private string m_ProfileServerURI;
55 59
56 #endregion 60 #endregion
57 61
58 #region Constructor 62 #region Constructor
59 63
60 public HGAssetMapper(Scene scene) 64 public HGAssetMapper(Scene scene, string profileURL)
61 { 65 {
62 m_scene = scene; 66 m_scene = scene;
67 m_ProfileServerURI = profileURL;
63 } 68 }
64 69
65 #endregion 70 #endregion
@@ -95,16 +100,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
95 try 100 try
96 { 101 {
97 asset1.ID = url + "/" + asset.ID; 102 asset1.ID = url + "/" + asset.ID;
98// UUID temp = UUID.Zero;
99 // TODO: if the creator is local, stick this grid's URL in front
100 //if (UUID.TryParse(asset.Metadata.CreatorID, out temp))
101 // asset1.Metadata.CreatorID = ??? + "/" + asset.Metadata.CreatorID;
102 } 103 }
103 catch 104 catch
104 { 105 {
105 m_log.Warn("[HG ASSET MAPPER]: Oops."); 106 m_log.Warn("[HG ASSET MAPPER]: Oops.");
106 } 107 }
107 108
109 AdjustIdentifiers(asset1.Metadata);
110 if (asset1.Metadata.Type == (sbyte)AssetType.Object)
111 asset1.Data = AdjustIdentifiers(asset.Data);
112 else
113 asset1.Data = asset.Data;
114
108 m_scene.AssetService.Store(asset1); 115 m_scene.AssetService.Store(asset1);
109 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); 116 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
110 } 117 }
@@ -118,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
118 125
119 private void Copy(AssetBase from, AssetBase to) 126 private void Copy(AssetBase from, AssetBase to)
120 { 127 {
121 to.Data = from.Data; 128 //to.Data = from.Data; // don't copy this, it's copied elsewhere
122 to.Description = from.Description; 129 to.Description = from.Description;
123 to.FullID = from.FullID; 130 to.FullID = from.FullID;
124 to.ID = from.ID; 131 to.ID = from.ID;
@@ -129,6 +136,70 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
129 136
130 } 137 }
131 138
139 private void AdjustIdentifiers(AssetMetadata meta)
140 {
141 if (meta.CreatorID != null && meta.CreatorID != string.Empty)
142 {
143 UUID uuid = UUID.Zero;
144 UUID.TryParse(meta.CreatorID, out uuid);
145 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
146 if (creator != null)
147 meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName;
148 }
149 }
150
151 protected byte[] AdjustIdentifiers(byte[] data)
152 {
153 string xml = Utils.BytesToString(data);
154 return Utils.StringToBytes(RewriteSOP(xml));
155 }
156
157 protected string RewriteSOP(string xml)
158 {
159 XmlDocument doc = new XmlDocument();
160 doc.LoadXml(xml);
161 XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
162
163 foreach (XmlNode sop in sops)
164 {
165 UserAccount creator = null;
166 bool hasCreatorData = false;
167 XmlNodeList nodes = sop.ChildNodes;
168 foreach (XmlNode node in nodes)
169 {
170 if (node.Name == "CreatorID")
171 {
172 UUID uuid = UUID.Zero;
173 UUID.TryParse(node.InnerText, out uuid);
174 creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
175 }
176 if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
177 hasCreatorData = true;
178
179 //if (node.Name == "OwnerID")
180 //{
181 // UserAccount owner = GetUser(node.InnerText);
182 // if (owner != null)
183 // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
184 //}
185 }
186
187 if (!hasCreatorData && creator != null)
188 {
189 XmlElement creatorData = doc.CreateElement("CreatorData");
190 creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName;
191 sop.AppendChild(creatorData);
192 }
193 }
194
195 using (StringWriter wr = new StringWriter())
196 {
197 doc.Save(wr);
198 return wr.ToString();
199 }
200
201 }
202
132 // TODO: unused 203 // TODO: unused
133 // private void Dump(Dictionary<UUID, bool> lst) 204 // private void Dump(Dictionary<UUID, bool> lst)
134 // { 205 // {
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 125a397..34b8114 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -54,6 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
54 get { return m_assMapper; } 54 get { return m_assMapper; }
55 } 55 }
56 56
57 private string m_ProfileServerURI;
58
57// private bool m_Initialized = false; 59// private bool m_Initialized = false;
58 60
59 #region INonSharedRegionModule 61 #region INonSharedRegionModule
@@ -73,6 +75,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
73 { 75 {
74 m_Enabled = true; 76 m_Enabled = true;
75 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); 77 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
78
79 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
80 if (thisModuleConfig != null)
81 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
82 else
83 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
76 } 84 }
77 } 85 }
78 } 86 }
@@ -83,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
83 return; 91 return;
84 92
85 base.AddRegion(scene); 93 base.AddRegion(scene);
86 m_assMapper = new HGAssetMapper(scene); 94 m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI);
87 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 95 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
88 96
89 } 97 }
@@ -97,7 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
97 string userAssetServer = string.Empty; 105 string userAssetServer = string.Empty;
98 if (IsForeignUser(avatarID, out userAssetServer)) 106 if (IsForeignUser(avatarID, out userAssetServer))
99 { 107 {
100 m_assMapper.Post(assetID, avatarID, userAssetServer); 108 Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
101 } 109 }
102 } 110 }
103 111
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 67732ff..1ebccd1 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -53,6 +53,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
53 53
54 protected bool m_Enabled = false; 54 protected bool m_Enabled = false;
55 protected Scene m_Scene; 55 protected Scene m_Scene;
56 protected IUserManagement m_UserManagement;
57 protected IUserManagement UserManagementModule
58 {
59 get
60 {
61 if (m_UserManagement == null)
62 m_UserManagement = m_Scene.RequestModuleInterface<IUserManagement>();
63 return m_UserManagement;
64 }
65 }
66
56 67
57 #region INonSharedRegionModule 68 #region INonSharedRegionModule
58 69
@@ -542,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
542 SceneObjectGroup group 553 SceneObjectGroup group
543 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); 554 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);
544 555
556 Util.FireAndForget(delegate { AddUserData(group); });
557
545 group.RootPart.FromFolderID = item.Folder; 558 group.RootPart.FromFolderID = item.Folder;
546 559
547 // If it's rezzed in world, select it. Much easier to 560 // If it's rezzed in world, select it. Much easier to
@@ -699,6 +712,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
699 return null; 712 return null;
700 } 713 }
701 714
715 protected void AddUserData(SceneObjectGroup sog)
716 {
717 UserManagementModule.AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
718 foreach (SceneObjectPart sop in sog.Parts)
719 UserManagementModule.AddUser(sop.CreatorID, sop.CreatorData);
720 }
721
702 public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) 722 public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
703 { 723 {
704 } 724 }
@@ -779,9 +799,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
779 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID) 799 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID)
780 { 800 {
781 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>(); 801 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>();
782 InventoryItemBase assetRequestItem = new InventoryItemBase(itemID, agentID); 802 InventoryItemBase item = new InventoryItemBase(itemID, agentID);
783 assetRequestItem = invService.GetItem(assetRequestItem); 803 item = invService.GetItem(item);
784 return assetRequestItem; 804
805 if (item.CreatorData != null && item.CreatorData != string.Empty)
806 UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData);
807
808 return item;
785 } 809 }
786 810
787 #endregion 811 #endregion
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 0d94baa..bf84100 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -275,6 +275,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); 275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
276 } 276 }
277 277
278 public void AddUser(UUID uuid, string first, string last, string profileURL)
279 {
280 AddUser(uuid, profileURL + ";" + first + " " + last);
281 }
282
278 //public void AddUser(UUID uuid, string userData) 283 //public void AddUser(UUID uuid, string userData)
279 //{ 284 //{
280 // if (m_UserCache.ContainsKey(uuid)) 285 // if (m_UserCache.ContainsKey(uuid))
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
index 2324380..e25700d 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
@@ -91,9 +91,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset
91 { 91 {
92 m_Registered = true; 92 m_Registered = true;
93 93
94 m_log.Info("[RegionAssetService]: Starting..."); 94 m_log.Info("[HGAssetService]: Starting...");
95 95
96 Object[] args = new Object[] { m_Config, MainServer.Instance, string.Empty }; 96
97 Object[] args = new Object[] { m_Config, MainServer.Instance, "HGAssetService" };
97 98
98 ServerUtils.LoadPlugin<IServiceConnector>("OpenSim.Server.Handlers.dll:AssetServiceConnector", args); 99 ServerUtils.LoadPlugin<IServiceConnector>("OpenSim.Server.Handlers.dll:AssetServiceConnector", args);
99 } 100 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index b987b5a..0699407 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -190,7 +190,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
190 190
191 new AssetsRequest( 191 new AssetsRequest(
192 new AssetsArchiver(archiveWriter), assetUuids, 192 new AssetsArchiver(archiveWriter), assetUuids,
193 m_scene.AssetService, awre.ReceivedAllAssets).Execute(); 193 m_scene.AssetService, m_scene.UserAccountService,
194 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
194 } 195 }
195 catch (Exception) 196 catch (Exception)
196 { 197 {
@@ -238,10 +239,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
238 } 239 }
239 240
240 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); 241 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
241 if (majorVersion == 1) 242 //if (majorVersion == 1)
242 { 243 //{
243 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); 244 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
244 } 245 //}
245 246
246 StringWriter sw = new StringWriter(); 247 StringWriter sw = new StringWriter();
247 XmlTextWriter xtw = new XmlTextWriter(sw); 248 XmlTextWriter xtw = new XmlTextWriter(sw);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index d4a09b4..5da1656 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -34,6 +34,7 @@ using log4net;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Serialization; 36using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.World.Archiver 40namespace OpenSim.Region.CoreModules.World.Archiver
@@ -100,17 +101,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
100 /// Asset service used to request the assets 101 /// Asset service used to request the assets
101 /// </value> 102 /// </value>
102 protected IAssetService m_assetService; 103 protected IAssetService m_assetService;
104 protected IUserAccountService m_userAccountService;
105 protected UUID m_scopeID; // the grid ID
103 106
104 protected AssetsArchiver m_assetsArchiver; 107 protected AssetsArchiver m_assetsArchiver;
105 108
109 protected Dictionary<string, object> m_options;
110
106 protected internal AssetsRequest( 111 protected internal AssetsRequest(
107 AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids, 112 AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids,
108 IAssetService assetService, AssetsRequestCallback assetsRequestCallback) 113 IAssetService assetService, IUserAccountService userService,
114 UUID scope, Dictionary<string, object> options,
115 AssetsRequestCallback assetsRequestCallback)
109 { 116 {
110 m_assetsArchiver = assetsArchiver; 117 m_assetsArchiver = assetsArchiver;
111 m_uuids = uuids; 118 m_uuids = uuids;
112 m_assetsRequestCallback = assetsRequestCallback; 119 m_assetsRequestCallback = assetsRequestCallback;
113 m_assetService = assetService; 120 m_assetService = assetService;
121 m_userAccountService = userService;
122 m_scopeID = scope;
123 m_options = options;
114 m_repliesRequired = uuids.Count; 124 m_repliesRequired = uuids.Count;
115 125
116 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); 126 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
@@ -241,7 +251,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
241 { 251 {
242// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id); 252// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
243 m_foundAssetUuids.Add(asset.FullID); 253 m_foundAssetUuids.Add(asset.FullID);
244 m_assetsArchiver.WriteAsset(asset); 254
255 m_assetsArchiver.WriteAsset(PostProcess(asset));
245 } 256 }
246 else 257 else
247 { 258 {
@@ -288,5 +299,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
288 "[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e); 299 "[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e);
289 } 300 }
290 } 301 }
302
303 protected AssetBase PostProcess(AssetBase asset)
304 {
305 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("profile"))
306 {
307 //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID);
308 string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["profile"].ToString(), m_userAccountService, m_scopeID);
309 asset.Data = Utils.StringToBytes(xml);
310 }
311 return asset;
312 }
291 } 313 }
292} 314}
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 622fc08..ddae20f 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -231,7 +231,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
231 231
232 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) 232 private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds)
233 { 233 {
234 m_scene.Restart(timeInSeconds); 234 IRestartModule restartModule = m_scene.RequestModuleInterface<IRestartModule>();
235 if (restartModule != null)
236 {
237 List<int> times = new List<int>();
238 while (timeInSeconds > 0)
239 {
240 times.Add(timeInSeconds);
241 if (timeInSeconds > 300)
242 timeInSeconds -= 120;
243 else if (timeInSeconds > 30)
244 timeInSeconds -= 30;
245 else
246 timeInSeconds -= 15;
247 }
248
249 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
250 }
235 } 251 }
236 252
237 private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID) 253 private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID)
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
new file mode 100644
index 0000000..c65aa6a
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -0,0 +1,263 @@
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.Reflection;
30using System.Timers;
31using System.Threading;
32using System.Collections.Generic;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using Timer=System.Timers.Timer;
41using Mono.Addins;
42
43namespace OpenSim.Region.CoreModules.World.Region
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
46 public class RestartModule : INonSharedRegionModule, IRestartModule
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 protected Scene m_Scene;
52 protected Timer m_CountdownTimer = null;
53 protected DateTime m_RestartBegin;
54 protected List<int> m_Alerts;
55 protected string m_Message;
56 protected UUID m_Initiator;
57 protected bool m_Notice = false;
58 protected IDialogModule m_DialogModule = null;
59
60 public void Initialise(IConfigSource config)
61 {
62 }
63
64 public void AddRegion(Scene scene)
65 {
66 m_Scene = scene;
67 scene.RegisterModuleInterface<IRestartModule>(this);
68 MainConsole.Instance.Commands.AddCommand("RestartModule",
69 false, "region restart bluebox",
70 "region restart bluebox <message> <time> ...",
71 "Restart the region", HandleRegionRestart);
72 MainConsole.Instance.Commands.AddCommand("RestartModule",
73 false, "region restart notice",
74 "region restart notice <message> <time> ...",
75 "Restart the region", HandleRegionRestart);
76 MainConsole.Instance.Commands.AddCommand("RestartModule",
77 false, "region restart abort",
78 "region restart abort [<message>]",
79 "Restart the region", HandleRegionRestart);
80 }
81
82 public void RegionLoaded(Scene scene)
83 {
84 m_DialogModule = m_Scene.RequestModuleInterface<IDialogModule>();
85 }
86
87 public void RemoveRegion(Scene scene)
88 {
89 }
90
91 public void Close()
92 {
93 }
94
95 public string Name
96 {
97 get { return "RestartModule"; }
98 }
99
100 public Type ReplaceableInterface
101 {
102 get { return typeof(IRestartModule); }
103 }
104
105 public TimeSpan TimeUntilRestart
106 {
107 get { return DateTime.Now - m_RestartBegin; }
108 }
109
110 public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
111 {
112 if (m_CountdownTimer != null)
113 return;
114
115 if (alerts == null)
116 {
117 m_Scene.RestartNow();
118 return;
119 }
120
121 m_Message = message;
122 m_Initiator = initiator;
123 m_Notice = notice;
124 m_Alerts = new List<int>(alerts);
125 m_Alerts.Sort();
126 m_Alerts.Reverse();
127
128 if (m_Alerts[0] == 0)
129 {
130 m_Scene.RestartNow();
131 return;
132 }
133
134 int nextInterval = DoOneNotice();
135
136 SetTimer(nextInterval);
137 }
138
139 public int DoOneNotice()
140 {
141 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
142 {
143 m_Scene.RestartNow();
144 return 0;
145 }
146
147 int nextAlert = 0;
148 while (m_Alerts.Count > 1)
149 {
150 if (m_Alerts[1] == m_Alerts[0])
151 {
152 m_Alerts.RemoveAt(0);
153 continue;
154 }
155 nextAlert = m_Alerts[1];
156 break;
157 }
158
159 int currentAlert = m_Alerts[0];
160
161 m_Alerts.RemoveAt(0);
162
163 int minutes = currentAlert / 60;
164 string currentAlertString = String.Empty;
165 if (minutes > 0)
166 {
167 if (minutes == 1)
168 currentAlertString += "1 minute";
169 else
170 currentAlertString += String.Format("{0} minutes", minutes);
171 if ((currentAlert % 60) != 0)
172 currentAlertString += " and ";
173 }
174 if ((currentAlert % 60) != 0)
175 {
176 int seconds = currentAlert % 60;
177 if (seconds == 1)
178 currentAlertString += "1 second";
179 else
180 currentAlertString += String.Format("{0} seconds", seconds);
181 }
182
183 string msg = String.Format(m_Message, currentAlertString);
184
185 if (m_DialogModule != null && msg != String.Empty)
186 {
187 if (m_Notice)
188 m_DialogModule.SendGeneralAlert(msg);
189 else
190 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
191 }
192
193 return currentAlert - nextAlert;
194 }
195
196 public void SetTimer(int intervalSeconds)
197 {
198 m_CountdownTimer = new Timer();
199 m_CountdownTimer.AutoReset = false;
200 m_CountdownTimer.Interval = intervalSeconds * 1000;
201 m_CountdownTimer.Elapsed += OnTimer;
202 m_CountdownTimer.Start();
203 }
204
205 private void OnTimer(object source, ElapsedEventArgs e)
206 {
207 int nextInterval = DoOneNotice();
208
209 SetTimer(nextInterval);
210 }
211
212 public void AbortRestart(string message)
213 {
214 if (m_CountdownTimer != null)
215 {
216 m_CountdownTimer.Stop();
217 m_CountdownTimer = null;
218 if (m_DialogModule != null && message != String.Empty)
219 m_DialogModule.SendGeneralAlert(message);
220 }
221 }
222
223 private void HandleRegionRestart(string module, string[] args)
224 {
225 if (!(MainConsole.Instance.ConsoleScene is Scene))
226 return;
227
228 if (MainConsole.Instance.ConsoleScene != m_Scene)
229 return;
230
231 if (args.Length < 5)
232 {
233 if (args.Length > 2)
234 {
235 if (args[2] == "abort")
236 {
237 string msg = String.Empty;
238 if (args.Length > 3)
239 msg = args[3];
240
241 AbortRestart(msg);
242
243 MainConsole.Instance.Output("Region restart aborted");
244 return;
245 }
246 }
247
248 MainConsole.Instance.Output("Error: restart region <mode> <name> <time> ...");
249 return;
250 }
251
252 bool notice = false;
253 if (args[2] == "notice")
254 notice = true;
255
256 List<int> times = new List<int>();
257 for (int i = 4 ; i < args.Length ; i++)
258 times.Add(Convert.ToInt32(args[i]));
259
260 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
261 }
262 }
263}
diff --git a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
index 6da41db..088b818 100644
--- a/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
+++ b/OpenSim/Region/Examples/SimpleModule/RegionModule.cs
@@ -34,6 +34,17 @@ using OpenSim.Region.Framework.Scenes;
34 34
35namespace OpenSim.Region.Examples.SimpleModule 35namespace OpenSim.Region.Examples.SimpleModule
36{ 36{
37 /// <summary>
38 /// Example region module.
39 /// </summary>
40 /// <remarks>
41 /// This is an old and unmaintained region module which uses the old style module interface. It is not loaded into
42 /// OpenSim by default. If you want to try enabling it, look in the bin folder of this project.
43 /// Please see the README.txt in this project on the filesystem for some more information.
44 /// Nonetheless, it may contain some useful example code so has been left here for now.
45 ///
46 /// You can see bare bones examples of the more modern region module system in OpenSim/Region/OptionalModules/Example
47 /// </remarks>
37 public class RegionModule : IRegionModule 48 public class RegionModule : IRegionModule
38 { 49 {
39 #region IRegionModule Members 50 #region IRegionModule Members
diff --git a/OpenSim/Region/Framework/Interfaces/IRestartModule.cs b/OpenSim/Region/Framework/Interfaces/IRestartModule.cs
new file mode 100644
index 0000000..c68550f
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRestartModule.cs
@@ -0,0 +1,39 @@
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 OpenMetaverse;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 public interface IRestartModule
34 {
35 TimeSpan TimeUntilRestart { get; }
36 void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice);
37 void AbortRestart(string message);
38 }
39}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 1a5cb7e..2904ee8 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -9,5 +9,6 @@ namespace OpenSim.Region.Framework.Interfaces
9 { 9 {
10 string GetUserName(UUID uuid); 10 string GetUserName(UUID uuid);
11 void AddUser(UUID uuid, string userData); 11 void AddUser(UUID uuid, string userData);
12 void AddUser(UUID uuid, string firstName, string lastName, string profileURL);
12 } 13 }
13} 14}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 06f8ac1..2cf0ced 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -416,6 +416,10 @@ namespace OpenSim.Region.Framework.Scenes
416 416
417 if ((item != null) && (item.Owner == senderId)) 417 if ((item != null) && (item.Owner == senderId))
418 { 418 {
419 IUserManagement uman = RequestModuleInterface<IUserManagement>();
420 if (uman != null)
421 uman.AddUser(item.CreatorIdAsUuid, item.CreatorData);
422
419 if (!Permissions.BypassPermissions()) 423 if (!Permissions.BypassPermissions())
420 { 424 {
421 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 425 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 55fca9b..fcfb4d7 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -893,60 +893,6 @@ namespace OpenSim.Region.Framework.Scenes
893 return new GridRegion(RegionInfo); 893 return new GridRegion(RegionInfo);
894 } 894 }
895 895
896 /// <summary>
897 /// Given float seconds, this will restart the region.
898 /// </summary>
899 /// <param name="seconds">float indicating duration before restart.</param>
900 public virtual void Restart(float seconds)
901 {
902 // notifications are done in 15 second increments
903 // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
904 // It's a 'Cancel restart' request.
905
906 // RestartNow() does immediate restarting.
907 if (seconds < 15)
908 {
909 m_restartTimer.Stop();
910 m_dialogModule.SendGeneralAlert("Restart Aborted");
911 }
912 else
913 {
914 // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
915 m_restartTimer.Interval = 15000;
916 m_incrementsof15seconds = (int)seconds / 15;
917 m_RestartTimerCounter = 0;
918 m_restartTimer.AutoReset = true;
919 m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
920 m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
921 m_restartTimer.Start();
922 m_dialogModule.SendNotificationToUsersInRegion(
923 UUID.Random(), String.Empty, RegionInfo.RegionName + String.Format(": Restarting in {0} Minutes", (int)(seconds / 60.0)));
924 }
925 }
926
927 // The Restart timer has occured.
928 // We have to figure out if this is a notification or if the number of seconds specified in Restart
929 // have elapsed.
930 // If they have elapsed, call RestartNow()
931 public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
932 {
933 m_RestartTimerCounter++;
934 if (m_RestartTimerCounter <= m_incrementsof15seconds)
935 {
936 if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
937 m_dialogModule.SendNotificationToUsersInRegion(
938 UUID.Random(),
939 String.Empty,
940 RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter) * 15) + " seconds");
941 }
942 else
943 {
944 m_restartTimer.Stop();
945 m_restartTimer.AutoReset = false;
946 RestartNow();
947 }
948 }
949
950 // This causes the region to restart immediatley. 896 // This causes the region to restart immediatley.
951 public void RestartNow() 897 public void RestartNow()
952 { 898 {
@@ -969,7 +915,8 @@ namespace OpenSim.Region.Framework.Scenes
969 Close(); 915 Close();
970 916
971 m_log.Error("[REGION]: Firing Region Restart Message"); 917 m_log.Error("[REGION]: Firing Region Restart Message");
972 base.Restart(0); 918
919 base.Restart();
973 } 920 }
974 921
975 // This is a helper function that notifies root agents in this region that a new sim near them has come up 922 // This is a helper function that notifies root agents in this region that a new sim near them has come up
@@ -2050,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes
2050 /// <param name="group">Object Id</param> 1997 /// <param name="group">Object Id</param>
2051 /// <param name="silent">Suppress broadcasting changes to other clients.</param> 1998 /// <param name="silent">Suppress broadcasting changes to other clients.</param>
2052 public void DeleteSceneObject(SceneObjectGroup group, bool silent) 1999 public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2053 { 2000 {
2054// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); 2001// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2055 2002
2056 //SceneObjectPart rootPart = group.GetChildPart(group.UUID); 2003 //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@@ -2091,7 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes
2091 2038
2092 group.DeleteGroupFromScene(silent); 2039 group.DeleteGroupFromScene(silent);
2093 2040
2094// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); 2041// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2095 } 2042 }
2096 2043
2097 /// <summary> 2044 /// <summary>
@@ -2110,9 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes
2110 // Force a database update so that the scene object group ID is accurate. It's possible that the 2057 // Force a database update so that the scene object group ID is accurate. It's possible that the
2111 // group has recently been delinked from another group but that this change has not been persisted 2058 // group has recently been delinked from another group but that this change has not been persisted
2112 // to the DB. 2059 // to the DB.
2113 ForceSceneObjectBackup(so); 2060 // This is an expensive thing to do so only do it if absolutely necessary.
2061 if (so.HasGroupChangedDueToDelink)
2062 ForceSceneObjectBackup(so);
2063
2114 so.DetachFromBackup(); 2064 so.DetachFromBackup();
2115 SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); 2065 SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
2116 } 2066 }
2117 2067
2118 // We need to keep track of this state in case this group is still queued for further backup. 2068 // We need to keep track of this state in case this group is still queued for further backup.
@@ -2377,16 +2327,14 @@ namespace OpenSim.Region.Framework.Scenes
2377 m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); 2327 m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
2378 return false; 2328 return false;
2379 } 2329 }
2380 2330
2381 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 2); 2331 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2382 2332
2383 newObject.ResumeScripts(); 2333 newObject.ResumeScripts();
2384 2334
2385 // Do this as late as possible so that listeners have full access to the incoming object 2335 // Do this as late as possible so that listeners have full access to the incoming object
2386 EventManager.TriggerOnIncomingSceneObject(newObject); 2336 EventManager.TriggerOnIncomingSceneObject(newObject);
2387 2337
2388 TriggerChangedTeleport(newObject);
2389
2390 return true; 2338 return true;
2391 } 2339 }
2392 2340
@@ -2494,7 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes
2494 return true; 2442 return true;
2495 } 2443 }
2496 2444
2497 private void TriggerChangedTeleport(SceneObjectGroup sog) 2445 private int GetStateSource(SceneObjectGroup sog)
2498 { 2446 {
2499 ScenePresence sp = GetScenePresence(sog.OwnerID); 2447 ScenePresence sp = GetScenePresence(sog.OwnerID);
2500 2448
@@ -2505,13 +2453,12 @@ namespace OpenSim.Region.Framework.Scenes
2505 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) 2453 if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default))
2506 { 2454 {
2507 // This will get your attention 2455 // This will get your attention
2508 //m_log.Error("[XXX] Triggering "); 2456 //m_log.Error("[XXX] Triggering CHANGED_TELEPORT");
2509 2457
2510 // Trigger CHANGED_TELEPORT 2458 return 5; // StateSource.Teleporting
2511 sp.Scene.EventManager.TriggerOnScriptChangedEvent(sog.LocalId, (uint)Changed.TELEPORT);
2512 } 2459 }
2513
2514 } 2460 }
2461 return 2; // StateSource.PrimCrossing
2515 } 2462 }
2516 2463
2517 #endregion 2464 #endregion
@@ -2616,6 +2563,7 @@ namespace OpenSim.Region.Framework.Scenes
2616 } 2563 }
2617 else 2564 else
2618 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); 2565 m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
2566
2619 } 2567 }
2620 } 2568 }
2621 2569
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index c71aefa..f343bc8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -218,18 +218,6 @@ namespace OpenSim.Region.Framework.Scenes
218 218
219 #region admin stuff 219 #region admin stuff
220 220
221 /// <summary>
222 /// Region Restart - Seconds till restart.
223 /// </summary>
224 /// <param name="seconds"></param>
225 public virtual void Restart(int seconds)
226 {
227 m_log.Error("[REGION]: passing Restart Message up the namespace");
228 restart handlerPhysicsCrash = OnRestart;
229 if (handlerPhysicsCrash != null)
230 handlerPhysicsCrash(RegionInfo);
231 }
232
233 public virtual bool PresenceChildStatus(UUID avatarID) 221 public virtual bool PresenceChildStatus(UUID avatarID)
234 { 222 {
235 return false; 223 return false;
@@ -562,6 +550,14 @@ namespace OpenSim.Region.Framework.Scenes
562 get { return false; } 550 get { return false; }
563 } 551 }
564 552
553 public void Restart()
554 {
555 // This has to be here to fire the event
556 restart handlerPhysicsCrash = OnRestart;
557 if (handlerPhysicsCrash != null)
558 handlerPhysicsCrash(RegionInfo);
559 }
560
565 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep); 561 public abstract bool CheckClient(UUID agentID, System.Net.IPEndPoint ep);
566 } 562 }
567} 563}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4ec530e..f17fb28 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -119,10 +119,19 @@ namespace OpenSim.Region.Framework.Scenes
119 timeFirstChanged = DateTime.Now.Ticks; 119 timeFirstChanged = DateTime.Now.Ticks;
120 } 120 }
121 m_hasGroupChanged = value; 121 m_hasGroupChanged = value;
122
123// m_log.DebugFormat(
124// "[SCENE OBJECT GROUP]: HasGroupChanged set to {0} for {1} {2}", m_hasGroupChanged, Name, LocalId);
122 } 125 }
123 126
124 get { return m_hasGroupChanged; } 127 get { return m_hasGroupChanged; }
125 } 128 }
129
130 /// <summary>
131 /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since
132 /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation.
133 /// </summary>
134 public bool HasGroupChangedDueToDelink { get; private set; }
126 135
127 private bool isTimeToPersist() 136 private bool isTimeToPersist()
128 { 137 {
@@ -1330,6 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes
1330 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; 1339 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
1331 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; 1340 backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
1332 HasGroupChanged = false; 1341 HasGroupChanged = false;
1342 HasGroupChangedDueToDelink = false;
1333 1343
1334 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); 1344 m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this);
1335 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); 1345 datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID);
@@ -2208,8 +2218,9 @@ namespace OpenSim.Region.Framework.Scenes
2208 2218
2209 linkPart.Rezzed = RootPart.Rezzed; 2219 linkPart.Rezzed = RootPart.Rezzed;
2210 2220
2211 //HasGroupChanged = true; 2221 // When we delete a group, we currently have to force persist to the database if the object id has changed
2212 //ScheduleGroupForFullUpdate(); 2222 // (since delete works by deleting all rows which have a given object id)
2223 objectGroup.HasGroupChangedDueToDelink = true;
2213 2224
2214 return objectGroup; 2225 return objectGroup;
2215 } 2226 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ba592c4..f87056e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -449,7 +449,10 @@ namespace OpenSim.Region.Framework.Scenes
449 } 449 }
450 } 450 }
451 451
452 public string CreatorData // = <profile url>;<name> 452 /// <summary>
453 /// Data about the creator in the form profile_url;name
454 /// </summary>
455 public string CreatorData
453 { 456 {
454 get { return m_creatorData; } 457 get { return m_creatorData; }
455 set { m_creatorData = value; } 458 set { m_creatorData = value; }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4526a59..d88526f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -445,8 +445,36 @@ namespace OpenSim.Region.Framework.Scenes
445 PhysicsActor actor = m_physicsActor; 445 PhysicsActor actor = m_physicsActor;
446 if (actor != null) 446 if (actor != null)
447 m_pos = actor.Position; 447 m_pos = actor.Position;
448 else
449 {
450 // Obtain the correct position of a seated avatar.
451 // In addition to providing the correct position while
452 // the avatar is seated, this value will also
453 // be used as the location to unsit to.
454 //
455 // If m_parentID is not 0, assume we are a seated avatar
456 // and we should return the position based on the sittarget
457 // offset and rotation of the prim we are seated on.
458 //
459 // Generally, m_pos will contain the position of the avatar
460 // in the sim unless the avatar is on a sit target. While
461 // on a sit target, m_pos will contain the desired offset
462 // without the parent rotation applied.
463 if (m_parentID != 0)
464 {
465 SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID);
466 if (part != null)
467 {
468 return m_parentPosition + (m_pos * part.GetWorldRotation());
469 }
470 else
471 {
472 return m_parentPosition + m_pos;
473 }
474 }
475 }
448 476
449 return m_parentPosition + m_pos; 477 return m_pos;
450 } 478 }
451 set 479 set
452 { 480 {
@@ -703,7 +731,9 @@ namespace OpenSim.Region.Framework.Scenes
703 // Note: This won't send data *to* other clients in that region (children don't send) 731 // Note: This won't send data *to* other clients in that region (children don't send)
704 732
705// MIC: This gets called again in CompleteMovement 733// MIC: This gets called again in CompleteMovement
706 SendInitialFullUpdateToAllClients(); 734 // SendInitialFullUpdateToAllClients();
735 SendOtherAgentsAvatarDataToMe();
736 SendOtherAgentsAppearanceToMe();
707 737
708 RegisterToEvents(); 738 RegisterToEvents();
709 SetDirectionVectors(); 739 SetDirectionVectors();
@@ -1613,7 +1643,7 @@ namespace OpenSim.Region.Framework.Scenes
1613 { 1643 {
1614 AbsolutePosition = part.AbsolutePosition; 1644 AbsolutePosition = part.AbsolutePosition;
1615 Velocity = Vector3.Zero; 1645 Velocity = Vector3.Zero;
1616 SendFullUpdateToAllClients(); 1646 SendAvatarDataToAllAgents();
1617 1647
1618 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); 1648 //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID);
1619 } 1649 }
@@ -1688,7 +1718,7 @@ namespace OpenSim.Region.Framework.Scenes
1688 m_parentPosition = Vector3.Zero; 1718 m_parentPosition = Vector3.Zero;
1689 1719
1690 m_parentID = 0; 1720 m_parentID = 0;
1691 SendFullUpdateToAllClients(); 1721 SendAvatarDataToAllAgents();
1692 m_requestedSitTargetID = 0; 1722 m_requestedSitTargetID = 0;
1693 if (m_physicsActor != null && m_appearance != null) 1723 if (m_physicsActor != null && m_appearance != null)
1694 { 1724 {
@@ -2154,7 +2184,7 @@ namespace OpenSim.Region.Framework.Scenes
2154 RemoveFromPhysicalScene(); 2184 RemoveFromPhysicalScene();
2155 2185
2156 Animator.TrySetMovementAnimation(sitAnimation); 2186 Animator.TrySetMovementAnimation(sitAnimation);
2157 SendFullUpdateToAllClients(); 2187 SendAvatarDataToAllAgents();
2158 // This may seem stupid, but Our Full updates don't send avatar rotation :P 2188 // This may seem stupid, but Our Full updates don't send avatar rotation :P
2159 // So we're also sending a terse update (which has avatar rotation) 2189 // So we're also sending a terse update (which has avatar rotation)
2160 // [Update] We do now. 2190 // [Update] We do now.
@@ -2379,165 +2409,183 @@ namespace OpenSim.Region.Framework.Scenes
2379 } 2409 }
2380 2410
2381 /// <summary> 2411 /// <summary>
2382 /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) 2412 /// Do everything required once a client completes its movement into a region and becomes
2413 /// a root agent.
2383 /// </summary> 2414 /// </summary>
2384 /// <param name="remoteAvatar"></param> 2415 private void SendInitialData()
2385 public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar)
2386 { 2416 {
2387 // 2 stage check is needed. 2417 // Moved this into CompleteMovement to ensure that m_appearance is initialized before
2388 if (remoteAvatar == null) 2418 // the inventory arrives
2389 return; 2419 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2390
2391 IClientAPI cl = remoteAvatar.ControllingClient;
2392 if (cl == null)
2393 return;
2394
2395 if (m_appearance.Texture == null)
2396 return;
2397 2420
2398// MT: This is needed for sit. It's legal to send it to oneself, and the name 2421 bool cachedappearance = false;
2399// of the method is a misnomer
2400//
2401// if (LocalId == remoteAvatar.LocalId)
2402// {
2403// m_log.WarnFormat("[SCENEPRESENCE]: An agent is attempting to send avatar data to itself; {0}", UUID);
2404// return;
2405// }
2406 2422
2407 if (IsChildAgent) 2423 // We have an appearance but we may not have the baked textures. Check the asset cache
2424 // to see if all the baked textures are already here.
2425 if (m_scene.AvatarFactory != null)
2408 { 2426 {
2409 m_log.WarnFormat("[SCENEPRESENCE]: A child agent is attempting to send out avatar data; {0}", UUID); 2427 cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient);
2410 return; 2428 }
2429 else
2430 {
2431 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name);
2411 } 2432 }
2412 2433
2413 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); 2434 // If we aren't using a cached appearance, then clear out the baked textures
2414 m_scene.StatsReporter.AddAgentUpdates(1); 2435 if (! cachedappearance)
2436 {
2437 m_appearance.ResetAppearance();
2438 if (m_scene.AvatarFactory != null)
2439 m_scene.AvatarFactory.QueueAppearanceSave(UUID);
2440 }
2441
2442 // This agent just became root. We are going to tell everyone about it. The process of
2443 // getting other avatars information was initiated in the constructor... don't do it
2444 // again here... this comes after the cached appearance check because the avatars
2445 // appearance goes into the avatar update packet
2446 SendAvatarDataToAllAgents();
2447 SendAppearanceToAgent(this);
2448
2449 // If we are using the the cached appearance then send it out to everyone
2450 if (cachedappearance)
2451 {
2452 m_log.InfoFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
2453
2454 // If the avatars baked textures are all in the cache, then we have a
2455 // complete appearance... send it out, if not, then we'll send it when
2456 // the avatar finishes updating its appearance
2457 SendAppearanceToAllOtherAgents();
2458 }
2415 } 2459 }
2416 2460
2417 /// <summary> 2461 /// <summary>
2418 /// Tell *ALL* agents about this agent 2462 /// Send this agent's avatar data to all other root and child agents in the scene
2463 /// This agent must be root. This avatar will receive its own update.
2419 /// </summary> 2464 /// </summary>
2420 public void SendInitialFullUpdateToAllClients() 2465 public void SendAvatarDataToAllAgents()
2421 { 2466 {
2422 m_perfMonMS = Util.EnvironmentTickCount(); 2467 // only send update from root agents to other clients; children are only "listening posts"
2423 int avUpdates = 0; 2468 if (IsChildAgent)
2424 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
2425 { 2469 {
2426 ++avUpdates; 2470 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
2427 2471 return;
2428 // Don't update ourselves 2472 }
2429 if (avatar.LocalId == LocalId) 2473
2430 return; 2474 m_perfMonMS = Util.EnvironmentTickCount();
2431
2432 // If this is a root agent, then get info about the avatar
2433 if (!IsChildAgent)
2434 {
2435 SendFullUpdateToOtherClient(avatar);
2436 }
2437 2475
2438 // If the other avatar is a root 2476 int count = 0;
2439 if (!avatar.IsChildAgent) 2477 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2440 { 2478 {
2441 avatar.SendFullUpdateToOtherClient(this); 2479 SendAvatarDataToAgent(scenePresence);
2442 avatar.SendAppearanceToOtherAgent(this); 2480 count++;
2443 avatar.Animator.SendAnimPackToClient(ControllingClient); 2481 });
2444 }
2445 });
2446 2482
2447 m_scene.StatsReporter.AddAgentUpdates(avUpdates); 2483 m_scene.StatsReporter.AddAgentUpdates(count);
2448 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2484 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2449
2450 //Animator.SendAnimPack();
2451 } 2485 }
2452 2486
2453 public void SendFullUpdateToAllClients() 2487 /// <summary>
2488 /// Send avatar data for all other root agents to this agent, this agent
2489 /// can be either a child or root
2490 /// </summary>
2491 public void SendOtherAgentsAvatarDataToMe()
2454 { 2492 {
2455 m_perfMonMS = Util.EnvironmentTickCount(); 2493 m_perfMonMS = Util.EnvironmentTickCount();
2456 2494
2457 // only send update from root agents to other clients; children are only "listening posts"
2458 if (IsChildAgent)
2459 {
2460 m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent");
2461 return;
2462 }
2463
2464 int count = 0; 2495 int count = 0;
2465 m_scene.ForEachScenePresence(delegate(ScenePresence sp) 2496 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2466 { 2497 {
2467 if (sp.IsChildAgent) 2498 // only send information about root agents
2468 return; 2499 if (scenePresence.IsChildAgent)
2469 SendFullUpdateToOtherClient(sp); 2500 return;
2470 ++count; 2501
2471 }); 2502 // only send information about other root agents
2503 if (scenePresence.UUID == UUID)
2504 return;
2505
2506 scenePresence.SendAvatarDataToAgent(this);
2507 count++;
2508 });
2509
2472 m_scene.StatsReporter.AddAgentUpdates(count); 2510 m_scene.StatsReporter.AddAgentUpdates(count);
2473 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2511 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2474
2475 Animator.SendAnimPack();
2476 } 2512 }
2477 2513
2478 /// <summary> 2514 /// <summary>
2479 /// Do everything required once a client completes its movement into a region 2515 /// Send avatar data to an agent.
2480 /// </summary> 2516 /// </summary>
2481 public void SendInitialData() 2517 /// <param name="avatar"></param>
2518 public void SendAvatarDataToAgent(ScenePresence avatar)
2482 { 2519 {
2483 // Moved this into CompleteMovement to ensure that m_appearance is initialized before 2520// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2484 // the inventory arrives
2485 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2486 2521
2487 m_controllingClient.SendAvatarDataImmediate(this); 2522 avatar.ControllingClient.SendAvatarDataImmediate(this);
2488 if (m_scene.AvatarFactory != null) 2523 Animator.SendAnimPackToClient(avatar.ControllingClient);
2489 { 2524 }
2490 if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) 2525
2491 { 2526 /// <summary>
2492// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2527 /// Send this agent's appearance to all other root and child agents in the scene
2493 m_controllingClient.SendAppearance( 2528 /// This agent must be root.
2494 m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); 2529 /// </summary>
2495 } 2530 public void SendAppearanceToAllOtherAgents()
2496 } 2531 {
2497 else 2532 // only send update from root agents to other clients; children are only "listening posts"
2533 if (IsChildAgent)
2498 { 2534 {
2499 m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); 2535 m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent");
2536 return;
2500 } 2537 }
2538
2539 m_perfMonMS = Util.EnvironmentTickCount();
2501 2540
2502 SendInitialFullUpdateToAllClients(); 2541 int count = 0;
2542 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2543 {
2544 if (scenePresence.UUID == UUID)
2545 return;
2546
2547 SendAppearanceToAgent(scenePresence);
2548 count++;
2549 });
2550
2551 m_scene.StatsReporter.AddAgentUpdates(count);
2552 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2503 } 2553 }
2504 2554
2505 /// <summary> 2555 /// <summary>
2506 /// 2556 /// Send appearance from all other root agents to this agent. this agent
2557 /// can be either root or child
2507 /// </summary> 2558 /// </summary>
2508 public void SendAppearanceToAllOtherAgents() 2559 public void SendOtherAgentsAppearanceToMe()
2509 { 2560 {
2510// DEBUG ON
2511// m_log.WarnFormat("[SCENEPRESENCE]: Send appearance from {0} to all other agents", m_uuid);
2512// DEBUG OFF
2513 m_perfMonMS = Util.EnvironmentTickCount(); 2561 m_perfMonMS = Util.EnvironmentTickCount();
2514 2562
2563 int count = 0;
2515 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2564 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2516 { 2565 {
2517 if (scenePresence.UUID != UUID) 2566 // only send information about root agents
2518 { 2567 if (scenePresence.IsChildAgent)
2519 SendAppearanceToOtherAgent(scenePresence); 2568 return;
2520 } 2569
2570 // only send information about other root agents
2571 if (scenePresence.UUID == UUID)
2572 return;
2573
2574 scenePresence.SendAppearanceToAgent(this);
2575 count++;
2521 }); 2576 });
2522 2577
2578 m_scene.StatsReporter.AddAgentUpdates(count);
2523 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2579 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2524 } 2580 }
2525 2581
2526 /// <summary> 2582 /// <summary>
2527 /// Send appearance data to an agent that isn't this one. 2583 /// Send appearance data to an agent.
2528 /// </summary> 2584 /// </summary>
2529 /// <param name="avatar"></param> 2585 /// <param name="avatar"></param>
2530 public void SendAppearanceToOtherAgent(ScenePresence avatar) 2586 public void SendAppearanceToAgent(ScenePresence avatar)
2531 { 2587 {
2532 if (LocalId == avatar.LocalId)
2533 {
2534 m_log.WarnFormat("[SCENE PRESENCE]: An agent is attempting to send appearance data to itself; {0}", UUID);
2535 return;
2536 }
2537
2538// DEBUG ON
2539// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); 2588// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2540// DEBUG OFF
2541 2589
2542 avatar.ControllingClient.SendAppearance( 2590 avatar.ControllingClient.SendAppearance(
2543 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 2591 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
@@ -3050,9 +3098,6 @@ namespace OpenSim.Region.Framework.Scenes
3050 3098
3051 public void CopyFrom(AgentData cAgent) 3099 public void CopyFrom(AgentData cAgent)
3052 { 3100 {
3053// DEBUG ON
3054 m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
3055// DEBUG OFF
3056 m_originRegionID = cAgent.RegionID; 3101 m_originRegionID = cAgent.RegionID;
3057 3102
3058 m_callbackURI = cAgent.CallbackURI; 3103 m_callbackURI = cAgent.CallbackURI;
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 9cf5a39..6c9826f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -409,12 +409,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
409 #region SOPXmlProcessors 409 #region SOPXmlProcessors
410 private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) 410 private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader)
411 { 411 {
412 obj.AllowedDrop = reader.ReadElementContentAsBoolean("AllowedDrop", String.Empty); 412 obj.AllowedDrop = Util.ReadBoolean(reader);
413 } 413 }
414 414
415 private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) 415 private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader)
416 { 416 {
417 obj.CreatorID = ReadUUID(reader, "CreatorID"); 417 obj.CreatorID = Util.ReadUUID(reader, "CreatorID");
418 } 418 }
419 419
420 private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader) 420 private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader)
@@ -424,7 +424,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
424 424
425 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader) 425 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader)
426 { 426 {
427 obj.FolderID = ReadUUID(reader, "FolderID"); 427 obj.FolderID = Util.ReadUUID(reader, "FolderID");
428 } 428 }
429 429
430 private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader) 430 private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader)
@@ -439,7 +439,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
439 439
440 private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader) 440 private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader)
441 { 441 {
442 obj.UUID = ReadUUID(reader, "UUID"); 442 obj.UUID = Util.ReadUUID(reader, "UUID");
443 } 443 }
444 444
445 private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader) 445 private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader)
@@ -459,7 +459,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
459 459
460 private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader) 460 private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader)
461 { 461 {
462 obj.PassTouches = reader.ReadElementContentAsBoolean("PassTouches", String.Empty); 462 obj.PassTouches = Util.ReadBoolean(reader);
463 } 463 }
464 464
465 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) 465 private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader)
@@ -474,32 +474,32 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
474 474
475 private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader) 475 private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader)
476 { 476 {
477 obj.GroupPosition = ReadVector(reader, "GroupPosition"); 477 obj.GroupPosition = Util.ReadVector(reader, "GroupPosition");
478 } 478 }
479 479
480 private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader) 480 private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader)
481 { 481 {
482 obj.OffsetPosition = ReadVector(reader, "OffsetPosition"); ; 482 obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ;
483 } 483 }
484 484
485 private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader) 485 private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader)
486 { 486 {
487 obj.RotationOffset = ReadQuaternion(reader, "RotationOffset"); 487 obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset");
488 } 488 }
489 489
490 private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader) 490 private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader)
491 { 491 {
492 obj.Velocity = ReadVector(reader, "Velocity"); 492 obj.Velocity = Util.ReadVector(reader, "Velocity");
493 } 493 }
494 494
495 private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader) 495 private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader)
496 { 496 {
497 obj.AngularVelocity = ReadVector(reader, "AngularVelocity"); 497 obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity");
498 } 498 }
499 499
500 private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) 500 private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader)
501 { 501 {
502 obj.Acceleration = ReadVector(reader, "Acceleration"); 502 obj.Acceleration = Util.ReadVector(reader, "Acceleration");
503 } 503 }
504 504
505 private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader) 505 private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader)
@@ -553,7 +553,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
553 553
554 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) 554 private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
555 { 555 {
556 obj.Scale = ReadVector(reader, "Scale"); 556 obj.Scale = Util.ReadVector(reader, "Scale");
557 } 557 }
558 558
559 private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) 559 private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader)
@@ -563,22 +563,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
563 563
564 private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader) 564 private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader)
565 { 565 {
566 obj.SitTargetOrientation = ReadQuaternion(reader, "SitTargetOrientation"); 566 obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation");
567 } 567 }
568 568
569 private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader) 569 private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader)
570 { 570 {
571 obj.SitTargetPosition = ReadVector(reader, "SitTargetPosition"); 571 obj.SitTargetPosition = Util.ReadVector(reader, "SitTargetPosition");
572 } 572 }
573 573
574 private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader) 574 private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader)
575 { 575 {
576 obj.SitTargetPositionLL = ReadVector(reader, "SitTargetPositionLL"); 576 obj.SitTargetPositionLL = Util.ReadVector(reader, "SitTargetPositionLL");
577 } 577 }
578 578
579 private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader) 579 private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader)
580 { 580 {
581 obj.SitTargetOrientationLL = ReadQuaternion(reader, "SitTargetOrientationLL"); 581 obj.SitTargetOrientationLL = Util.ReadQuaternion(reader, "SitTargetOrientationLL");
582 } 582 }
583 583
584 private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader) 584 private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader)
@@ -614,17 +614,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
614 614
615 private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader) 615 private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader)
616 { 616 {
617 obj.GroupID = ReadUUID(reader, "GroupID"); 617 obj.GroupID = Util.ReadUUID(reader, "GroupID");
618 } 618 }
619 619
620 private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader) 620 private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader)
621 { 621 {
622 obj.OwnerID = ReadUUID(reader, "OwnerID"); 622 obj.OwnerID = Util.ReadUUID(reader, "OwnerID");
623 } 623 }
624 624
625 private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader) 625 private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader)
626 { 626 {
627 obj.LastOwnerID = ReadUUID(reader, "LastOwnerID"); 627 obj.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
628 } 628 }
629 629
630 private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader) 630 private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader)
@@ -654,16 +654,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
654 654
655 private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader) 655 private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader)
656 { 656 {
657 string value = reader.ReadElementContentAsString("Flags", String.Empty); 657 obj.Flags = Util.ReadEnum<PrimFlags>(reader, "Flags");
658 // !!!!! to deal with flags without commas
659 if (value.Contains(" ") && !value.Contains(","))
660 value = value.Replace(" ", ", ");
661 obj.Flags = (PrimFlags)Enum.Parse(typeof(PrimFlags), value);
662 } 658 }
663 659
664 private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader) 660 private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader)
665 { 661 {
666 obj.CollisionSound = ReadUUID(reader, "CollisionSound"); 662 obj.CollisionSound = Util.ReadUUID(reader, "CollisionSound");
667 } 663 }
668 664
669 private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader) 665 private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader)
@@ -690,7 +686,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
690 #region TaskInventoryXmlProcessors 686 #region TaskInventoryXmlProcessors
691 private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader) 687 private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader)
692 { 688 {
693 item.AssetID = ReadUUID(reader, "AssetID"); 689 item.AssetID = Util.ReadUUID(reader, "AssetID");
694 } 690 }
695 691
696 private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader) 692 private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -705,7 +701,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
705 701
706 private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader) 702 private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader)
707 { 703 {
708 item.CreatorID = ReadUUID(reader, "CreatorID"); 704 item.CreatorID = Util.ReadUUID(reader, "CreatorID");
709 } 705 }
710 706
711 private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader) 707 private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader)
@@ -730,7 +726,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
730 726
731 private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader) 727 private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader)
732 { 728 {
733 item.GroupID = ReadUUID(reader, "GroupID"); 729 item.GroupID = Util.ReadUUID(reader, "GroupID");
734 } 730 }
735 731
736 private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader) 732 private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -745,20 +741,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
745 741
746 private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader) 742 private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader)
747 { 743 {
748 item.ItemID = ReadUUID(reader, "ItemID"); 744 item.ItemID = Util.ReadUUID(reader, "ItemID");
749 } 745 }
750 746
751 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) 747 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader)
752 { 748 {
753 ReadUUID(reader, "OldItemID"); 749 Util.ReadUUID(reader, "OldItemID");
754 // On deserialization, the old item id MUST BE UUID.Zero!!!!! 750 // On deserialization, the old item id MUST BE UUID.Zero!!!!!
755 // Setting this to the saved value will BREAK script persistence! 751 // Setting this to the saved value will BREAK script persistence!
756 // item.OldItemID = ReadUUID(reader, "OldItemID"); 752 // item.OldItemID = Util.ReadUUID(reader, "OldItemID");
757 } 753 }
758 754
759 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) 755 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader)
760 { 756 {
761 item.LastOwnerID = ReadUUID(reader, "LastOwnerID"); 757 item.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID");
762 } 758 }
763 759
764 private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader) 760 private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader)
@@ -773,7 +769,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
773 769
774 private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader) 770 private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader)
775 { 771 {
776 item.OwnerID = ReadUUID(reader, "OwnerID"); 772 item.OwnerID = Util.ReadUUID(reader, "OwnerID");
777 } 773 }
778 774
779 private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader) 775 private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader)
@@ -783,17 +779,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
783 779
784 private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader) 780 private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader)
785 { 781 {
786 item.ParentID = ReadUUID(reader, "ParentID"); 782 item.ParentID = Util.ReadUUID(reader, "ParentID");
787 } 783 }
788 784
789 private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader) 785 private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader)
790 { 786 {
791 item.ParentPartID = ReadUUID(reader, "ParentPartID"); 787 item.ParentPartID = Util.ReadUUID(reader, "ParentPartID");
792 } 788 }
793 789
794 private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader) 790 private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader)
795 { 791 {
796 item.PermsGranter = ReadUUID(reader, "PermsGranter"); 792 item.PermsGranter = Util.ReadUUID(reader, "PermsGranter");
797 } 793 }
798 794
799 private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader) 795 private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader)
@@ -808,7 +804,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
808 804
809 private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader) 805 private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader)
810 { 806 {
811 item.OwnerChanged = reader.ReadElementContentAsBoolean("OwnerChanged", String.Empty); 807 item.OwnerChanged = Util.ReadBoolean(reader);
812 } 808 }
813 809
814 #endregion 810 #endregion
@@ -922,7 +918,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
922 918
923 private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader) 919 private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader)
924 { 920 {
925 shp.Scale = ReadVector(reader, "Scale"); 921 shp.Scale = Util.ReadVector(reader, "Scale");
926 } 922 }
927 923
928 private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader) 924 private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -932,25 +928,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
932 928
933 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) 929 private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader)
934 { 930 {
935 string value = reader.ReadElementContentAsString("ProfileShape", String.Empty); 931 shp.ProfileShape = Util.ReadEnum<ProfileShape>(reader, "ProfileShape");
936 // !!!!! to deal with flags without commas
937 if (value.Contains(" ") && !value.Contains(","))
938 value = value.Replace(" ", ", ");
939 shp.ProfileShape = (ProfileShape)Enum.Parse(typeof(ProfileShape), value);
940 } 932 }
941 933
942 private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader) 934 private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader)
943 { 935 {
944 string value = reader.ReadElementContentAsString("HollowShape", String.Empty); 936 shp.HollowShape = Util.ReadEnum<HollowShape>(reader, "HollowShape");
945 // !!!!! to deal with flags without commas
946 if (value.Contains(" ") && !value.Contains(","))
947 value = value.Replace(" ", ", ");
948 shp.HollowShape = (HollowShape)Enum.Parse(typeof(HollowShape), value);
949 } 937 }
950 938
951 private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader) 939 private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader)
952 { 940 {
953 shp.SculptTexture = ReadUUID(reader, "SculptTexture"); 941 shp.SculptTexture = Util.ReadUUID(reader, "SculptTexture");
954 } 942 }
955 943
956 private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader) 944 private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -1045,17 +1033,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1045 1033
1046 private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1034 private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1047 { 1035 {
1048 shp.FlexiEntry = reader.ReadElementContentAsBoolean("FlexiEntry", String.Empty); 1036 shp.FlexiEntry = Util.ReadBoolean(reader);
1049 } 1037 }
1050 1038
1051 private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1039 private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1052 { 1040 {
1053 shp.LightEntry = reader.ReadElementContentAsBoolean("LightEntry", String.Empty); 1041 shp.LightEntry = Util.ReadBoolean(reader);
1054 } 1042 }
1055 1043
1056 private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader) 1044 private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader)
1057 { 1045 {
1058 shp.SculptEntry = reader.ReadElementContentAsBoolean("SculptEntry", String.Empty); 1046 shp.SculptEntry = Util.ReadBoolean(reader);
1059 } 1047 }
1060 1048
1061 private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader) 1049 private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader)
@@ -1220,16 +1208,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1220 1208
1221 static void WriteFlags(XmlTextWriter writer, string name, string flagsStr, Dictionary<string, object> options) 1209 static void WriteFlags(XmlTextWriter writer, string name, string flagsStr, Dictionary<string, object> options)
1222 { 1210 {
1223 // Older versions of serialization can't cope with commas 1211 // Older versions of serialization can't cope with commas, so we eliminate the commas
1224 if (options.ContainsKey("version")) 1212 writer.WriteElementString(name, flagsStr.Replace(",", ""));
1225 {
1226 float version = 0.5F;
1227 float.TryParse(options["version"].ToString(), out version);
1228 if (version < 0.5)
1229 flagsStr = flagsStr.Replace(",", "");
1230 }
1231
1232 writer.WriteElementString(name, flagsStr);
1233 } 1213 }
1234 1214
1235 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene) 1215 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene)
@@ -1459,66 +1439,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1459 return obj; 1439 return obj;
1460 } 1440 }
1461 1441
1462 static UUID ReadUUID(XmlTextReader reader, string name)
1463 {
1464 UUID id;
1465 string idStr;
1466
1467 reader.ReadStartElement(name);
1468
1469 if (reader.Name == "Guid")
1470 idStr = reader.ReadElementString("Guid");
1471 else // UUID
1472 idStr = reader.ReadElementString("UUID");
1473
1474 UUID.TryParse(idStr, out id);
1475 reader.ReadEndElement();
1476
1477 return id;
1478 }
1479
1480 static Vector3 ReadVector(XmlTextReader reader, string name)
1481 {
1482 Vector3 vec;
1483
1484 reader.ReadStartElement(name);
1485 vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // X or x
1486 vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Y or y
1487 vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Z or z
1488 reader.ReadEndElement();
1489
1490 return vec;
1491 }
1492
1493 static Quaternion ReadQuaternion(XmlTextReader reader, string name)
1494 {
1495 Quaternion quat = new Quaternion();
1496
1497 reader.ReadStartElement(name);
1498 while (reader.NodeType != XmlNodeType.EndElement)
1499 {
1500 switch (reader.Name.ToLower())
1501 {
1502 case "x":
1503 quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1504 break;
1505 case "y":
1506 quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1507 break;
1508 case "z":
1509 quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1510 break;
1511 case "w":
1512 quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
1513 break;
1514 }
1515 }
1516
1517 reader.ReadEndElement();
1518
1519 return quat;
1520 }
1521
1522 static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name) 1442 static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name)
1523 { 1443 {
1524 TaskInventoryDictionary tinv = new TaskInventoryDictionary(); 1444 TaskInventoryDictionary tinv = new TaskInventoryDictionary();
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index f57cf98..b84298f 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -121,13 +121,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
121 "Not exactly sure what this is asserting..."); 121 "Not exactly sure what this is asserting...");
122 122
123 // Delink part 2 123 // Delink part 2
124 grp1.DelinkFromGroup(part2.LocalId); 124 SceneObjectGroup grp3 = grp1.DelinkFromGroup(part2.LocalId);
125 125
126 if (debugtest) 126 if (debugtest)
127 m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); 127 m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset);
128 128
129 Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink."); 129 Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink.");
130 Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero"); 130 Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero");
131 Assert.That(grp3.HasGroupChangedDueToDelink, Is.True);
131 } 132 }
132 133
133 [Test] 134 [Test]
@@ -325,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
325 326
326 SceneObjectGroup sog = new SceneObjectGroup(rootPart); 327 SceneObjectGroup sog = new SceneObjectGroup(rootPart);
327 sog.AddPart(linkPart); 328 sog.AddPart(linkPart);
328 scene.AddNewSceneObject(sog, true); 329 scene.AddNewSceneObject(sog, true);
329 330
330 // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked 331 // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked
331 // scene backup thread. 332 // scene backup thread.
@@ -333,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
333 334
334 // These changes should occur immediately without waiting for a backup pass 335 // These changes should occur immediately without waiting for a backup pass
335 SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false); 336 SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false);
337
338 Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.True);
336 scene.DeleteSceneObject(groupToDelete, false); 339 scene.DeleteSceneObject(groupToDelete, false);
340 Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.False);
337 341
338 List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); 342 List<SceneObjectGroup> storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID);
339 343
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index aee2d10..3978a7d 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -86,23 +86,33 @@ namespace OpenSim.Region.Framework.Scenes
86 /// <param name="assetUuids">The assets gathered</param> 86 /// <param name="assetUuids">The assets gathered</param>
87 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids) 87 public void GatherAssetUuids(UUID assetUuid, AssetType assetType, IDictionary<UUID, AssetType> assetUuids)
88 { 88 {
89 assetUuids[assetUuid] = assetType; 89 try
90 90 {
91 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType) 91 assetUuids[assetUuid] = assetType;
92 { 92
93 GetWearableAssetUuids(assetUuid, assetUuids); 93 if (AssetType.Bodypart == assetType || AssetType.Clothing == assetType)
94 } 94 {
95 else if (AssetType.Gesture == assetType) 95 GetWearableAssetUuids(assetUuid, assetUuids);
96 { 96 }
97 GetGestureAssetUuids(assetUuid, assetUuids); 97 else if (AssetType.Gesture == assetType)
98 } 98 {
99 else if (AssetType.LSLText == assetType) 99 GetGestureAssetUuids(assetUuid, assetUuids);
100 { 100 }
101 GetScriptAssetUuids(assetUuid, assetUuids); 101 else if (AssetType.LSLText == assetType)
102 {
103 GetScriptAssetUuids(assetUuid, assetUuids);
104 }
105 else if (AssetType.Object == assetType)
106 {
107 GetSceneObjectAssetUuids(assetUuid, assetUuids);
108 }
102 } 109 }
103 else if (AssetType.Object == assetType) 110 catch (Exception)
104 { 111 {
105 GetSceneObjectAssetUuids(assetUuid, assetUuids); 112 m_log.ErrorFormat(
113 "[UUID GATHERER]: Failed to gather uuids for asset id {0}, type {1}",
114 assetUuid, assetType);
115 throw;
106 } 116 }
107 } 117 }
108 118
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index a583cca..e9c5453 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -132,7 +132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
132 m_FreeswitchService = ServerUtils.LoadPlugin<IFreeswitchService>(serviceDll, args); 132 m_FreeswitchService = ServerUtils.LoadPlugin<IFreeswitchService>(serviceDll, args);
133 133
134 string jsonConfig = m_FreeswitchService.GetJsonConfig(); 134 string jsonConfig = m_FreeswitchService.GetJsonConfig();
135 m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig); 135 //m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig);
136 OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig); 136 OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig);
137 137
138 m_freeSwitchAPIPrefix = map["APIPrefix"].AsString(); 138 m_freeSwitchAPIPrefix = map["APIPrefix"].AsString();
@@ -363,8 +363,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
363 363
364 try 364 try
365 { 365 {
366 m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", 366 //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
367 request, path, param); 367 // request, path, param);
368 368
369 //XmlElement resp; 369 //XmlElement resp;
370 string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); 370 string agentname = "x" + Convert.ToBase64String(agentID.GetBytes());
@@ -445,8 +445,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
445 // voice channel 445 // voice channel
446 LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 446 LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
447 447
448 m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", 448 //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
449 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); 449 // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
450 450
451 // TODO: EstateSettings don't seem to get propagated... 451 // TODO: EstateSettings don't seem to get propagated...
452 // if (!scene.RegionInfo.EstateSettings.AllowVoice) 452 // if (!scene.RegionInfo.EstateSettings.AllowVoice)
@@ -592,7 +592,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
592 592
593 response["int_response_code"] = 200; 593 response["int_response_code"] = 200;
594 594
595 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]); 595 //m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler return {0}",response["str_response_string"]);
596 return response; 596 return response;
597 } 597 }
598 598
@@ -664,7 +664,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
664 response["str_response_string"] = resp.ToString(); 664 response["str_response_string"] = resp.ToString();
665 Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); 665 Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
666 666
667 m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); 667 //m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],""));
668 return response; 668 return response;
669 } 669 }
670 670
@@ -696,8 +696,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
696 } 696 }
697 } 697 }
698 698
699 m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, 699 //m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype,
700 requestbody); 700 // requestbody);
701 Hashtable response = new Hashtable(); 701 Hashtable response = new Hashtable();
702 response["str_response_string"] = string.Format(@"<response xsi:schemaLocation=""/xsd/signin.xsd""> 702 response["str_response_string"] = string.Format(@"<response xsi:schemaLocation=""/xsd/signin.xsd"">
703 <level0> 703 <level0>
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 0c8113e..ccf5289 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -1173,10 +1173,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1173 presence = scene.GetScenePresence(AgentID); 1173 presence = scene.GetScenePresence(AgentID);
1174 if (presence != null) 1174 if (presence != null)
1175 { 1175 {
1176 presence.Grouptitle = Title; 1176 if (presence.Grouptitle != Title)
1177 {
1178 presence.Grouptitle = Title;
1177 1179
1178 // FixMe: Ter suggests a "Schedule" method that I can't find. 1180 if (! presence.IsChildAgent)
1179 presence.SendFullUpdateToAllClients(); 1181 presence.SendAvatarDataToAllAgents();
1182 }
1180 } 1183 }
1181 } 1184 }
1182 } 1185 }
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
new file mode 100644
index 0000000..7d37135
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesNonShared/BareBonesNonSharedModule.cs
@@ -0,0 +1,86 @@
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.Reflection;
30using log4net;
31using Mono.Addins;
32using Nini.Config;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35
36namespace OpenSim.Region.OptionalModules.Example.BareBonesNonShared
37{
38 /// <summary>
39 /// Simplest possible example of a non-shared region module.
40 /// </summary>
41 /// <remarks>
42 /// This module is the simplest possible example of a non-shared region module (a module where each scene/region
43 /// in the simulator has its own copy). If anybody wants to create a more complex example in the future then
44 /// please create a separate class.
45 ///
46 /// This module is not active by default. If you want to see it in action,
47 /// then just uncomment the line below starting with [Extension(Path...
48 ///
49 /// When the module is enabled it will print messages when it receives certain events to the screen and the log
50 /// file.
51 /// </remarks>
52 //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BareBonesNonSharedModule")]
53 public class BareBonesNonSharedModule : INonSharedRegionModule
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 public string Name { get { return "Bare Bones Non Shared Module"; } }
58
59 public Type ReplaceableInterface { get { return null; } }
60
61 public void Initialise(IConfigSource source)
62 {
63 m_log.DebugFormat("[BARE BONES NON SHARED]: INITIALIZED MODULE");
64 }
65
66 public void Close()
67 {
68 m_log.DebugFormat("[BARE BONES NON SHARED]: CLOSED MODULE");
69 }
70
71 public void AddRegion(Scene scene)
72 {
73 m_log.DebugFormat("[BARE BONES NON SHARED]: REGION {0} ADDED", scene.RegionInfo.RegionName);
74 }
75
76 public void RemoveRegion(Scene scene)
77 {
78 m_log.DebugFormat("[BARE BONES NON SHARED]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
79 }
80
81 public void RegionLoaded(Scene scene)
82 {
83 m_log.DebugFormat("[BARE BONES NON SHARED]: REGION {0} LOADED", scene.RegionInfo.RegionName);
84 }
85 }
86} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
new file mode 100644
index 0000000..781fe95
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Example/BareBonesShared/BareBonesSharedModule.cs
@@ -0,0 +1,91 @@
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.Reflection;
30using log4net;
31using Mono.Addins;
32using Nini.Config;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35
36namespace OpenSim.Region.OptionalModules.Example.BareBonesShared
37{
38 /// <summary>
39 /// Simplest possible example of a shared region module.
40 /// </summary>
41 /// <remarks>
42 /// This module is the simplest possible example of a shared region module (a module which is shared by every
43 /// scene/region running on the simulator). If anybody wants to create a more complex example in the future then
44 /// please create a separate class.
45 ///
46 /// This module is not active by default. If you want to see it in action,
47 /// then just uncomment the line below starting with [Extension(Path...
48 ///
49 /// When the module is enabled it will print messages when it receives certain events to the screen and the log
50 /// file.
51 /// </remarks>
52 //[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BareBonesSharedModule")]
53 public class BareBonesSharedModule : ISharedRegionModule
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 public string Name { get { return "Bare Bones Shared Module"; } }
58
59 public Type ReplaceableInterface { get { return null; } }
60
61 public void Initialise(IConfigSource source)
62 {
63 m_log.DebugFormat("[BARE BONES SHARED]: INITIALIZED MODULE");
64 }
65
66 public void PostInitialise()
67 {
68 m_log.DebugFormat("[BARE BONES SHARED]: POST INITIALIZED MODULE");
69 }
70
71 public void Close()
72 {
73 m_log.DebugFormat("[BARE BONES SHARED]: CLOSED MODULE");
74 }
75
76 public void AddRegion(Scene scene)
77 {
78 m_log.DebugFormat("[BARE BONES SHARED]: REGION {0} ADDED", scene.RegionInfo.RegionName);
79 }
80
81 public void RemoveRegion(Scene scene)
82 {
83 m_log.DebugFormat("[BARE BONES SHARED]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
84 }
85
86 public void RegionLoaded(Scene scene)
87 {
88 m_log.DebugFormat("[BARE BONES SHARED]: REGION {0} LOADED", scene.RegionInfo.RegionName);
89 }
90 }
91} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index d770ad1..3386e72 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -276,7 +276,7 @@ namespace OpenSim.Region.Physics.Meshing
276 276
277 m_log.Debug("[MESH]: experimental mesh proxy generation"); 277 m_log.Debug("[MESH]: experimental mesh proxy generation");
278 278
279 OSD meshOsd; 279 OSD meshOsd = null;
280 280
281 if (primShape.SculptData.Length <= 0) 281 if (primShape.SculptData.Length <= 0)
282 { 282 {
@@ -287,7 +287,14 @@ namespace OpenSim.Region.Physics.Meshing
287 long start = 0; 287 long start = 0;
288 using (MemoryStream data = new MemoryStream(primShape.SculptData)) 288 using (MemoryStream data = new MemoryStream(primShape.SculptData))
289 { 289 {
290 meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data); 290 try
291 {
292 meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data);
293 }
294 catch (Exception e)
295 {
296 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
297 }
291 start = data.Position; 298 start = data.Position;
292 } 299 }
293 300
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 0c99d8c..8b7871b 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -42,7 +42,8 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
42 NewRez = 1, 42 NewRez = 1,
43 PrimCrossing = 2, 43 PrimCrossing = 2,
44 ScriptedRez = 3, 44 ScriptedRez = 3,
45 AttachedRez = 4 45 AttachedRez = 4,
46 Teleporting = 5
46 } 47 }
47 48
48 public interface IScriptWorkItem 49 public interface IScriptWorkItem
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index d06b134..3c5f2d0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7759,24 +7759,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 break; 7759 break;
7760 7760
7761 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 7761 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7762 // TODO--------------
7763 if (remain < 1) 7762 if (remain < 1)
7764 return res; 7763 return res;
7765 7764
7766 face=(int)rules.GetLSLIntegerItem(idx++); 7765 face=(int)rules.GetLSLIntegerItem(idx++);
7767 7766
7768 res.Add(new LSL_Integer(0)); 7767 tex = part.Shape.Textures;
7769 res.Add(new LSL_Integer(0)); 7768 if (face == ScriptBaseClass.ALL_SIDES)
7769 {
7770 for (face = 0; face < GetNumberOfSides(part); face++)
7771 {
7772 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7773 // Convert Shininess to PRIM_SHINY_*
7774 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7775 // PRIM_BUMP_*
7776 res.Add(new LSL_Integer((int)texface.Bump));
7777 }
7778 }
7779 else
7780 {
7781 if (face >= 0 && face < GetNumberOfSides(part))
7782 {
7783 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7784 // Convert Shininess to PRIM_SHINY_*
7785 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7786 // PRIM_BUMP_*
7787 res.Add(new LSL_Integer((int)texface.Bump));
7788 }
7789 }
7770 break; 7790 break;
7771 7791
7772 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 7792 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7773 // TODO--------------
7774 if (remain < 1) 7793 if (remain < 1)
7775 return res; 7794 return res;
7776 7795
7777 face=(int)rules.GetLSLIntegerItem(idx++); 7796 face=(int)rules.GetLSLIntegerItem(idx++);
7778 7797
7779 res.Add(new LSL_Integer(0)); 7798 tex = part.Shape.Textures;
7799 if (face == ScriptBaseClass.ALL_SIDES)
7800 {
7801 for (face = 0; face < GetNumberOfSides(part); face++)
7802 {
7803 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7804 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7805 }
7806 }
7807 else
7808 {
7809 if (face >= 0 && face < GetNumberOfSides(part))
7810 {
7811 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7812 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7813 }
7814 }
7780 break; 7815 break;
7781 7816
7782 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 7817 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7797,14 +7832,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7797 break; 7832 break;
7798 7833
7799 case (int)ScriptBaseClass.PRIM_TEXGEN: 7834 case (int)ScriptBaseClass.PRIM_TEXGEN:
7800 // TODO--------------
7801 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7802 if (remain < 1) 7835 if (remain < 1)
7803 return res; 7836 return res;
7804 7837
7805 face=(int)rules.GetLSLIntegerItem(idx++); 7838 face=(int)rules.GetLSLIntegerItem(idx++);
7806 7839
7807 res.Add(new LSL_Integer(0)); 7840 tex = part.Shape.Textures;
7841 if (face == ScriptBaseClass.ALL_SIDES)
7842 {
7843 for (face = 0; face < GetNumberOfSides(part); face++)
7844 {
7845 MappingType texgen = tex.GetFace((uint)face).TexMapType;
7846 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc.
7847 res.Add(new LSL_Integer((uint)texgen >> 1));
7848 }
7849 }
7850 else
7851 {
7852 if (face >= 0 && face < GetNumberOfSides(part))
7853 {
7854 MappingType texgen = tex.GetFace((uint)face).TexMapType;
7855 res.Add(new LSL_Integer((uint)texgen >> 1));
7856 }
7857 }
7808 break; 7858 break;
7809 7859
7810 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 7860 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7823,14 +7873,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7823 break; 7873 break;
7824 7874
7825 case (int)ScriptBaseClass.PRIM_GLOW: 7875 case (int)ScriptBaseClass.PRIM_GLOW:
7826 // TODO--------------
7827 if (remain < 1) 7876 if (remain < 1)
7828 return res; 7877 return res;
7829 7878
7830 face=(int)rules.GetLSLIntegerItem(idx++); 7879 face=(int)rules.GetLSLIntegerItem(idx++);
7831 7880
7832 res.Add(new LSL_Float(0)); 7881 tex = part.Shape.Textures;
7882 if (face == ScriptBaseClass.ALL_SIDES)
7883 {
7884 for (face = 0; face < GetNumberOfSides(part); face++)
7885 {
7886 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7887 res.Add(new LSL_Float(texface.Glow));
7888 }
7889 }
7890 else
7891 {
7892 if (face >= 0 && face < GetNumberOfSides(part))
7893 {
7894 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7895 res.Add(new LSL_Float(texface.Glow));
7896 }
7897 }
7833 break; 7898 break;
7899
7834 case (int)ScriptBaseClass.PRIM_TEXT: 7900 case (int)ScriptBaseClass.PRIM_TEXT:
7835 Color4 textColor = part.GetTextColor(); 7901 Color4 textColor = part.GetTextColor();
7836 res.Add(part.Text); 7902 res.Add(part.Text);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index fc92f23..827626f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -395,10 +395,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
395 // 395 //
396 CheckThreatLevel(ThreatLevel.High, "osRegionRestart"); 396 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
397 397
398 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
398 m_host.AddScriptLPS(1); 399 m_host.AddScriptLPS(1);
399 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false)) 400 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
400 { 401 {
401 World.Restart((float)seconds); 402 if (seconds < 15)
403 {
404 restartModule.AbortRestart("Restart aborted");
405 return 1;
406 }
407
408 List<int> times = new List<int>();
409 while (seconds > 0)
410 {
411 times.Add((int)seconds);
412 if (seconds > 300)
413 seconds -= 120;
414 else if (seconds > 30)
415 seconds -= 30;
416 else
417 seconds -= 15;
418 }
419
420 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
402 return 1; 421 return 1;
403 } 422 }
404 else 423 else
@@ -2315,4 +2334,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2315 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2334 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2316 } 2335 }
2317 } 2336 }
2318} \ No newline at end of file 2337}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 660e9a3..8e712b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -390,19 +390,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
390 } 390 }
391 else if (m_stateSource == StateSource.RegionStart) 391 else if (m_stateSource == StateSource.RegionStart)
392 { 392 {
393// m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); 393 //m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
394 PostEvent(new EventParams("changed", 394 PostEvent(new EventParams("changed",
395 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION_RESTART) }, 395 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION_RESTART) }, new DetectParams[0]));
396 new DetectParams[0]));
397 } 396 }
398 else if (m_stateSource == StateSource.PrimCrossing) 397 else if (m_stateSource == StateSource.PrimCrossing || m_stateSource == StateSource.Teleporting)
399 { 398 {
400 // CHANGED_REGION 399 // CHANGED_REGION
401 PostEvent(new EventParams("changed", 400 PostEvent(new EventParams("changed",
402 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION) }, 401 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION) }, new DetectParams[0]));
403 new DetectParams[0])); 402
403 // CHANGED_TELEPORT
404 if (m_stateSource == StateSource.Teleporting)
405 PostEvent(new EventParams("changed",
406 new Object[] { new LSL_Types.LSLInteger((int)Changed.TELEPORT) }, new DetectParams[0]));
404 } 407 }
405 } 408 }
406 else 409 else
407 { 410 {
408 Start(); 411 Start();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index dfc9aa3..1d55b95 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -47,6 +47,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
47 { 47 {
48 48
49 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; 49 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
50 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
50 private LSL_Api m_lslApi; 51 private LSL_Api m_lslApi;
51 52
52 [SetUp] 53 [SetUp]
@@ -164,5 +165,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
164 Assert.Greater(eulerCalc.z, eulerCheck.z - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z lower bounds check fail"); 165 Assert.Greater(eulerCalc.z, eulerCheck.z - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z lower bounds check fail");
165 Assert.Less(eulerCalc.z, eulerCheck.z + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z upper bounds check fail"); 166 Assert.Less(eulerCalc.z, eulerCheck.z + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z upper bounds check fail");
166 } 167 }
168
169 [Test]
170 // llVecNorm test.
171 public void TestllVecNorm()
172 {
173 // Check special case for normalizing zero vector.
174 CheckllVecNorm(new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), new LSL_Types.Vector3(0.0d, 0.0d, 0.0d));
175 // Check various vectors.
176 CheckllVecNorm(new LSL_Types.Vector3(10.0d, 25.0d, 0.0d), new LSL_Types.Vector3(0.371391d, 0.928477d, 0.0d));
177 CheckllVecNorm(new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), new LSL_Types.Vector3(1.0d, 0.0d, 0.0d));
178 CheckllVecNorm(new LSL_Types.Vector3(-90.0d, 55.0d, 2.0d), new LSL_Types.Vector3(-0.853128d, 0.521356d, 0.018958d));
179 CheckllVecNorm(new LSL_Types.Vector3(255.0d, 255.0d, 255.0d), new LSL_Types.Vector3(0.577350d, 0.577350d, 0.577350d));
180 }
181
182 public void CheckllVecNorm(LSL_Types.Vector3 vec, LSL_Types.Vector3 vecNormCheck)
183 {
184 // Call LSL function to normalize the vector.
185 LSL_Types.Vector3 vecNorm = m_lslApi.llVecNorm(vec);
186 // Check each vector component against expected result.
187 Assert.AreEqual(vecNorm.x, vecNormCheck.x, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on x component");
188 Assert.AreEqual(vecNorm.y, vecNormCheck.y, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on y component");
189 Assert.AreEqual(vecNorm.z, vecNormCheck.z, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on z component");
190 }
167 } 191 }
168} 192}