aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs6
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs186
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs6
-rw-r--r--OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs4
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs169
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs106
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs556
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs191
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs260
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs100
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs59
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs421
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs211
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs227
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs454
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs85
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs7
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs12
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs20
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs355
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs76
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs119
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs148
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs624
56 files changed, 3143 insertions, 1781 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index f56d17d..1e14f45 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
152 } 152 }
153 } 153 }
154 154
155 public void RequestCreateInventoryItem(IClientAPI remoteClient, 155 public bool RequestCreateInventoryItem(IClientAPI remoteClient,
156 UUID transactionID, UUID folderID, uint callbackID, 156 UUID transactionID, UUID folderID, uint callbackID,
157 string description, string name, sbyte invType, 157 string description, string name, sbyte invType,
158 sbyte type, byte wearableType, uint nextOwnerMask) 158 sbyte type, byte wearableType, uint nextOwnerMask)
@@ -162,6 +162,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
162 uploader.RequestCreateInventoryItem( 162 uploader.RequestCreateInventoryItem(
163 remoteClient, folderID, callbackID, 163 remoteClient, folderID, callbackID,
164 description, name, invType, type, wearableType, nextOwnerMask); 164 description, name, invType, type, wearableType, nextOwnerMask);
165
166 return true;
165 } 167 }
166 168
167 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, 169 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
@@ -181,4 +183,4 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
181 uploader.RequestUpdateInventoryItem(remoteClient, item); 183 uploader.RequestUpdateInventoryItem(remoteClient, item);
182 } 184 }
183 } 185 }
184} \ No newline at end of file 186}
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index b67c0df..f489262 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
158 /// <param name="type"></param> 158 /// <param name="type"></param>
159 /// <param name="wearableType"></param> 159 /// <param name="wearableType"></param>
160 /// <param name="nextOwnerMask"></param> 160 /// <param name="nextOwnerMask"></param>
161 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, 161 public bool HandleItemCreationFromTransaction(IClientAPI remoteClient,
162 UUID transactionID, UUID folderID, uint callbackID, 162 UUID transactionID, UUID folderID, uint callbackID,
163 string description, string name, sbyte invType, 163 string description, string name, sbyte invType,
164 sbyte type, byte wearableType, uint nextOwnerMask) 164 sbyte type, byte wearableType, uint nextOwnerMask)
@@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
169 AgentAssetTransactions transactions = 169 AgentAssetTransactions transactions =
170 GetUserTransactions(remoteClient.AgentId); 170 GetUserTransactions(remoteClient.AgentId);
171 171
172 transactions.RequestCreateInventoryItem(remoteClient, transactionID, 172 return transactions.RequestCreateInventoryItem(remoteClient, transactionID,
173 folderID, callbackID, description, name, invType, type, 173 folderID, callbackID, description, name, invType, type,
174 wearableType, nextOwnerMask); 174 wearableType, nextOwnerMask);
175 } 175 }
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 5e772e6..ffff37d 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Reflection; 30using System.Reflection;
31using System.Collections.Generic;
31using log4net; 32using log4net;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -39,6 +40,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
39{ 40{
40 public class AssetXferUploader 41 public class AssetXferUploader
41 { 42 {
43 // Viewer's notion of the default texture
44 private List<UUID> defaultIDs = new List<UUID> {
45 new UUID("5748decc-f629-461c-9a36-a35a221fe21f"),
46 new UUID("7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"),
47 new UUID("6522e74d-1660-4e7f-b601-6f48c1659a77"),
48 new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97")
49 };
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 51
44 /// <summary> 52 /// <summary>
@@ -86,6 +94,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
86 94
87 private sbyte type = 0; 95 private sbyte type = 0;
88 private byte wearableType = 0; 96 private byte wearableType = 0;
97 private byte[] m_oldData = null;
89 public ulong XferID; 98 public ulong XferID;
90 private Scene m_Scene; 99 private Scene m_Scene;
91 100
@@ -128,18 +137,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
128 137
129 if (XferID == xferID) 138 if (XferID == xferID)
130 { 139 {
131 if (m_asset.Data.Length > 1) 140 lock (this)
132 { 141 {
133 byte[] destinationArray = new byte[m_asset.Data.Length + data.Length]; 142 int assetLength = m_asset.Data.Length;
134 Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length); 143 int dataLength = data.Length;
135 Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length); 144
136 m_asset.Data = destinationArray; 145 if (m_asset.Data.Length > 1)
137 } 146 {
138 else 147 byte[] destinationArray = new byte[assetLength + dataLength];
139 { 148 Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
140 byte[] buffer2 = new byte[data.Length - 4]; 149 Array.Copy(data, 0, destinationArray, assetLength, dataLength);
141 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 150 m_asset.Data = destinationArray;
142 m_asset.Data = buffer2; 151 }
152 else
153 {
154 if (dataLength > 4)
155 {
156 byte[] buffer2 = new byte[dataLength - 4];
157 Array.Copy(data, 4, buffer2, 0, dataLength - 4);
158 m_asset.Data = buffer2;
159 }
160 }
143 } 161 }
144 162
145 ourClient.SendConfirmXfer(xferID, packetID); 163 ourClient.SendConfirmXfer(xferID, packetID);
@@ -243,10 +261,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
243 { 261 {
244 CompleteTaskItemUpdate(m_updateTaskItemData); 262 CompleteTaskItemUpdate(m_updateTaskItemData);
245 } 263 }
246// else if (m_storeLocal) 264 else if (m_asset.Local)
247// { 265 {
248// m_Scene.AssetService.Store(m_asset); 266 m_Scene.AssetService.Store(m_asset);
249// } 267 }
250 } 268 }
251 269
252 m_log.DebugFormat( 270 m_log.DebugFormat(
@@ -374,6 +392,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
374// m_asset.FullID, item.Name, ourClient.Name); 392// m_asset.FullID, item.Name, ourClient.Name);
375 393
376 m_Scene.AssetService.Store(m_asset); 394 m_Scene.AssetService.Store(m_asset);
395 if (m_asset.FullID != UUID.Zero)
396 {
397 item.AssetID = m_asset.FullID;
398 m_Scene.InventoryService.UpdateItem(item);
399 }
377 400
378 m_transactions.RemoveXferUploader(m_transactionID); 401 m_transactions.RemoveXferUploader(m_transactionID);
379 } 402 }
@@ -395,6 +418,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
395 418
396 private void CompleteCreateItem(uint callbackID) 419 private void CompleteCreateItem(uint callbackID)
397 { 420 {
421 ValidateAssets();
398 m_Scene.AssetService.Store(m_asset); 422 m_Scene.AssetService.Store(m_asset);
399 423
400 InventoryItemBase item = new InventoryItemBase(); 424 InventoryItemBase item = new InventoryItemBase();
@@ -415,6 +439,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
415 item.Flags = (uint) wearableType; 439 item.Flags = (uint) wearableType;
416 item.CreationDate = Util.UnixTimeSinceEpoch(); 440 item.CreationDate = Util.UnixTimeSinceEpoch();
417 441
442 m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
443 item.ID, item.AssetID);
444
418 if (m_Scene.AddInventoryItem(item)) 445 if (m_Scene.AddInventoryItem(item))
419 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 446 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
420 else 447 else
@@ -422,5 +449,132 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
422 449
423 m_transactions.RemoveXferUploader(m_transactionID); 450 m_transactions.RemoveXferUploader(m_transactionID);
424 } 451 }
452
453 private void ValidateAssets()
454 {
455 if (m_asset.Type == (sbyte)AssetType.Clothing ||
456 m_asset.Type == (sbyte)AssetType.Bodypart)
457 {
458 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
459 string[] lines = content.Split(new char[] {'\n'});
460
461 List<string> validated = new List<string>();
462
463 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
464
465 int textures = 0;
466
467 foreach (string line in lines)
468 {
469 try
470 {
471 if (line.StartsWith("textures "))
472 {
473 textures = Convert.ToInt32(line.Substring(9));
474 validated.Add(line);
475 }
476 else if (textures > 0)
477 {
478 string[] parts = line.Split(new char[] {' '});
479
480 UUID tx = new UUID(parts[1]);
481 int id = Convert.ToInt32(parts[0]);
482
483 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
484 (allowed.ContainsKey(id) && allowed[id] == tx))
485 {
486 validated.Add(parts[0] + " " + tx.ToString());
487 }
488 else
489 {
490 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
491 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
492
493 if ((perms & full) != full)
494 {
495 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
496 validated.Add(parts[0] + " " + UUID.Zero.ToString());
497 }
498 else
499 {
500 validated.Add(line);
501 }
502 }
503 textures--;
504 }
505 else
506 {
507 validated.Add(line);
508 }
509 }
510 catch
511 {
512 // If it's malformed, skip it
513 }
514 }
515
516 string final = String.Join("\n", validated.ToArray());
517
518 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
519 }
520 }
521
522 /// <summary>
523 /// Get the asset data uploaded in this transfer.
524 /// </summary>
525 /// <returns>null if the asset has not finished uploading</returns>
526 public AssetBase GetAssetData()
527 {
528 if (m_uploadState == UploadState.Complete)
529 {
530 ValidateAssets();
531 return m_asset;
532 }
533
534 return null;
535 }
536
537 public void SetOldData(byte[] d)
538 {
539 m_oldData = d;
540 }
541
542 private Dictionary<int,UUID> ExtractTexturesFromOldData()
543 {
544 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
545 if (m_oldData == null)
546 return result;
547
548 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
549 string[] lines = content.Split(new char[] {'\n'});
550
551 int textures = 0;
552
553 foreach (string line in lines)
554 {
555 try
556 {
557 if (line.StartsWith("textures "))
558 {
559 textures = Convert.ToInt32(line.Substring(9));
560 }
561 else if (textures > 0)
562 {
563 string[] parts = line.Split(new char[] {' '});
564
565 UUID tx = new UUID(parts[1]);
566 int id = Convert.ToInt32(parts[0]);
567 result[id] = tx;
568 textures--;
569 }
570 }
571 catch
572 {
573 // If it's malformed, skip it
574 }
575 }
576
577 return result;
578 }
425 } 579 }
426} \ No newline at end of file 580}
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index 4299726..7113f4f 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -160,6 +160,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
160 { 160 {
161 byte[] fileData = NewFiles[fileName].Data; 161 byte[] fileData = NewFiles[fileName].Data;
162 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 162 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
163 if (fileName.StartsWith("inventory_"))
164 transaction.isTaskInventory = true;
163 165
164 Transfers.Add(xferID, transaction); 166 Transfers.Add(xferID, transaction);
165 167
@@ -243,6 +245,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
243 public uint Packet = 0; 245 public uint Packet = 0;
244 public uint Serial = 1; 246 public uint Serial = 1;
245 public ulong XferID = 0; 247 public ulong XferID = 0;
248 public bool isTaskInventory = false;
246 249
247 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) 250 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
248 { 251 {
@@ -268,7 +271,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
268 byte[] transferData = new byte[Data.Length + 4]; 271 byte[] transferData = new byte[Data.Length + 4];
269 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 272 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
270 Array.Copy(Data, 0, transferData, 4, Data.Length); 273 Array.Copy(Data, 0, transferData, 4, Data.Length);
271 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); 274 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData, isTaskInventory);
272 complete = true; 275 complete = true;
273 } 276 }
274 else 277 else
@@ -276,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
276 byte[] transferData = new byte[1000 + 4]; 279 byte[] transferData = new byte[1000 + 4];
277 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 280 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
278 Array.Copy(Data, 0, transferData, 4, 1000); 281 Array.Copy(Data, 0, transferData, 4, 1000);
279 Client.SendXferPacket(XferID, 0, transferData); 282 Client.SendXferPacket(XferID, 0, transferData, isTaskInventory);
280 Packet++; 283 Packet++;
281 DataPointer = 1000; 284 DataPointer = 1000;
282 } 285 }
@@ -297,7 +300,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
297 { 300 {
298 byte[] transferData = new byte[1000]; 301 byte[] transferData = new byte[1000];
299 Array.Copy(Data, DataPointer, transferData, 0, 1000); 302 Array.Copy(Data, DataPointer, transferData, 0, 1000);
300 Client.SendXferPacket(XferID, Packet, transferData); 303 Client.SendXferPacket(XferID, Packet, transferData, isTaskInventory);
301 Packet++; 304 Packet++;
302 DataPointer += 1000; 305 DataPointer += 1000;
303 } 306 }
@@ -306,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
306 byte[] transferData = new byte[Data.Length - DataPointer]; 309 byte[] transferData = new byte[Data.Length - DataPointer];
307 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); 310 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
308 uint endPacket = Packet |= (uint) 0x80000000; 311 uint endPacket = Packet |= (uint) 0x80000000;
309 Client.SendXferPacket(XferID, endPacket, transferData); 312 Client.SendXferPacket(XferID, endPacket, transferData, isTaskInventory);
310 Packet++; 313 Packet++;
311 DataPointer += (Data.Length - DataPointer); 314 DataPointer += (Data.Length - DataPointer);
312 315
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index e40caec..f43305f 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -194,6 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset
194 194
195 #region IImprovedAssetCache Members 195 #region IImprovedAssetCache Members
196 196
197
198 public bool Check(string id)
199 {
200 return false;
201 }
202
197 /// <summary> 203 /// <summary>
198 /// Cache asset. 204 /// Cache asset.
199 /// </summary> 205 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
index 9742a5c..58ce61a 100644
--- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
@@ -112,6 +112,10 @@ namespace OpenSim.Region.CoreModules.Asset
112 //////////////////////////////////////////////////////////// 112 ////////////////////////////////////////////////////////////
113 // IImprovedAssetCache 113 // IImprovedAssetCache
114 // 114 //
115 public bool Check(string id)
116 {
117 return false;
118 }
115 119
116 public void Cache(AssetBase asset) 120 public void Cache(AssetBase asset)
117 { 121 {
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 08d4fc0..f1fee63 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -248,57 +248,70 @@ namespace OpenSim.Region.CoreModules.Asset
248 248
249 private void UpdateFileCache(string key, AssetBase asset) 249 private void UpdateFileCache(string key, AssetBase asset)
250 { 250 {
251 string filename = GetFileName(asset.ID); 251 // TODO: Spawn this off to some seperate thread to do the actual writing
252 252 if (asset != null)
253 try
254 { 253 {
255 // If the file is already cached just update access time. 254 string filename = GetFileName(key);
256 if (File.Exists(filename)) 255
257 { 256 try
258 lock (m_CurrentlyWriting)
259 {
260 if (!m_CurrentlyWriting.Contains(filename))
261 File.SetLastAccessTime(filename, DateTime.Now);
262 }
263 }
264 else
265 { 257 {
266 // Once we start writing, make sure we flag that we're writing 258 // If the file is already cached, don't cache it, just touch it so access time is updated
267 // that object to the cache so that we don't try to write the 259 if (File.Exists(filename))
268 // same file multiple times.
269 lock (m_CurrentlyWriting)
270 { 260 {
271#if WAIT_ON_INPROGRESS_REQUESTS 261 // We don't really want to know about sharing
272 if (m_CurrentlyWriting.ContainsKey(filename)) 262 // violations here. If the file is locked, then
263 // the other thread has updated the time for us.
264 try
273 { 265 {
274 return; 266 lock (m_CurrentlyWriting)
267 {
268 if (!m_CurrentlyWriting.Contains(filename))
269 File.SetLastAccessTime(filename, DateTime.Now);
270 }
275 } 271 }
276 else 272 catch
277 {
278 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
279 }
280
281#else
282 if (m_CurrentlyWriting.Contains(filename))
283 { 273 {
284 return;
285 } 274 }
286 else 275 } else {
276
277 // Once we start writing, make sure we flag that we're writing
278 // that object to the cache so that we don't try to write the
279 // same file multiple times.
280 lock (m_CurrentlyWriting)
287 { 281 {
288 m_CurrentlyWriting.Add(filename); 282#if WAIT_ON_INPROGRESS_REQUESTS
289 } 283 if (m_CurrentlyWriting.ContainsKey(filename))
284 {
285 return;
286 }
287 else
288 {
289 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
290 }
291
292#else
293 if (m_CurrentlyWriting.Contains(filename))
294 {
295 return;
296 }
297 else
298 {
299 m_CurrentlyWriting.Add(filename);
300 }
290#endif 301#endif
291 }
292 302
293 Util.FireAndForget( 303 }
294 delegate { WriteFileCache(filename, asset); }); 304
305 Util.FireAndForget(
306 delegate { WriteFileCache(filename, asset); });
307 }
308 }
309 catch (Exception e)
310 {
311 m_log.ErrorFormat(
312 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
313 asset.ID, e.Message, e.StackTrace);
295 } 314 }
296 }
297 catch (Exception e)
298 {
299 m_log.WarnFormat(
300 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
301 asset.ID, e.Message, e.StackTrace);
302 } 315 }
303 } 316 }
304 317
@@ -332,6 +345,17 @@ namespace OpenSim.Region.CoreModules.Asset
332 return asset; 345 return asset;
333 } 346 }
334 347
348 private bool CheckFromMemoryCache(string id)
349 {
350 AssetBase asset = null;
351
352 if (m_MemoryCache.TryGetValue(id, out asset))
353 return true;
354
355 return false;
356 }
357
358
335 /// <summary> 359 /// <summary>
336 /// Try to get an asset from the file cache. 360 /// Try to get an asset from the file cache.
337 /// </summary> 361 /// </summary>
@@ -396,6 +420,7 @@ namespace OpenSim.Region.CoreModules.Asset
396 m_log.WarnFormat( 420 m_log.WarnFormat(
397 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 421 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
398 filename, id, e.Message, e.StackTrace); 422 filename, id, e.Message, e.StackTrace);
423
399 } 424 }
400 finally 425 finally
401 { 426 {
@@ -407,6 +432,50 @@ namespace OpenSim.Region.CoreModules.Asset
407 return asset; 432 return asset;
408 } 433 }
409 434
435 private bool CheckFromFileCache(string id)
436 {
437 bool found = false;
438
439 string filename = GetFileName(id);
440 if (File.Exists(filename))
441 {
442 // actually check if we can open it, and so update expire
443 FileStream stream = null;
444 try
445 {
446 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
447 if (stream != null)
448 {
449 found = true;
450 stream.Close();
451 }
452
453 }
454 catch (System.Runtime.Serialization.SerializationException e)
455 {
456 found = false;
457 m_log.ErrorFormat(
458 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
459 filename, id, e.Message, e.StackTrace);
460
461 // If there was a problem deserializing the asset, the asset may
462 // either be corrupted OR was serialized under an old format
463 // {different version of AssetBase} -- we should attempt to
464 // delete it and re-cache
465 File.Delete(filename);
466 }
467 catch (Exception e)
468 {
469 found = false;
470 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
472 filename, id, e.Message, e.StackTrace);
473 }
474 }
475
476 return found;
477 }
478
410 public AssetBase Get(string id) 479 public AssetBase Get(string id)
411 { 480 {
412 m_Requests++; 481 m_Requests++;
@@ -434,11 +503,26 @@ namespace OpenSim.Region.CoreModules.Asset
434 return asset; 503 return asset;
435 } 504 }
436 505
506 public bool Check(string id)
507 {
508 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
509 return true;
510
511 if (m_FileCacheEnabled && CheckFromFileCache(id))
512 return true;
513 return false;
514 }
515
437 public AssetBase GetCached(string id) 516 public AssetBase GetCached(string id)
438 { 517 {
439 return Get(id); 518 return Get(id);
440 } 519 }
441 520
521 public AssetBase CheckCached(string id)
522 {
523 return Get(id);
524 }
525
442 public void Expire(string id) 526 public void Expire(string id)
443 { 527 {
444 if (m_LogLevel >= 2) 528 if (m_LogLevel >= 2)
@@ -983,6 +1067,11 @@ namespace OpenSim.Region.CoreModules.Asset
983 return asset.Data; 1067 return asset.Data;
984 } 1068 }
985 1069
1070 public bool CheckData(string id)
1071 {
1072 return Check(id); ;
1073 }
1074
986 public bool Get(string id, object sender, AssetRetrieved handler) 1075 public bool Get(string id, object sender, AssetRetrieved handler)
987 { 1076 {
988 AssetBase asset = Get(id); 1077 AssetBase asset = Get(id);
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
index 9592ca0..ce9b546 100644
--- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
@@ -115,6 +115,11 @@ namespace OpenSim.Region.CoreModules.Asset
115 // IImprovedAssetCache 115 // IImprovedAssetCache
116 // 116 //
117 117
118 public bool Check(string id)
119 {
120 return false;
121 }
122
118 public void Cache(AssetBase asset) 123 public void Cache(AssetBase asset)
119 { 124 {
120 if (asset != null) 125 if (asset != null)
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 1ca142e..d47ca4b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -41,6 +41,7 @@ using OpenSim.Region.Framework;
41using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Serialization; 43using OpenSim.Region.Framework.Scenes.Serialization;
44using OpenSim.Services.Interfaces;
44 45
45namespace OpenSim.Region.CoreModules.Avatar.Attachments 46namespace OpenSim.Region.CoreModules.Avatar.Attachments
46{ 47{
@@ -295,6 +296,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
295 if (DebugLevel > 0) 296 if (DebugLevel > 0)
296 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); 297 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name);
297 298
299 XmlDocument doc = new XmlDocument();
300 string stateData = String.Empty;
301
302 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
303 if (attServ != null)
304 {
305 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
306 stateData = attServ.Get(sp.UUID.ToString());
307 if (stateData != String.Empty)
308 {
309 try
310 {
311 doc.LoadXml(stateData);
312 }
313 catch { }
314 }
315 }
316
317 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
318
319 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
320 if (nodes.Count > 0)
321 {
322 foreach (XmlNode n in nodes)
323 {
324 XmlElement elem = (XmlElement)n;
325 string itemID = elem.GetAttribute("ItemID");
326 string xml = elem.InnerXml;
327
328 itemData[new UUID(itemID)] = xml;
329 }
330 }
331
332
298 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 333 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
299 foreach (AvatarAttachment attach in attachments) 334 foreach (AvatarAttachment attach in attachments)
300 { 335 {
@@ -314,10 +349,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
314 349
315 try 350 try
316 { 351 {
352 string xmlData;
353 XmlDocument d = null;
354 UUID asset;
355 if (itemData.TryGetValue(attach.ItemID, out xmlData))
356 {
357 d = new XmlDocument();
358 d.LoadXml(xmlData);
359 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID);
360 }
361
317 // If we're an NPC then skip all the item checks and manipulations since we don't have an 362 // If we're an NPC then skip all the item checks and manipulations since we don't have an
318 // inventory right now. 363 // inventory right now.
319 RezSingleAttachmentFromInventoryInternal( 364 RezSingleAttachmentFromInventoryInternal(
320 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true); 365 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d);
321 } 366 }
322 catch (Exception e) 367 catch (Exception e)
323 { 368 {
@@ -380,13 +425,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
380 sp.ClearAttachments(); 425 sp.ClearAttachments();
381 } 426 }
382 427
383 public bool AttachObject( 428 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append)
384 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append)
385 { 429 {
386 if (!Enabled) 430 if (!Enabled)
387 return false; 431 return false;
388 432
389 return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); 433 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append);
390 } 434 }
391 435
392 /// <summary> 436 /// <summary>
@@ -399,10 +443,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
399 /// <param name='silent'></param> 443 /// <param name='silent'></param>
400 /// <param name='addToInventory'>If true then add object to user inventory.</param> 444 /// <param name='addToInventory'>If true then add object to user inventory.</param>
401 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> 445 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
402 /// <param name='append'>Append to attachment point rather than replace.</param> 446 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append)
403 private bool AttachObjectInternal(
404 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append)
405 { 447 {
448// m_log.DebugFormat(
449// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
450// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
451
452 if (sp.GetAttachments().Contains(group))
453 {
454// m_log.WarnFormat(
455// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
456// group.Name, group.LocalId, sp.Name, AttachmentPt);
457
458 return false;
459 }
460
406 if (group.GetSittingAvatarsCount() != 0) 461 if (group.GetSittingAvatarsCount() != 0)
407 { 462 {
408 if (DebugLevel > 0) 463 if (DebugLevel > 0)
@@ -414,6 +469,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
414 } 469 }
415 470
416 Vector3 attachPos = group.AbsolutePosition; 471 Vector3 attachPos = group.AbsolutePosition;
472
473 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
474 // be removed when that functionality is implemented in opensim
475 attachmentPt &= 0x7f;
476
417 // If the attachment point isn't the same as the one previously used 477 // If the attachment point isn't the same as the one previously used
418 // set it's offset position = 0 so that it appears on the attachment point 478 // set it's offset position = 0 so that it appears on the attachment point
419 // and not in a weird location somewhere unknown. 479 // and not in a weird location somewhere unknown.
@@ -452,9 +512,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
452 attachPos = Vector3.Zero; 512 attachPos = Vector3.Zero;
453 } 513 }
454 514
455 group.AttachmentPoint = attachmentPt;
456 group.AbsolutePosition = attachPos;
457
458 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 515 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
459 516
460 if (attachments.Contains(group)) 517 if (attachments.Contains(group))
@@ -487,6 +544,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
487 544
488 lock (sp.AttachmentsSyncLock) 545 lock (sp.AttachmentsSyncLock)
489 { 546 {
547 group.AttachmentPoint = attachmentPt;
548 group.AbsolutePosition = attachPos;
549
490 if (addToInventory && sp.PresenceType != PresenceType.Npc) 550 if (addToInventory && sp.PresenceType != PresenceType.Npc)
491 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); 551 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
492 552
@@ -517,7 +577,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
517 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); 577 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
518 } 578 }
519 579
520 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 580 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
581 {
582 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
583 }
584
585 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
521 { 586 {
522 if (!Enabled) 587 if (!Enabled)
523 return null; 588 return null;
@@ -555,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
555 bool append = (AttachmentPt & 0x80) != 0; 620 bool append = (AttachmentPt & 0x80) != 0;
556 AttachmentPt &= 0x7f; 621 AttachmentPt &= 0x7f;
557 622
558 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); 623 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc);
559 } 624 }
560 625
561 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 626 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -620,6 +685,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
620 if (changed && m_scene.AvatarFactory != null) 685 if (changed && m_scene.AvatarFactory != null)
621 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); 686 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
622 687
688 so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint;
689
623 sp.RemoveAttachment(so); 690 sp.RemoveAttachment(so);
624 so.FromItemID = UUID.Zero; 691 so.FromItemID = UUID.Zero;
625 692
@@ -632,9 +699,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
632 so.AttachedAvatar = UUID.Zero; 699 so.AttachedAvatar = UUID.Zero;
633 rootPart.SetParentLocalId(0); 700 rootPart.SetParentLocalId(0);
634 so.ClearPartAttachmentData(); 701 so.ClearPartAttachmentData();
635 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 702 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
636 so.HasGroupChanged = true; 703 so.HasGroupChanged = true;
637 so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint;
638 rootPart.Rezzed = DateTime.Now; 704 rootPart.Rezzed = DateTime.Now;
639 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 705 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
640 so.AttachToBackup(); 706 so.AttachToBackup();
@@ -966,7 +1032,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
966 } 1032 }
967 1033
968 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 1034 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
969 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) 1035 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc)
970 { 1036 {
971 if (m_invAccessModule == null) 1037 if (m_invAccessModule == null)
972 return null; 1038 return null;
@@ -1010,7 +1076,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1010 // This will throw if the attachment fails 1076 // This will throw if the attachment fails
1011 try 1077 try
1012 { 1078 {
1013 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); 1079 if (doc != null)
1080 {
1081 objatt.LoadScriptState(doc);
1082 objatt.ResetOwnerChangeFlag();
1083 }
1084
1085 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append);
1014 } 1086 }
1015 catch (Exception e) 1087 catch (Exception e)
1016 { 1088 {
@@ -1164,7 +1236,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1164 AttachmentPt &= 0x7f; 1236 AttachmentPt &= 0x7f;
1165 1237
1166 // Calls attach with a Zero position 1238 // Calls attach with a Zero position
1167 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) 1239 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, true, append))
1168 { 1240 {
1169 if (DebugLevel > 0) 1241 if (DebugLevel > 0)
1170 m_log.Debug( 1242 m_log.Debug(
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 4e58045..f023e77 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -201,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
201 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 201 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
202 202
203 m_numberOfAttachEventsFired = 0; 203 m_numberOfAttachEventsFired = 0;
204 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); 204 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
205 205
206 // Check status on scene presence 206 // Check status on scene presence
207 Assert.That(sp.HasAttachments(), Is.True); 207 Assert.That(sp.HasAttachments(), Is.True);
@@ -248,7 +248,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
248 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); 248 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
249 249
250 m_numberOfAttachEventsFired = 0; 250 m_numberOfAttachEventsFired = 0;
251 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false); 251 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false, false);
252 252
253 // Check status on scene presence 253 // Check status on scene presence
254 Assert.That(sp.HasAttachments(), Is.True); 254 Assert.That(sp.HasAttachments(), Is.True);
@@ -281,7 +281,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
281 281
282 // Test wearing a different attachment from the ground. 282 // Test wearing a different attachment from the ground.
283 { 283 {
284 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); 284 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
285 285
286 // Check status on scene presence 286 // Check status on scene presence
287 Assert.That(sp.HasAttachments(), Is.True); 287 Assert.That(sp.HasAttachments(), Is.True);
@@ -314,7 +314,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
314 314
315 // Test rewearing an already worn attachment from ground. Nothing should happen. 315 // Test rewearing an already worn attachment from ground. Nothing should happen.
316 { 316 {
317 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); 317 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
318 318
319 // Check status on scene presence 319 // Check status on scene presence
320 Assert.That(sp.HasAttachments(), Is.True); 320 Assert.That(sp.HasAttachments(), Is.True);
@@ -372,7 +372,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
372 sp2.AbsolutePosition = new Vector3(0, 0, 0); 372 sp2.AbsolutePosition = new Vector3(0, 0, 0);
373 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 373 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
374 374
375 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); 375 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
376 376
377 Assert.That(sp.HasAttachments(), Is.False); 377 Assert.That(sp.HasAttachments(), Is.False);
378 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 378 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -667,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
667 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 667 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
668 668
669 SceneObjectGroup rezzedSo 669 SceneObjectGroup rezzedSo
670 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 670 = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
671 671
672 // Wait for chat to signal rezzed script has been started. 672 // Wait for chat to signal rezzed script has been started.
673 m_chatEvent.WaitOne(60000); 673 m_chatEvent.WaitOne(60000);
@@ -686,7 +686,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
686 Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); 686 Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
687 687
688 // Re-rez the attachment to check script running state 688 // Re-rez the attachment to check script running state
689 SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 689 SceneObjectGroup reRezzedSo = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
690 690
691 // Wait for chat to signal rezzed script has been started. 691 // Wait for chat to signal rezzed script has been started.
692 m_chatEvent.WaitOne(60000); 692 m_chatEvent.WaitOne(60000);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index aea768e..09cc998 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -145,33 +145,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
145 /// <param name="sp"></param> 145 /// <param name="sp"></param>
146 /// <param name="texture"></param> 146 /// <param name="texture"></param>
147 /// <param name="visualParam"></param> 147 /// <param name="visualParam"></param>
148 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) 148 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
149 { 149 {
150 DoSetAppearance(sp, appearance.Texture, appearance.VisualParams, new List<CachedTextureRequestArg>()); 150 SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
151 } 151 }
152 152
153 /// <summary> 153
154 /// Set appearance data (texture asset IDs and slider settings) 154 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
155 /// </summary>
156 /// <param name="sp"></param>
157 /// <param name="texture"></param>
158 /// <param name="visualParam"></param>
159 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
160 { 155 {
161 DoSetAppearance(sp, textureEntry, visualParams, new List<CachedTextureRequestArg>()); 156 float oldoff = sp.Appearance.AvatarFeetOffset;
157 Vector3 oldbox = sp.Appearance.AvatarBoxSize;
158
159 SetAppearance(sp, textureEntry, visualParams, cacheItems);
160 sp.Appearance.SetSize(avSize);
161
162 float off = sp.Appearance.AvatarFeetOffset;
163 Vector3 box = sp.Appearance.AvatarBoxSize;
164 if (oldoff != off || oldbox != box)
165 ((ScenePresence)sp).SetSize(box, off);
162 } 166 }
163 167
164 /// <summary> 168 /// <summary>
165 /// Set appearance data (texture asset IDs and slider settings) 169 /// Set appearance data (texture asset IDs and slider settings)
166 /// </summary> 170 /// </summary>
167 /// <param name="sp"></param> 171 /// <param name="sp"></param>
168 /// <param name="texture"></param> 172 /// <param name="texture"></param>
169 /// <param name="visualParam"></param> 173 /// <param name="visualParam"></param>
170 protected void DoSetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) 174 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
171 { 175 {
172 // m_log.DebugFormat( 176// m_log.DebugFormat(
173 // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 177// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
174 // sp.Name, textureEntry, visualParams); 178// sp.Name, textureEntry, visualParams);
175 179
176 // TODO: This is probably not necessary any longer, just assume the 180 // TODO: This is probably not necessary any longer, just assume the
177 // textureEntry set implies that the appearance transaction is complete 181 // textureEntry set implies that the appearance transaction is complete
@@ -190,36 +194,38 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
190 // m_log.DebugFormat( 194 // m_log.DebugFormat(
191 // "[AVFACTORY]: Setting visual params for {0} to {1}", 195 // "[AVFACTORY]: Setting visual params for {0} to {1}",
192 // client.Name, string.Join(", ", visualParamsStrings)); 196 // client.Name, string.Join(", ", visualParamsStrings));
193 197/*
194 float oldHeight = sp.Appearance.AvatarHeight; 198 float oldHeight = sp.Appearance.AvatarHeight;
195 changed = sp.Appearance.SetVisualParams(visualParams); 199 changed = sp.Appearance.SetVisualParams(visualParams);
196 200
197 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) 201 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
198 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); 202 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
199 } 203 */
204// float oldoff = sp.Appearance.AvatarFeetOffset;
205// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
206 changed = sp.Appearance.SetVisualParams(visualParams);
207// float off = sp.Appearance.AvatarFeetOffset;
208// Vector3 box = sp.Appearance.AvatarBoxSize;
209// if(oldoff != off || oldbox != box)
210// ((ScenePresence)sp).SetSize(box,off);
200 211
212 }
213
201 // Process the baked texture array 214 // Process the baked texture array
202 if (textureEntry != null) 215 if (textureEntry != null)
203 { 216 {
204 // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 217 m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
205 // WriteBakedTexturesReport(sp, m_log.DebugFormat); 218
219// WriteBakedTexturesReport(sp, m_log.DebugFormat);
206 220
207 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 221 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
208 222
209 // WriteBakedTexturesReport(sp, m_log.DebugFormat); 223// WriteBakedTexturesReport(sp, m_log.DebugFormat);
210 224
211 // If bake textures are missing and this is not an NPC, request a rebake from client 225 // If bake textures are missing and this is not an NPC, request a rebake from client
212 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) 226 if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
213 RequestRebake(sp, true); 227 RequestRebake(sp, true);
214 228
215 // Save the wearble hashes in the appearance
216 sp.Appearance.ResetTextureHashes();
217 if (m_reusetextures)
218 {
219 foreach (CachedTextureRequestArg arg in hashes)
220 sp.Appearance.SetTextureHash(arg.BakedTextureIndex,arg.WearableHashID);
221 }
222
223 // This appears to be set only in the final stage of the appearance 229 // This appears to be set only in the final stage of the appearance
224 // update transaction. In theory, we should be able to do an immediate 230 // update transaction. In theory, we should be able to do an immediate
225 // appearance send and save here. 231 // appearance send and save here.
@@ -253,13 +259,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
253 259
254 public bool SendAppearance(UUID agentId) 260 public bool SendAppearance(UUID agentId)
255 { 261 {
256 // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); 262// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
257 263
258 ScenePresence sp = m_scene.GetScenePresence(agentId); 264 ScenePresence sp = m_scene.GetScenePresence(agentId);
259 if (sp == null) 265 if (sp == null)
260 { 266 {
261 // This is expected if the user has gone away. 267 // This is expected if the user has gone away.
262 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); 268// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
263 return false; 269 return false;
264 } 270 }
265 271
@@ -277,6 +283,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
277 return GetBakedTextureFaces(sp); 283 return GetBakedTextureFaces(sp);
278 } 284 }
279 285
286 public WearableCacheItem[] GetCachedItems(UUID agentId)
287 {
288 ScenePresence sp = m_scene.GetScenePresence(agentId);
289 WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
290 //foreach (WearableCacheItem item in items)
291 //{
292
293 //}
294 return items;
295 }
296
280 public bool SaveBakedTextures(UUID agentId) 297 public bool SaveBakedTextures(UUID agentId)
281 { 298 {
282 ScenePresence sp = m_scene.GetScenePresence(agentId); 299 ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -336,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
336 /// <param name="agentId"></param> 353 /// <param name="agentId"></param>
337 public void QueueAppearanceSend(UUID agentid) 354 public void QueueAppearanceSend(UUID agentid)
338 { 355 {
339 // m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); 356// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
340 357
341 // 10000 ticks per millisecond, 1000 milliseconds per second 358 // 10000 ticks per millisecond, 1000 milliseconds per second
342 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); 359 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
@@ -349,7 +366,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
349 366
350 public void QueueAppearanceSave(UUID agentid) 367 public void QueueAppearanceSave(UUID agentid)
351 { 368 {
352 // m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid); 369// m_log.DebugFormat("[AVFACTORY]: Queueing appearance save for {0}", agentid);
353 370
354 // 10000 ticks per millisecond, 1000 milliseconds per second 371 // 10000 ticks per millisecond, 1000 milliseconds per second
355 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); 372 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
@@ -363,6 +380,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
363 public bool ValidateBakedTextureCache(IScenePresence sp) 380 public bool ValidateBakedTextureCache(IScenePresence sp)
364 { 381 {
365 bool defonly = true; // are we only using default textures 382 bool defonly = true; // are we only using default textures
383 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
384 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
385 WearableCacheItem[] wearableCache = null;
386
387 // Cache wearable data for teleport.
388 // Only makes sense if there's a bake module and a cache module
389 if (bakedModule != null && cache != null)
390 {
391 try
392 {
393 wearableCache = bakedModule.Get(sp.UUID);
394 }
395 catch (Exception)
396 {
397
398 }
399 if (wearableCache != null)
400 {
401 for (int i = 0; i < wearableCache.Length; i++)
402 {
403 cache.Cache(wearableCache[i].TextureAsset);
404 }
405 }
406 }
407 /*
408 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
409 if (invService.GetRootFolder(userID) != null)
410 {
411 WearableCacheItem[] wearableCache = null;
412 if (bakedModule != null)
413 {
414 try
415 {
416 wearableCache = bakedModule.Get(userID);
417 appearance.WearableCacheItems = wearableCache;
418 appearance.WearableCacheItemsDirty = false;
419 foreach (WearableCacheItem item in wearableCache)
420 {
421 appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID;
422 }
423 }
424 catch (Exception)
425 {
426
427 }
428 }
429 */
366 430
367 // Process the texture entry 431 // Process the texture entry
368 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 432 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@@ -370,13 +434,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
370 int idx = AvatarAppearance.BAKE_INDICES[i]; 434 int idx = AvatarAppearance.BAKE_INDICES[i];
371 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 435 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
372 436
373 // if there is no texture entry, skip it 437 // No face, so lets check our baked service cache, teleport or login.
374 if (face == null) 438 if (face == null)
375 continue; 439 {
440 if (wearableCache != null)
441 {
442 // If we find the an appearance item, set it as the textureentry and the face
443 WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache);
444 if (searchitem != null)
445 {
446 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx);
447 sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID;
448 face = sp.Appearance.Texture.FaceTextures[idx];
449 }
450 else
451 {
452 // if there is no texture entry and no baked cache, skip it
453 continue;
454 }
455 }
456 else
457 {
458 //No texture entry face and no cache. Skip this face.
459 continue;
460 }
461 }
462
376 463
377 // m_log.DebugFormat( 464// m_log.DebugFormat(
378 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 465// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
379 // face.TextureID, idx, client.Name, client.AgentId); 466// face.TextureID, idx, client.Name, client.AgentId);
380 467
381 // if the texture is one of the "defaults" then skip it 468 // if the texture is one of the "defaults" then skip it
382 // this should probably be more intelligent (skirt texture doesnt matter 469 // this should probably be more intelligent (skirt texture doesnt matter
@@ -387,11 +474,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
387 474
388 defonly = false; // found a non-default texture reference 475 defonly = false; // found a non-default texture reference
389 476
390 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 477 if (cache != null)
391 return false; 478 {
479 if (!cache.Check(face.TextureID.ToString()))
480 return false;
481 }
482 else
483 {
484 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
485 return false;
486 }
392 } 487 }
393 488
394 // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 489// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
395 490
396 // If we only found default textures, then the appearance is not cached 491 // If we only found default textures, then the appearance is not cached
397 return (defonly ? false : true); 492 return (defonly ? false : true);
@@ -400,6 +495,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
400 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) 495 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
401 { 496 {
402 int texturesRebaked = 0; 497 int texturesRebaked = 0;
498 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
403 499
404 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 500 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
405 { 501 {
@@ -410,9 +506,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
410 if (face == null) 506 if (face == null)
411 continue; 507 continue;
412 508
413 // m_log.DebugFormat( 509// m_log.DebugFormat(
414 // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 510// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
415 // face.TextureID, idx, client.Name, client.AgentId); 511// face.TextureID, idx, client.Name, client.AgentId);
416 512
417 // if the texture is one of the "defaults" then skip it 513 // if the texture is one of the "defaults" then skip it
418 // this should probably be more intelligent (skirt texture doesnt matter 514 // this should probably be more intelligent (skirt texture doesnt matter
@@ -423,21 +519,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
423 519
424 if (missingTexturesOnly) 520 if (missingTexturesOnly)
425 { 521 {
426 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 522 if (cache != null)
427 { 523 {
428 continue; 524 if (cache.Check(face.TextureID.ToString()))
525 continue;
526 else
527 {
528 m_log.DebugFormat(
529 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
530 face.TextureID, idx, sp.Name);
531 }
429 } 532 }
430 else 533 else
431 { 534 {
432 // On inter-simulator teleports, this occurs if baked textures are not being stored by the 535 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
433 // grid asset service (which means that they are not available to the new region and so have 536 {
434 // to be re-requested from the client). 537 continue;
435 // 538 }
436 // The only available core OpenSimulator behaviour right now 539
437 // is not to store these textures, temporarily or otherwise. 540 else
438 m_log.DebugFormat( 541 {
439 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 542 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
440 face.TextureID, idx, sp.Name); 543 // grid asset service (which means that they are not available to the new region and so have
544 // to be re-requested from the client).
545 //
546 // The only available core OpenSimulator behaviour right now
547 // is not to store these textures, temporarily or otherwise.
548 m_log.DebugFormat(
549 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
550 face.TextureID, idx, sp.Name);
551 }
441 } 552 }
442 } 553 }
443 else 554 else
@@ -476,9 +587,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
476 if (bakeType == BakeType.Unknown) 587 if (bakeType == BakeType.Unknown)
477 continue; 588 continue;
478 589
479 // m_log.DebugFormat( 590// m_log.DebugFormat(
480 // "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", 591// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
481 // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); 592// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
482 593
483 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); 594 int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
484 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture 595 Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture
@@ -502,7 +613,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
502 UUID avatarID = kvp.Key; 613 UUID avatarID = kvp.Key;
503 long sendTime = kvp.Value; 614 long sendTime = kvp.Value;
504 615
505 // m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); 616// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
506 617
507 if (sendTime < now) 618 if (sendTime < now)
508 { 619 {
@@ -548,11 +659,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
548 if (sp == null) 659 if (sp == null)
549 { 660 {
550 // This is expected if the user has gone away. 661 // This is expected if the user has gone away.
551 // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); 662// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
552 return; 663 return;
553 } 664 }
554 665
555 // m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid); 666// m_log.DebugFormat("[AVFACTORY]: Saving appearance for avatar {0}", agentid);
556 667
557 // This could take awhile since it needs to pull inventory 668 // This could take awhile since it needs to pull inventory
558 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape 669 // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
@@ -579,26 +690,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
579 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 690 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
580 { 691 {
581 IInventoryService invService = m_scene.InventoryService; 692 IInventoryService invService = m_scene.InventoryService;
582 693 bool resetwearable = false;
583 if (invService.GetRootFolder(userID) != null) 694 if (invService.GetRootFolder(userID) != null)
584 { 695 {
585 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 696 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
586 { 697 {
587 for (int j = 0; j < appearance.Wearables[i].Count; j++) 698 for (int j = 0; j < appearance.Wearables[i].Count; j++)
588 { 699 {
700 // Check if the default wearables are not set
589 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 701 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
702 {
703 switch ((WearableType) i)
704 {
705 case WearableType.Eyes:
706 case WearableType.Hair:
707 case WearableType.Shape:
708 case WearableType.Skin:
709 //case WearableType.Underpants:
710 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
711 resetwearable = true;
712 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
713 resetwearable = true;
714 break;
715
716 }
590 continue; 717 continue;
718 }
591 719
592 // Ignore ruth's assets 720 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
593 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 721 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
722 {
723 switch ((WearableType)i)
724 {
725 case WearableType.Eyes:
726 case WearableType.Hair:
727 case WearableType.Shape:
728 case WearableType.Skin:
729 //case WearableType.Underpants:
730 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
731
732 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
733 resetwearable = true;
734 break;
735
736 }
594 continue; 737 continue;
595 738 }
739
596 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 740 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
597 baseItem = invService.GetItem(baseItem); 741 baseItem = invService.GetItem(baseItem);
598 742
599 if (baseItem != null) 743 if (baseItem != null)
600 { 744 {
601 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 745 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
746 int unmodifiedWearableIndexForClosure = i;
747 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
748 delegate(string x, object y, AssetBase z)
749 {
750 if (z == null)
751 {
752 TryAndRepairBrokenWearable(
753 (WearableType)unmodifiedWearableIndexForClosure, invService,
754 userID, appearance);
755 }
756 });
602 } 757 }
603 else 758 else
604 { 759 {
@@ -606,17 +761,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
606 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 761 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
607 appearance.Wearables[i][j].ItemID, (WearableType)i); 762 appearance.Wearables[i][j].ItemID, (WearableType)i);
608 763
609 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 764 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
765 resetwearable = true;
766
610 } 767 }
611 } 768 }
612 } 769 }
770
771 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
772 if (appearance.Wearables[(int) WearableType.Eyes] == null)
773 {
774 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
775
776 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
777 resetwearable = true;
778 }
779 else
780 {
781 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
782 {
783 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
784 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
785 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
786 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
787 resetwearable = true;
788
789 }
790
791 }
792 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
793 if (appearance.Wearables[(int)WearableType.Shape] == null)
794 {
795 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
796
797 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
798 resetwearable = true;
799 }
800 else
801 {
802 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
803 {
804 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
805 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
806 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
807 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
808 resetwearable = true;
809
810 }
811
812 }
813 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
814 if (appearance.Wearables[(int)WearableType.Hair] == null)
815 {
816 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
817
818 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
819 resetwearable = true;
820 }
821 else
822 {
823 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
824 {
825 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
826 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
827 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
828 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
829 resetwearable = true;
830
831 }
832
833 }
834 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
835 if (appearance.Wearables[(int)WearableType.Skin] == null)
836 {
837 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
838
839 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
840 resetwearable = true;
841 }
842 else
843 {
844 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
845 {
846 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
847 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
848 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
849 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
850 resetwearable = true;
851
852 }
853
854 }
855 if (resetwearable)
856 {
857 ScenePresence presence = null;
858 if (m_scene.TryGetScenePresence(userID, out presence))
859 {
860 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
861 presence.Appearance.Serial++);
862 }
863 }
864
613 } 865 }
614 else 866 else
615 { 867 {
616 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 868 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
617 } 869 }
618 } 870 }
871 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
872 {
873 UUID defaultwearable = GetDefaultItem(type);
874 if (defaultwearable != UUID.Zero)
875 {
876 UUID newInvItem = UUID.Random();
877 InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
878 {
879 AssetID =
880 defaultwearable,
881 AssetType
882 =
883 (int)
884 AssetType
885 .Bodypart,
886 CreatorId
887 =
888 userID
889 .ToString
890 (),
891 //InvType = (int)InventoryType.Wearable,
892
893 Description
894 =
895 "Failed Wearable Replacement",
896 Folder =
897 invService
898 .GetFolderForType
899 (userID,
900 AssetType
901 .Bodypart)
902 .ID,
903 Flags = (uint) type,
904 Name = Enum.GetName(typeof (WearableType), type),
905 BasePermissions = (uint) PermissionMask.Copy,
906 CurrentPermissions = (uint) PermissionMask.Copy,
907 EveryOnePermissions = (uint) PermissionMask.Copy,
908 GroupPermissions = (uint) PermissionMask.Copy,
909 NextPermissions = (uint) PermissionMask.Copy
910 };
911 invService.AddItem(itembase);
912 UUID LinkInvItem = UUID.Random();
913 itembase = new InventoryItemBase(LinkInvItem, userID)
914 {
915 AssetID =
916 newInvItem,
917 AssetType
918 =
919 (int)
920 AssetType
921 .Link,
922 CreatorId
923 =
924 userID
925 .ToString
926 (),
927 InvType = (int) InventoryType.Wearable,
928
929 Description
930 =
931 "Failed Wearable Replacement",
932 Folder =
933 invService
934 .GetFolderForType
935 (userID,
936 AssetType
937 .CurrentOutfitFolder)
938 .ID,
939 Flags = (uint) type,
940 Name = Enum.GetName(typeof (WearableType), type),
941 BasePermissions = (uint) PermissionMask.Copy,
942 CurrentPermissions = (uint) PermissionMask.Copy,
943 EveryOnePermissions = (uint) PermissionMask.Copy,
944 GroupPermissions = (uint) PermissionMask.Copy,
945 NextPermissions = (uint) PermissionMask.Copy
946 };
947 invService.AddItem(itembase);
948 appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
949 ScenePresence presence = null;
950 if (m_scene.TryGetScenePresence(userID, out presence))
951 {
952 m_scene.SendInventoryUpdate(presence.ControllingClient,
953 invService.GetFolderForType(userID,
954 AssetType
955 .CurrentOutfitFolder),
956 false, true);
957 }
958 }
959 }
960 private UUID GetDefaultItem(WearableType wearable)
961 {
962 // These are ruth
963 UUID ret = UUID.Zero;
964 switch (wearable)
965 {
966 case WearableType.Eyes:
967 ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
968 break;
969 case WearableType.Hair:
970 ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
971 break;
972 case WearableType.Pants:
973 ret = new UUID("00000000-38f9-1111-024e-222222111120");
974 break;
975 case WearableType.Shape:
976 ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
977 break;
978 case WearableType.Shirt:
979 ret = new UUID("00000000-38f9-1111-024e-222222111110");
980 break;
981 case WearableType.Skin:
982 ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
983 break;
984 case WearableType.Undershirt:
985 ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
986 break;
987 case WearableType.Underpants:
988 ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
989 break;
990 }
619 991
992 return ret;
993 }
620 #endregion 994 #endregion
621 995
622 #region Client Event Handlers 996 #region Client Event Handlers
@@ -626,12 +1000,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
626 /// <param name="client"></param> 1000 /// <param name="client"></param>
627 private void Client_OnRequestWearables(IClientAPI client) 1001 private void Client_OnRequestWearables(IClientAPI client)
628 { 1002 {
629 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 1003 Util.FireAndForget(delegate(object x)
630 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1004 {
631 if (sp != null) 1005 Thread.Sleep(4000);
632 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1006
633 else 1007 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
634 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1008 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
1009 if (sp != null)
1010 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1011 else
1012 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1013 });
635 } 1014 }
636 1015
637 /// <summary> 1016 /// <summary>
@@ -640,12 +1019,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
640 /// <param name="client"></param> 1019 /// <param name="client"></param>
641 /// <param name="texture"></param> 1020 /// <param name="texture"></param>
642 /// <param name="visualParam"></param> 1021 /// <param name="visualParam"></param>
643 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, List<CachedTextureRequestArg> hashes) 1022 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
644 { 1023 {
645 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 1024 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
646 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1025 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
647 if (sp != null) 1026 if (sp != null)
648 DoSetAppearance(sp, textureEntry, visualParams, hashes); 1027 SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
649 else 1028 else
650 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 1029 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
651 } 1030 }
@@ -702,7 +1081,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
702 /// <param name="cachedTextureRequest"></param> 1081 /// <param name="cachedTextureRequest"></param>
703 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) 1082 private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest)
704 { 1083 {
705 // m_log.DebugFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); 1084 // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId);
706 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1085 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
707 1086
708 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); 1087 List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>();
@@ -713,20 +1092,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
713 1092
714 if (m_reusetextures) 1093 if (m_reusetextures)
715 { 1094 {
716 if (sp.Appearance.GetTextureHash(index) == request.WearableHashID) 1095 // this is the most insanely dumb way to do this... however it seems to
717 { 1096 // actually work. if the appearance has been reset because wearables have
718 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; 1097 // changed then the texture entries are zero'd out until the bakes are
719 if (face != null) 1098 // uploaded. on login, if the textures exist in the cache (eg if you logged
720 texture = face.TextureID; 1099 // into the simulator recently, then the appearance will pull those and send
721 } 1100 // them back in the packet and you won't have to rebake. if the textures aren't
722 else 1101 // in the cache then the intial makeroot() call in scenepresence will zero
723 { 1102 // them out.
724 // We know that that hash is wrong, null it out 1103 //
725 // and wait for the setappearance call 1104 // a better solution (though how much better is an open question) is to
726 sp.Appearance.SetTextureHash(index,UUID.Zero); 1105 // store the hashes in the appearance and compare them. Thats's coming.
727 } 1106
728 1107 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index];
729 // m_log.WarnFormat("[AVFACTORY]: use texture {0} for index {1}; hash={2}",texture,index,request.WearableHashID); 1108 if (face != null)
1109 texture = face.TextureID;
1110
1111 // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index);
730 } 1112 }
731 1113
732 CachedTextureResponseArg response = new CachedTextureResponseArg(); 1114 CachedTextureResponseArg response = new CachedTextureResponseArg();
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index 1830d41..f090e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
61 for (byte i = 0; i < visualParams.Length; i++) 61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i; 62 visualParams[i] = i;
63 63
64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); 64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]);
65 65
66 // TODO: Check baked texture 66 // TODO: Check baked texture
67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams); 67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
@@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); 102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
103 eyesFace.TextureID = eyesTextureId; 103 eyesFace.TextureID = eyesTextureId;
104 104
105 afm.SetAppearance(sp, bakedTextureEntry, visualParams); 105 afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]);
106 afm.SaveBakedTextures(userId); 106 afm.SaveBakedTextures(userId);
107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); 107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
108 108
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 27ace68..5cbfec6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -51,7 +51,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
51 private int m_saydistance = 20; 51 private int m_saydistance = 20;
52 private int m_shoutdistance = 100; 52 private int m_shoutdistance = 100;
53 private int m_whisperdistance = 10; 53 private int m_whisperdistance = 10;
54 54 private List<Scene> m_scenes = new List<Scene>();
55 private List<string> FreezeCache = new List<string>();
56 private string m_adminPrefix = "";
55 internal object m_syncy = new object(); 57 internal object m_syncy = new object();
56 58
57 internal IConfig m_config; 59 internal IConfig m_config;
@@ -78,16 +80,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 80 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
79 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 81 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
80 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 82 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
83 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
81 } 84 }
82 85
83 public virtual void AddRegion(Scene scene) 86 public virtual void AddRegion(Scene scene)
84 { 87 {
85 if (!m_enabled) 88 if (!m_enabled) return;
86 return;
87 89
88 scene.EventManager.OnNewClient += OnNewClient; 90 lock (m_syncy)
89 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 91 {
90 scene.EventManager.OnChatBroadcast += OnChatBroadcast; 92 if (!m_scenes.Contains(scene))
93 {
94 m_scenes.Add(scene);
95 scene.EventManager.OnNewClient += OnNewClient;
96 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
97 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
98 }
99 }
91 100
92 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, 101 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
93 m_whisperdistance, m_saydistance, m_shoutdistance); 102 m_whisperdistance, m_saydistance, m_shoutdistance);
@@ -107,12 +116,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
107 116
108 public virtual void RemoveRegion(Scene scene) 117 public virtual void RemoveRegion(Scene scene)
109 { 118 {
110 if (!m_enabled) 119 if (!m_enabled) return;
111 return;
112 120
113 scene.EventManager.OnNewClient -= OnNewClient; 121 lock (m_syncy)
114 scene.EventManager.OnChatFromWorld -= OnChatFromWorld; 122 {
115 scene.EventManager.OnChatBroadcast -= OnChatBroadcast; 123 if (m_scenes.Contains(scene))
124 {
125 scene.EventManager.OnNewClient -= OnNewClient;
126 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
127 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
128 m_scenes.Remove(scene);
129 }
130 }
116 } 131 }
117 132
118 public virtual void Close() 133 public virtual void Close()
@@ -169,7 +184,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
169 return; 184 return;
170 } 185 }
171 186
172 DeliverChatToAvatars(ChatSourceType.Agent, c); 187 if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
188 {
189 if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
190 c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
191 }
192 else
193 {
194 DeliverChatToAvatars(ChatSourceType.Agent, c);
195 }
173 } 196 }
174 197
175 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 198 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -183,11 +206,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
183 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 206 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
184 { 207 {
185 string fromName = c.From; 208 string fromName = c.From;
209 string fromNamePrefix = "";
186 UUID fromID = UUID.Zero; 210 UUID fromID = UUID.Zero;
187 UUID ownerID = UUID.Zero; 211 UUID ownerID = UUID.Zero;
188 UUID targetID = c.TargetUUID;
189 string message = c.Message; 212 string message = c.Message;
190 Scene scene = (Scene)c.Scene; 213 IScene scene = c.Scene;
214 UUID destination = c.Destination;
191 Vector3 fromPos = c.Position; 215 Vector3 fromPos = c.Position;
192 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 216 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
193 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 217 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -197,10 +221,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
197 switch (sourceType) 221 switch (sourceType)
198 { 222 {
199 case ChatSourceType.Agent: 223 case ChatSourceType.Agent:
200 ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId); 224 if (!(scene is Scene))
225 {
226 m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
227 scene.RegionInfo.RegionName, c.Sender.AgentId);
228 return;
229 }
230 ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
201 fromPos = avatar.AbsolutePosition; 231 fromPos = avatar.AbsolutePosition;
202 fromName = avatar.Name; 232 fromName = avatar.Name;
203 fromID = c.Sender.AgentId; 233 fromID = c.Sender.AgentId;
234 if (avatar.GodLevel >= 200)
235 {
236 fromNamePrefix = m_adminPrefix;
237 }
238 destination = UUID.Zero; // Avatars cant "SayTo"
204 ownerID = c.Sender.AgentId; 239 ownerID = c.Sender.AgentId;
205 240
206 break; 241 break;
@@ -219,38 +254,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
219 message = message.Substring(0, 1000); 254 message = message.Substring(0, 1000);
220 255
221// m_log.DebugFormat( 256// m_log.DebugFormat(
222// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", 257// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}",
223// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 258// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
224 259
225 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 260 HashSet<UUID> receiverIDs = new HashSet<UUID>();
226 261
227 if (targetID == UUID.Zero) 262 foreach (Scene s in m_scenes)
228 { 263 {
229 // This should use ForEachClient, but clients don't have a position. 264 // This should use ForEachClient, but clients don't have a position.
230 // If camera is moved into client, then camera position can be used 265 // If camera is moved into client, then camera position can be used
231 scene.ForEachScenePresence( 266 // MT: No, it can't, as chat is heard from the avatar position, not
267 // the camera position.
268 s.ForEachScenePresence(
232 delegate(ScenePresence presence) 269 delegate(ScenePresence presence)
233 { 270 {
234 if (TrySendChatMessage( 271 if (destination != UUID.Zero && presence.UUID != destination)
235 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) 272 return;
236 receiverIDs.Add(presence.UUID); 273 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
274 if (Presencecheck != null)
275 {
276 // This will pass all chat from objects. Not
277 // perfect, but it will do. For now. Better
278 // than the prior behavior of muting all
279 // objects on a parcel with access restrictions
280 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
281 {
282 if (destination != UUID.Zero)
283 {
284 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
285 receiverIDs.Add(presence.UUID);
286 }
287 else
288 {
289 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
290 receiverIDs.Add(presence.UUID);
291 }
292 }
293 }
237 } 294 }
238 ); 295 );
239 } 296 }
240 else 297
241 { 298 (scene as Scene).EventManager.TriggerOnChatToClients(
242 // This is a send to a specific client eg from llRegionSayTo
243 // no need to check distance etc, jand send is as say
244 ScenePresence presence = scene.GetScenePresence(targetID);
245 if (presence != null && !presence.IsChildAgent)
246 {
247 if (TrySendChatMessage(
248 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
249 receiverIDs.Add(presence.UUID);
250 }
251 }
252
253 scene.EventManager.TriggerOnChatToClients(
254 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 299 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
255 } 300 }
256 301
@@ -289,28 +334,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
289 } 334 }
290 335
291 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 336 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
292
293 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 337 HashSet<UUID> receiverIDs = new HashSet<UUID>();
294 338
295 ((Scene)c.Scene).ForEachRootClient( 339 if (c.Scene != null)
296 delegate(IClientAPI client) 340 {
297 { 341 ((Scene)c.Scene).ForEachRootClient
298 // don't forward SayOwner chat from objects to 342 (
299 // non-owner agents 343 delegate(IClientAPI client)
300 if ((c.Type == ChatTypeEnum.Owner) && 344 {
301 (null != c.SenderObject) && 345 // don't forward SayOwner chat from objects to
302 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 346 // non-owner agents
303 return; 347 if ((c.Type == ChatTypeEnum.Owner) &&
304 348 (null != c.SenderObject) &&
305 client.SendChatMessage( 349 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
306 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 350 return;
307 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 351
308 352 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
309 receiverIDs.Add(client.AgentId); 353 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
310 }); 354 receiverIDs.Add(client.AgentId);
311 355 }
312 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 356 );
313 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 357 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
358 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
359 }
314 } 360 }
315 361
316 /// <summary> 362 /// <summary>
@@ -363,6 +409,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
363 return true; 409 return true;
364 } 410 }
365 411
412 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
413 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
414 {
415 System.Threading.Timer Timer;
416 if (flags == 0)
417 {
418 FreezeCache.Add(target.ToString());
419 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
420 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
421 Timers.Add(target, Timer);
422 }
423 else
424 {
425 FreezeCache.Remove(target.ToString());
426 Timers.TryGetValue(target, out Timer);
427 Timers.Remove(target);
428 Timer.Dispose();
429 }
430 }
431
432 private void OnEndParcelFrozen(object avatar)
433 {
434 UUID target = (UUID)avatar;
435 FreezeCache.Remove(target.ToString());
436 System.Threading.Timer Timer;
437 Timers.TryGetValue(target, out Timer);
438 Timers.Remove(target);
439 Timer.Dispose();
440 }
366 #region SimulatorFeaturesRequest 441 #region SimulatorFeaturesRequest
367 442
368 static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange; 443 static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange;
@@ -391,4 +466,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
391 466
392 #endregion 467 #endregion
393 } 468 }
394} \ No newline at end of file 469}
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 343cdb5..c52d586 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -182,6 +182,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
182 try 182 try
183 { 183 {
184 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 184 ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
185 if (obj == null)
186 return;
185 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 187 if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0
186 || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) 188 || avatar.Scene.RegionInfo.RegionSettings.AllowDamage)
187 { 189 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index d26907b..0e7ab7e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -260,4 +260,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
260 return result; 260 return result;
261 } 261 }
262 } 262 }
263} \ No newline at end of file 263}
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 3b6d970..adb838c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -49,6 +49,8 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
49using OSDArray = OpenMetaverse.StructuredData.OSDArray; 49using OSDArray = OpenMetaverse.StructuredData.OSDArray;
50using OSDMap = OpenMetaverse.StructuredData.OSDMap; 50using OSDMap = OpenMetaverse.StructuredData.OSDMap;
51 51
52using Mono.Addins;
53
52namespace OpenSim.Region.CoreModules.Avatar.Gods 54namespace OpenSim.Region.CoreModules.Avatar.Gods
53{ 55{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")] 56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
@@ -62,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
62 64
63 protected Scene m_scene; 65 protected Scene m_scene;
64 protected IDialogModule m_dialogModule; 66 protected IDialogModule m_dialogModule;
67
65 protected IDialogModule DialogModule 68 protected IDialogModule DialogModule
66 { 69 {
67 get 70 get
@@ -146,6 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
146 UUID godSessionID = userData["GodSessionID"].AsUUID(); 149 UUID godSessionID = userData["GodSessionID"].AsUUID();
147 uint kickFlags = userData["KickFlags"].AsUInteger(); 150 uint kickFlags = userData["KickFlags"].AsUInteger();
148 string reason = userData["Reason"].AsString(); 151 string reason = userData["Reason"].AsString();
152
149 ScenePresence god = m_scene.GetScenePresence(godID); 153 ScenePresence god = m_scene.GetScenePresence(godID);
150 if (god == null || god.ControllingClient.SessionId != godSessionID) 154 if (god == null || god.ControllingClient.SessionId != godSessionID)
151 return String.Empty; 155 return String.Empty;
diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
deleted file mode 100644
index b735c61..0000000
--- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37
38using Mono.Addins;
39
40namespace OpenSim.Region.CoreModules.Avatar.Groups
41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
43 public class GroupsModule : ISharedRegionModule
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private Dictionary<UUID, GroupMembershipData> m_GroupMap =
49 new Dictionary<UUID, GroupMembershipData>();
50
51 private Dictionary<UUID, IClientAPI> m_ClientMap =
52 new Dictionary<UUID, IClientAPI>();
53
54 private UUID opensimulatorGroupID =
55 new UUID("00000000-68f9-1111-024e-222222111123");
56
57 private List<Scene> m_SceneList = new List<Scene>();
58
59 private static GroupMembershipData osGroup =
60 new GroupMembershipData();
61
62 private bool m_Enabled = false;
63
64 #region ISharedRegionModule Members
65
66 public void Initialise(IConfigSource config)
67 {
68 IConfig groupsConfig = config.Configs["Groups"];
69
70 if (groupsConfig == null)
71 {
72 m_log.Info("[GROUPS]: No configuration found. Using defaults");
73 }
74 else
75 {
76 m_Enabled = groupsConfig.GetBoolean("Enabled", false);
77 if (!m_Enabled)
78 {
79 m_log.Info("[GROUPS]: Groups disabled in configuration");
80 return;
81 }
82
83 if (groupsConfig.GetString("Module", "Default") != "Default")
84 {
85 m_Enabled = false;
86 return;
87 }
88 }
89
90 }
91
92 public void AddRegion(Scene scene)
93 {
94 if (!m_Enabled)
95 return;
96
97 lock (m_SceneList)
98 {
99 if (!m_SceneList.Contains(scene))
100 {
101 if (m_SceneList.Count == 0)
102 {
103 osGroup.GroupID = opensimulatorGroupID;
104 osGroup.GroupName = "OpenSimulator Testing";
105 osGroup.GroupPowers =
106 (uint)(GroupPowers.AllowLandmark |
107 GroupPowers.AllowSetHome);
108 m_GroupMap[opensimulatorGroupID] = osGroup;
109 }
110 m_SceneList.Add(scene);
111 }
112 }
113
114 scene.EventManager.OnNewClient += OnNewClient;
115 scene.EventManager.OnClientClosed += OnClientClosed;
116 // scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
117 }
118
119 public void RemoveRegion(Scene scene)
120 {
121 if (!m_Enabled)
122 return;
123
124 lock (m_SceneList)
125 {
126 if (m_SceneList.Contains(scene))
127 m_SceneList.Remove(scene);
128 }
129
130 scene.EventManager.OnNewClient -= OnNewClient;
131 scene.EventManager.OnClientClosed -= OnClientClosed;
132 }
133
134 public void RegionLoaded(Scene scene)
135 {
136 }
137
138 public void PostInitialise()
139 {
140 }
141
142 public void Close()
143 {
144 if (!m_Enabled)
145 return;
146
147// m_log.Debug("[GROUPS]: Shutting down group module.");
148
149 lock (m_ClientMap)
150 {
151 m_ClientMap.Clear();
152 }
153
154 lock (m_GroupMap)
155 {
156 m_GroupMap.Clear();
157 }
158 }
159
160 public string Name
161 {
162 get { return "GroupsModule"; }
163 }
164
165 public Type ReplaceableInterface
166 {
167 get { return null; }
168 }
169
170 #endregion
171
172 private void OnNewClient(IClientAPI client)
173 {
174 // Subscribe to instant messages
175// client.OnInstantMessage += OnInstantMessage;
176 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
177 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
178 lock (m_ClientMap)
179 {
180 if (!m_ClientMap.ContainsKey(client.AgentId))
181 {
182 m_ClientMap.Add(client.AgentId, client);
183 }
184 }
185
186 GroupMembershipData[] updateGroups = new GroupMembershipData[1];
187 updateGroups[0] = osGroup;
188
189 client.SendGroupMembership(updateGroups);
190 }
191
192 private void OnAgentDataUpdateRequest(IClientAPI remoteClient,
193 UUID AgentID, UUID SessionID)
194 {
195 UUID ActiveGroupID;
196 string ActiveGroupName;
197 ulong ActiveGroupPowers;
198
199 string firstname = remoteClient.FirstName;
200 string lastname = remoteClient.LastName;
201
202 string ActiveGroupTitle = "I IZ N0T";
203
204 ActiveGroupID = osGroup.GroupID;
205 ActiveGroupName = osGroup.GroupName;
206 ActiveGroupPowers = osGroup.GroupPowers;
207
208 remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname,
209 lastname, ActiveGroupPowers, ActiveGroupName,
210 ActiveGroupTitle);
211 }
212
213// private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
214// {
215// }
216
217// private void OnGridInstantMessage(GridInstantMessage msg)
218// {
219// // Trigger the above event handler
220// OnInstantMessage(null, msg);
221// }
222
223 private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client)
224 {
225 string groupnamereply = "Unknown";
226 UUID groupUUID = UUID.Zero;
227
228 lock (m_GroupMap)
229 {
230 if (m_GroupMap.ContainsKey(id))
231 {
232 GroupMembershipData grp = m_GroupMap[id];
233 groupnamereply = grp.GroupName;
234 groupUUID = grp.GroupID;
235 }
236 }
237 remote_client.SendGroupNameReply(groupUUID, groupnamereply);
238 }
239
240 private void OnClientClosed(UUID agentID, Scene scene)
241 {
242 lock (m_ClientMap)
243 {
244 if (m_ClientMap.ContainsKey(agentID))
245 {
246// IClientAPI cli = m_ClientMap[agentID];
247// if (cli != null)
248// {
249// //m_log.Info("[GROUPS]: Removing all reference to groups for " + cli.Name);
250// }
251// else
252// {
253// //m_log.Info("[GROUPS]: Removing all reference to groups for " + agentID.ToString());
254// }
255 m_ClientMap.Remove(agentID);
256 }
257 }
258 }
259 }
260}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index c33a296..55e30a0 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -27,6 +27,7 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using System.Timers;
30using log4net; 31using log4net;
31using Mono.Addins; 32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
@@ -44,6 +45,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
44 private static readonly ILog m_log = LogManager.GetLogger( 45 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
46 47
48 private Timer m_logTimer = new Timer(10000);
49 private List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
50 private string m_restUrl;
51
47 /// <value> 52 /// <value>
48 /// Is this module enabled? 53 /// Is this module enabled?
49 /// </value> 54 /// </value>
@@ -63,9 +68,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
63 "InstantMessageModule", "InstantMessageModule") != 68 "InstantMessageModule", "InstantMessageModule") !=
64 "InstantMessageModule") 69 "InstantMessageModule")
65 return; 70 return;
71 m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
66 } 72 }
67 73
68 m_enabled = true; 74 m_enabled = true;
75 m_logTimer.AutoReset = false;
76 m_logTimer.Elapsed += LogTimerElapsed;
69 } 77 }
70 78
71 public void AddRegion(Scene scene) 79 public void AddRegion(Scene scene)
@@ -150,6 +158,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
150 { 158 {
151 byte dialog = im.dialog; 159 byte dialog = im.dialog;
152 160
161 if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
162 LogInstantMesssage(im);
163
153 if (dialog != (byte)InstantMessageDialog.MessageFromAgent 164 if (dialog != (byte)InstantMessageDialog.MessageFromAgent
154 && dialog != (byte)InstantMessageDialog.StartTyping 165 && dialog != (byte)InstantMessageDialog.StartTyping
155 && dialog != (byte)InstantMessageDialog.StopTyping 166 && dialog != (byte)InstantMessageDialog.StopTyping
@@ -159,6 +170,32 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
159 return; 170 return;
160 } 171 }
161 172
173 //DateTime dt = DateTime.UtcNow;
174
175 // Ticks from UtcNow, but make it look like local. Evil, huh?
176 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
177
178 //try
179 //{
180 // // Convert that to the PST timezone
181 // TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
182 // dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
183 //}
184 //catch
185 //{
186 // //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
187 //}
188
189 //// And make it look local again to fool the unix time util
190 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
191
192 // If client is null, this message comes from storage and IS offline
193 if (client != null)
194 im.offline = 0;
195
196 if (im.offline == 0)
197 im.timestamp = (uint)Util.UnixTimeSinceEpoch();
198
162 if (m_TransferModule != null) 199 if (m_TransferModule != null)
163 { 200 {
164 if (client != null) 201 if (client != null)
@@ -202,5 +239,35 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
202 // 239 //
203 OnInstantMessage(null, msg); 240 OnInstantMessage(null, msg);
204 } 241 }
242
243 private void LogInstantMesssage(GridInstantMessage im)
244 {
245 if (m_logData.Count < 20)
246 {
247 // Restart the log write timer
248 m_logTimer.Stop();
249 }
250 if (!m_logTimer.Enabled)
251 m_logTimer.Start();
252
253 lock (m_logData)
254 {
255 m_logData.Add(im);
256 }
257 }
258
259 private void LogTimerElapsed(object source, ElapsedEventArgs e)
260 {
261 lock (m_logData)
262 {
263 if (m_restUrl != String.Empty && m_logData.Count > 0)
264 {
265 bool success = SynchronousRestObjectRequester.MakeRequest<List<GridInstantMessage>, bool>("POST", m_restUrl + "/LogMessages/", m_logData);
266 if (!success)
267 m_log.ErrorFormat("[INSTANT MESSAGE]: Failed to save log data");
268 }
269 m_logData.Clear();
270 }
271 }
205 } 272 }
206} 273}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 40a400f..b321adb 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private bool m_Enabled = false; 52 private bool m_Enabled = false;
53 protected string m_MessageKey = String.Empty;
53 protected List<Scene> m_Scenes = new List<Scene>(); 54 protected List<Scene> m_Scenes = new List<Scene>();
54 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); 55 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
55 56
@@ -69,14 +70,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
69 public virtual void Initialise(IConfigSource config) 70 public virtual void Initialise(IConfigSource config)
70 { 71 {
71 IConfig cnf = config.Configs["Messaging"]; 72 IConfig cnf = config.Configs["Messaging"];
72 if (cnf != null && cnf.GetString( 73 if (cnf != null)
73 "MessageTransferModule", "MessageTransferModule") !=
74 "MessageTransferModule")
75 { 74 {
76 m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); 75 if (cnf.GetString("MessageTransferModule",
77 return; 76 "MessageTransferModule") != "MessageTransferModule")
78 } 77 {
78 return;
79 }
79 80
81 m_MessageKey = cnf.GetString("MessageKey", String.Empty);
82 }
83 m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
80 m_Enabled = true; 84 m_Enabled = true;
81 } 85 }
82 86
@@ -135,6 +139,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
135 { 139 {
136 UUID toAgentID = new UUID(im.toAgentID); 140 UUID toAgentID = new UUID(im.toAgentID);
137 141
142 if (toAgentID == UUID.Zero)
143 return;
144
138 // Try root avatar only first 145 // Try root avatar only first
139 foreach (Scene scene in m_Scenes) 146 foreach (Scene scene in m_Scenes)
140 { 147 {
@@ -249,6 +256,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
249 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 256 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
250 && requestData.ContainsKey("binary_bucket")) 257 && requestData.ContainsKey("binary_bucket"))
251 { 258 {
259 if (m_MessageKey != String.Empty)
260 {
261 XmlRpcResponse error_resp = new XmlRpcResponse();
262 Hashtable error_respdata = new Hashtable();
263 error_respdata["success"] = "FALSE";
264 error_resp.Value = error_respdata;
265
266 if (!requestData.Contains("message_key"))
267 return error_resp;
268 if (m_MessageKey != (string)requestData["message_key"])
269 return error_resp;
270 }
271
252 // Do the easy way of validating the UUIDs 272 // Do the easy way of validating the UUIDs
253 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 273 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
254 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 274 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -425,24 +445,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
425 return resp; 445 return resp;
426 } 446 }
427 447
428 /// <summary> 448 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
429 /// delegate for sending a grid instant message asynchronously
430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
432 449
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 450 private class GIM {
434 { 451 public GridInstantMessage im;
435 GridInstantMessageDelegate icon = 452 public MessageResultNotification result;
436 (GridInstantMessageDelegate)iar.AsyncState; 453 };
437 icon.EndInvoke(iar);
438 }
439 454
455 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
456 private int numInstantMessageThreads = 0;
440 457
441 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 458 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
442 { 459 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 460 lock (pendingInstantMessages) {
461 if (numInstantMessageThreads >= 4) {
462 GIM gim = new GIM();
463 gim.im = im;
464 gim.result = result;
465 pendingInstantMessages.Enqueue(gim);
466 } else {
467 ++ numInstantMessageThreads;
468 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
469 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
470 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
471 }
472 }
473 }
444 474
445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 475 private void GridInstantMessageCompleted(IAsyncResult iar)
476 {
477 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
478 d.EndInvoke(iar);
446 } 479 }
447 480
448 /// <summary> 481 /// <summary>
@@ -457,8 +490,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last 490 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried 491 /// regionhandle tried
459 /// </param> 492 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 493 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
461 { 494 {
495 GIM gim;
496 do {
497 try {
498 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
499 } catch (Exception e) {
500 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
501 }
502 lock (pendingInstantMessages) {
503 if (pendingInstantMessages.Count > 0) {
504 gim = pendingInstantMessages.Dequeue();
505 im = gim.im;
506 result = gim.result;
507 } else {
508 gim = null;
509 -- numInstantMessageThreads;
510 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
511 }
512 }
513 } while (gim != null);
514 }
515 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
516 {
517
462 UUID toAgentID = new UUID(im.toAgentID); 518 UUID toAgentID = new UUID(im.toAgentID);
463 519
464 PresenceInfo upd = null; 520 PresenceInfo upd = null;
@@ -525,7 +581,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
525 581
526 if (upd != null) 582 if (upd != null)
527 { 583 {
528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 584 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
529 upd.RegionID); 585 upd.RegionID);
530 if (reginfo != null) 586 if (reginfo != null)
531 { 587 {
@@ -674,6 +730,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
674 gim["position_z"] = msg.Position.Z.ToString(); 730 gim["position_z"] = msg.Position.Z.ToString();
675 gim["region_id"] = new UUID(msg.RegionID).ToString(); 731 gim["region_id"] = new UUID(msg.RegionID).ToString();
676 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 732 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
733 if (m_MessageKey != String.Empty)
734 gim["message_key"] = m_MessageKey;
677 return gim; 735 return gim;
678 } 736 }
679 737
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 7f3d0a2..2d46276 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -173,7 +173,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
173 173
174 private void RetrieveInstantMessages(IClientAPI client) 174 private void RetrieveInstantMessages(IClientAPI client)
175 { 175 {
176 if (m_RestURL != "") 176 if (m_RestURL == String.Empty)
177 {
178 return;
179 }
180 else
177 { 181 {
178 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); 182 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
179 183
@@ -181,28 +185,28 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
181 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>( 185 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
182 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 186 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
183 187
184 if (msglist == null) 188 if (msglist != null)
185 { 189 {
186 m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list."); 190 foreach (GridInstantMessage im in msglist)
187 return;
188 }
189
190 foreach (GridInstantMessage im in msglist)
191 {
192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
193 // send it directly or else the item will be given twice
194 client.SendInstantMessage(im);
195 else
196 { 191 {
197 // Send through scene event manager so all modules get a chance 192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
198 // to look at this message before it gets delivered. 193 // send it directly or else the item will be given twice
199 // 194 client.SendInstantMessage(im);
200 // Needed for proper state management for stored group 195 else
201 // invitations 196 {
202 // 197 // Send through scene event manager so all modules get a chance
203 Scene s = FindScene(client.AgentId); 198 // to look at this message before it gets delivered.
204 if (s != null) 199 //
205 s.EventManager.TriggerIncomingInstantMessage(im); 200 // Needed for proper state management for stored group
201 // invitations
202 //
203
204 im.offline = 1;
205
206 Scene s = FindScene(client.AgentId);
207 if (s != null)
208 s.EventManager.TriggerIncomingInstantMessage(im);
209 }
206 } 210 }
207 } 211 }
208 } 212 }
@@ -214,24 +218,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
214 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 218 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
215 im.dialog != (byte)InstantMessageDialog.GroupNotice && 219 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
216 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 220 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
217 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 221 im.dialog != (byte)InstantMessageDialog.InventoryOffered &&
222 im.dialog != (byte)InstantMessageDialog.TaskInventoryOffered)
218 { 223 {
219 return; 224 return;
220 } 225 }
221 226
222 if (!m_ForwardOfflineGroupMessages)
223 {
224 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
225 im.dialog == (byte)InstantMessageDialog.GroupInvitation)
226 return;
227 }
228
229 Scene scene = FindScene(new UUID(im.fromAgentID)); 227 Scene scene = FindScene(new UUID(im.fromAgentID));
230 if (scene == null) 228 if (scene == null)
231 scene = m_SceneList[0]; 229 scene = m_SceneList[0];
232 230
233 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 231 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
234 "POST", m_RestURL+"/SaveMessage/", im); 232 "POST", m_RestURL+"/SaveMessage/?scope=" +
233 scene.RegionInfo.ScopeID.ToString(), im);
235 234
236 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 235 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
237 { 236 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index f7057fe..5a8544e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -656,4 +656,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
656 m_assetsLoaded = true; 656 m_assetsLoaded = true;
657 } 657 }
658 } 658 }
659} \ No newline at end of file 659}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 5854428..ea660bd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -519,6 +519,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
519 return null; 519 return null;
520 } 520 }
521 521
522 return account;
523 /*
522 try 524 try
523 { 525 {
524 string encpass = Util.Md5Hash(pass); 526 string encpass = Util.Md5Hash(pass);
@@ -539,6 +541,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
539 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e); 541 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e);
540 return null; 542 return null;
541 } 543 }
544 */
542 } 545 }
543 546
544 /// <summary> 547 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 0b10dd8..03aaaac 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -165,8 +165,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
165 if (im.binaryBucket.Length < 17) // Invalid 165 if (im.binaryBucket.Length < 17) // Invalid
166 return; 166 return;
167 167
168 UUID receipientID = new UUID(im.toAgentID); 168 UUID recipientID = new UUID(im.toAgentID);
169 ScenePresence user = scene.GetScenePresence(receipientID); 169 ScenePresence user = scene.GetScenePresence(recipientID);
170 UUID copyID; 170 UUID copyID;
171 171
172 // First byte is the asset type 172 // First byte is the asset type
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
181 folderID, new UUID(im.toAgentID)); 181 folderID, new UUID(im.toAgentID));
182 182
183 InventoryFolderBase folderCopy 183 InventoryFolderBase folderCopy
184 = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); 184 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
185 185
186 if (folderCopy == null) 186 if (folderCopy == null)
187 { 187 {
@@ -240,6 +240,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
240 im.imSessionID = copyID.Guid; 240 im.imSessionID = copyID.Guid;
241 } 241 }
242 242
243 im.offline = 0;
244
243 // Send the IM to the recipient. The item is already 245 // Send the IM to the recipient. The item is already
244 // in their inventory, so it will not be lost if 246 // in their inventory, so it will not be lost if
245 // they are offline. 247 // they are offline.
@@ -259,8 +261,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
259 }); 261 });
260 } 262 }
261 } 263 }
262 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) 264 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
265 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
263 { 266 {
267 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
268 IInventoryService invService = scene.InventoryService;
269
270 // Special case: folder redirect.
271 // RLV uses this
272 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
273 {
274 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, client.AgentId);
275 folder = invService.GetFolder(folder);
276
277 if (folder != null)
278 {
279 if (im.binaryBucket.Length >= 16)
280 {
281 UUID destFolderID = new UUID(im.binaryBucket, 0);
282 if (destFolderID != UUID.Zero)
283 {
284 InventoryFolderBase destFolder = new InventoryFolderBase(destFolderID, client.AgentId);
285 destFolder = invService.GetFolder(destFolder);
286 if (destFolder != null)
287 {
288 if (folder.ParentID != destFolder.ID)
289 {
290 folder.ParentID = destFolder.ID;
291 invService.MoveFolder(folder);
292 client.SendBulkUpdateInventory(folder);
293 }
294 }
295 }
296 }
297 }
298 }
299
264 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 300 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
265 301
266 if (user != null) // Local 302 if (user != null) // Local
@@ -270,27 +306,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
270 else 306 else
271 { 307 {
272 if (m_TransferModule != null) 308 if (m_TransferModule != null)
273 m_TransferModule.SendInstantMessage(im, delegate(bool success) { 309 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
274
275 // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
276 // and is apparently supposed to fix bulk inventory updates after accepting items. But
277 // instead it appears to cause two copies of an accepted folder for the receiving user in
278 // at least some cases. Folder/item update is already done when the offer is made (see code above)
279
280// // Send BulkUpdateInventory
281// IInventoryService invService = scene.InventoryService;
282// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
283//
284// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
285// folder = invService.GetFolder(folder);
286//
287// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
288//
289// // If the user has left the scene by the time the message comes back then we can't send
290// // them the update.
291// if (fromUser != null)
292// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
293 });
294 } 310 }
295 } 311 }
296 312
@@ -403,6 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
403 previousParentFolderID = folder.ParentID; 419 previousParentFolderID = folder.ParentID;
404 folder.ParentID = trashFolder.ID; 420 folder.ParentID = trashFolder.ID;
405 invService.MoveFolder(folder); 421 invService.MoveFolder(folder);
422 client.SendBulkUpdateInventory(folder);
406 } 423 }
407 } 424 }
408 425
@@ -475,32 +492,100 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
475 // Find agent to deliver to 492 // Find agent to deliver to
476 // 493 //
477 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 494 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
495 if (user == null)
496 return;
478 497
479 if (user != null) 498 // This requires a little bit of processing because we have to make the
499 // new item visible in the recipient's inventory here
500 //
501 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
480 { 502 {
481 user.ControllingClient.SendInstantMessage(im); 503 if (im.binaryBucket.Length < 17) // Invalid
504 return;
505
506 UUID recipientID = new UUID(im.toAgentID);
482 507
483 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) 508 // First byte is the asset type
484 { 509 AssetType assetType = (AssetType)im.binaryBucket[0];
485 AssetType assetType = (AssetType)im.binaryBucket[0];
486 UUID inventoryID = new UUID(im.binaryBucket, 1);
487 510
488 IInventoryService invService = scene.InventoryService; 511 if (AssetType.Folder == assetType)
489 InventoryNodeBase node = null; 512 {
490 if (AssetType.Folder == assetType) 513 UUID folderID = new UUID(im.binaryBucket, 1);
514
515 InventoryFolderBase given =
516 new InventoryFolderBase(folderID, recipientID);
517 InventoryFolderBase folder =
518 scene.InventoryService.GetFolder(given);
519
520 if (folder != null)
521 user.ControllingClient.SendBulkUpdateInventory(folder);
522 }
523 else
524 {
525 UUID itemID = new UUID(im.binaryBucket, 1);
526
527 InventoryItemBase given =
528 new InventoryItemBase(itemID, recipientID);
529 InventoryItemBase item =
530 scene.InventoryService.GetItem(given);
531
532 if (item != null)
491 { 533 {
492 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, new UUID(im.toAgentID)); 534 user.ControllingClient.SendBulkUpdateInventory(item);
493 node = invService.GetFolder(folder);
494 } 535 }
495 else 536 }
537 user.ControllingClient.SendInstantMessage(im);
538 }
539 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
540 {
541 if (im.binaryBucket.Length < 1) // Invalid
542 return;
543
544 UUID recipientID = new UUID(im.toAgentID);
545
546 // Bucket is the asset type
547 AssetType assetType = (AssetType)im.binaryBucket[0];
548
549 if (AssetType.Folder == assetType)
550 {
551 UUID folderID = new UUID(im.imSessionID);
552
553 InventoryFolderBase given =
554 new InventoryFolderBase(folderID, recipientID);
555 InventoryFolderBase folder =
556 scene.InventoryService.GetFolder(given);
557
558 if (folder != null)
559 user.ControllingClient.SendBulkUpdateInventory(folder);
560 }
561 else
562 {
563 UUID itemID = new UUID(im.imSessionID);
564
565 InventoryItemBase given =
566 new InventoryItemBase(itemID, recipientID);
567 InventoryItemBase item =
568 scene.InventoryService.GetItem(given);
569
570 if (item != null)
496 { 571 {
497 InventoryItemBase item = new InventoryItemBase(inventoryID, new UUID(im.toAgentID)); 572 user.ControllingClient.SendBulkUpdateInventory(item);
498 node = invService.GetItem(item);
499 } 573 }
500
501 if (node != null)
502 user.ControllingClient.SendBulkUpdateInventory(node);
503 } 574 }
575
576 // Fix up binary bucket since this may be 17 chars long here
577 Byte[] bucket = new Byte[1];
578 bucket[0] = im.binaryBucket[0];
579 im.binaryBucket = bucket;
580
581 user.ControllingClient.SendInstantMessage(im);
582 }
583 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
584 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
585 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
586 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
587 {
588 user.ControllingClient.SendInstantMessage(im);
504 } 589 }
505 } 590 }
506 } 591 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 465ffbc..c517a30 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -163,16 +163,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
163 scene.RegionInfo.RegionHandle, 163 scene.RegionInfo.RegionHandle,
164 (uint)presence.AbsolutePosition.X, 164 (uint)presence.AbsolutePosition.X,
165 (uint)presence.AbsolutePosition.Y, 165 (uint)presence.AbsolutePosition.Y,
166 (uint)Math.Ceiling(presence.AbsolutePosition.Z)); 166 (uint)presence.AbsolutePosition.Z + 2);
167 167
168 m_log.DebugFormat("[LURE MODULE]: TP invite with message {0}, type {1}", message, lureType); 168 m_log.DebugFormat("[LURE MODULE]: TP invite with message {0}, type {1}", message, lureType);
169 169
170 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, 170 GridInstantMessage m;
171 client.FirstName+" "+client.LastName, targetid, 171
172 (byte)InstantMessageDialog.RequestTeleport, false, 172 if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
173 message, dest, false, presence.AbsolutePosition, 173 {
174 new Byte[0], true); 174 m = new GridInstantMessage(scene, client.AgentId,
175 175 client.FirstName+" "+client.LastName, targetid,
176 (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
177 message, dest, false, presence.AbsolutePosition,
178 new Byte[0], true);
179 }
180 else
181 {
182 m = new GridInstantMessage(scene, client.AgentId,
183 client.FirstName+" "+client.LastName, targetid,
184 (byte)InstantMessageDialog.RequestTeleport, false,
185 message, dest, false, presence.AbsolutePosition,
186 new Byte[0], true);
187 }
188
176 if (m_TransferModule != null) 189 if (m_TransferModule != null)
177 { 190 {
178 m_TransferModule.SendInstantMessage(m, 191 m_TransferModule.SendInstantMessage(m,
@@ -207,7 +220,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
207 { 220 {
208 // Forward remote teleport requests 221 // Forward remote teleport requests
209 // 222 //
210 if (msg.dialog != 22) 223 if (msg.dialog != (byte)InstantMessageDialog.RequestTeleport &&
224 msg.dialog != (byte)InstantMessageDialog.GodLikeRequestTeleport)
211 return; 225 return;
212 226
213 if (m_TransferModule != null) 227 if (m_TransferModule != null)
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 6545a99..de8925d 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework
57 /// <summary> 57 /// <summary>
58 /// Each agent has its own capabilities handler. 58 /// Each agent has its own capabilities handler.
59 /// </summary> 59 /// </summary>
60 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 60 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
61 61
62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>(); 62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
63 63
@@ -118,9 +118,10 @@ namespace OpenSim.Region.CoreModules.Framework
118 get { return null; } 118 get { return null; }
119 } 119 }
120 120
121 public void CreateCaps(UUID agentId) 121 public void CreateCaps(UUID agentId, uint circuitCode)
122 { 122 {
123 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) 123 int flags = m_scene.GetUserFlags(agentId);
124 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
124 return; 125 return;
125 126
126 Caps caps; 127 Caps caps;
@@ -128,9 +129,9 @@ namespace OpenSim.Region.CoreModules.Framework
128 129
129 lock (m_capsObjects) 130 lock (m_capsObjects)
130 { 131 {
131 if (m_capsObjects.ContainsKey(agentId)) 132 if (m_capsObjects.ContainsKey(circuitCode))
132 { 133 {
133 Caps oldCaps = m_capsObjects[agentId]; 134 Caps oldCaps = m_capsObjects[circuitCode];
134 135
135 //m_log.WarnFormat( 136 //m_log.WarnFormat(
136 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", 137 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
@@ -141,13 +142,12 @@ namespace OpenSim.Region.CoreModules.Framework
141 (MainServer.Instance == null) ? 0: MainServer.Instance.Port, 142 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
142 capsObjectPath, agentId, m_scene.RegionInfo.RegionName); 143 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
143 144
144 m_capsObjects[agentId] = caps; 145 m_capsObjects[circuitCode] = caps;
145 } 146 }
146
147 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 147 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
148 } 148 }
149 149
150 public void RemoveCaps(UUID agentId) 150 public void RemoveCaps(UUID agentId, uint circuitCode)
151 { 151 {
152 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName); 152 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
153 lock (m_childrenSeeds) 153 lock (m_childrenSeeds)
@@ -160,11 +160,11 @@ namespace OpenSim.Region.CoreModules.Framework
160 160
161 lock (m_capsObjects) 161 lock (m_capsObjects)
162 { 162 {
163 if (m_capsObjects.ContainsKey(agentId)) 163 if (m_capsObjects.ContainsKey(circuitCode))
164 { 164 {
165 m_capsObjects[agentId].DeregisterHandlers(); 165 m_capsObjects[circuitCode].DeregisterHandlers();
166 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); 166 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
167 m_capsObjects.Remove(agentId); 167 m_capsObjects.Remove(circuitCode);
168 } 168 }
169 else 169 else
170 { 170 {
@@ -175,19 +175,30 @@ namespace OpenSim.Region.CoreModules.Framework
175 } 175 }
176 } 176 }
177 177
178 public Caps GetCapsForUser(UUID agentId) 178 public Caps GetCapsForUser(uint circuitCode)
179 { 179 {
180 lock (m_capsObjects) 180 lock (m_capsObjects)
181 { 181 {
182 if (m_capsObjects.ContainsKey(agentId)) 182 if (m_capsObjects.ContainsKey(circuitCode))
183 { 183 {
184 return m_capsObjects[agentId]; 184 return m_capsObjects[circuitCode];
185 } 185 }
186 } 186 }
187 187
188 return null; 188 return null;
189 } 189 }
190 190
191 public void ActivateCaps(uint circuitCode)
192 {
193 lock (m_capsObjects)
194 {
195 if (m_capsObjects.ContainsKey(circuitCode))
196 {
197 m_capsObjects[circuitCode].Activate();
198 }
199 }
200 }
201
191 public void SetAgentCapsSeeds(AgentCircuitData agent) 202 public void SetAgentCapsSeeds(AgentCircuitData agent)
192 { 203 {
193 lock (m_capsPaths) 204 lock (m_capsPaths)
@@ -287,9 +298,9 @@ namespace OpenSim.Region.CoreModules.Framework
287 298
288 lock (m_capsObjects) 299 lock (m_capsObjects)
289 { 300 {
290 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects) 301 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
291 { 302 {
292 capsReport.AppendFormat("** User {0}:\n", kvp.Key); 303 capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
293 Caps caps = kvp.Value; 304 Caps caps = kvp.Value;
294 305
295 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) 306 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
@@ -337,6 +348,7 @@ namespace OpenSim.Region.CoreModules.Framework
337 348
338 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName) 349 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
339 { 350 {
351 /*
340 sb.AppendFormat("Capability name {0}\n", capName); 352 sb.AppendFormat("Capability name {0}\n", capName);
341 353
342 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 354 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -382,10 +394,12 @@ namespace OpenSim.Region.CoreModules.Framework
382 } 394 }
383 395
384 sb.Append(cdt.ToString()); 396 sb.Append(cdt.ToString());
397 */
385 } 398 }
386 399
387 private void BuildSummaryStatsByCapReport(StringBuilder sb) 400 private void BuildSummaryStatsByCapReport(StringBuilder sb)
388 { 401 {
402 /*
389 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 403 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
390 cdt.AddColumn("Name", 34); 404 cdt.AddColumn("Name", 34);
391 cdt.AddColumn("Req Received", 12); 405 cdt.AddColumn("Req Received", 12);
@@ -442,10 +456,12 @@ namespace OpenSim.Region.CoreModules.Framework
442 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); 456 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
443 457
444 sb.Append(cdt.ToString()); 458 sb.Append(cdt.ToString());
459 */
445 } 460 }
446 461
447 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams) 462 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
448 { 463 {
464 /*
449 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) 465 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
450 return; 466 return;
451 467
@@ -476,10 +492,12 @@ namespace OpenSim.Region.CoreModules.Framework
476 } 492 }
477 493
478 MainConsole.Instance.Output(sb.ToString()); 494 MainConsole.Instance.Output(sb.ToString());
495 */
479 } 496 }
480 497
481 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp) 498 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
482 { 499 {
500 /*
483 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root"); 501 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
484 502
485 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 503 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -505,10 +523,12 @@ namespace OpenSim.Region.CoreModules.Framework
505 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled); 523 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
506 524
507 sb.Append(cdt.ToString()); 525 sb.Append(cdt.ToString());
526 */
508 } 527 }
509 528
510 private void BuildSummaryStatsByUserReport(StringBuilder sb) 529 private void BuildSummaryStatsByUserReport(StringBuilder sb)
511 { 530 {
531 /*
512 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 532 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
513 cdt.AddColumn("Name", 32); 533 cdt.AddColumn("Name", 32);
514 cdt.AddColumn("Type", 5); 534 cdt.AddColumn("Type", 5);
@@ -548,6 +568,7 @@ namespace OpenSim.Region.CoreModules.Framework
548 ); 568 );
549 569
550 sb.Append(cdt.ToString()); 570 sb.Append(cdt.ToString());
571 */
551 } 572 }
552 573
553 private class CapTableRow 574 private class CapTableRow
@@ -564,4 +585,4 @@ namespace OpenSim.Region.CoreModules.Framework
564 } 585 }
565 } 586 }
566 } 587 }
567} \ No newline at end of file 588}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index aa8a4db..ef5239a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -409,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
409 /// <param name="sp"></param> 409 /// <param name="sp"></param>
410 /// <param name="position"></param> 410 /// <param name="position"></param>
411 /// <param name="lookAt"></param> 411 /// <param name="lookAt"></param>
412 /// <param name="teleportFlags"></param 412 /// <param name="teleportFlags"></param>
413 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 413 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
414 { 414 {
415 m_log.DebugFormat( 415 m_log.DebugFormat(
@@ -444,11 +444,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
444 position.Z = newPosZ; 444 position.Z = newPosZ;
445 } 445 }
446 446
447 if (sp.Flying)
448 teleportFlags |= (uint)TeleportFlags.IsFlying;
449
447 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 450 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
448 451
449 sp.ControllingClient.SendTeleportStart(teleportFlags); 452 sp.ControllingClient.SendTeleportStart(teleportFlags);
450 453
451 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 454 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
455 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
452 sp.Velocity = Vector3.Zero; 456 sp.Velocity = Vector3.Zero;
453 sp.Teleport(position); 457 sp.Teleport(position);
454 458
@@ -652,8 +656,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
652 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 656 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
653 // it's actually doing a lot of work. 657 // it's actually doing a lot of work.
654 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 658 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
655 659 if (endPoint == null || endPoint.Address == null)
656 if (endPoint.Address == null)
657 { 660 {
658 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 661 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
659 662
@@ -692,6 +695,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
692 // both regions 695 // both regions
693 if (sp.ParentID != (uint)0) 696 if (sp.ParentID != (uint)0)
694 sp.StandUp(); 697 sp.StandUp();
698 else if (sp.Flying)
699 teleportFlags |= (uint)TeleportFlags.IsFlying;
695 700
696 if (DisableInterRegionTeleportCancellation) 701 if (DisableInterRegionTeleportCancellation)
697 teleportFlags |= (uint)TeleportFlags.DisableCancel; 702 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -1319,11 +1324,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1319 1324
1320 #region Teleport Home 1325 #region Teleport Home
1321 1326
1322 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1327 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1323 { 1328 {
1324 TeleportHome(id, client); 1329 TeleportHome(id, client);
1325 } 1330 }
1326 1331
1327 public virtual bool TeleportHome(UUID id, IClientAPI client) 1332 public virtual bool TeleportHome(UUID id, IClientAPI client)
1328 { 1333 {
1329 m_log.DebugFormat( 1334 m_log.DebugFormat(
@@ -1334,6 +1339,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1334 1339
1335 if (uinfo != null) 1340 if (uinfo != null)
1336 { 1341 {
1342 if (uinfo.HomeRegionID == UUID.Zero)
1343 {
1344 // can't find the Home region: Tell viewer and abort
1345 client.SendTeleportFailed("You don't have a home position set.");
1346 return false;
1347 }
1337 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1348 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1338 if (regionInfo == null) 1349 if (regionInfo == null)
1339 { 1350 {
@@ -1353,9 +1364,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1353 } 1364 }
1354 else 1365 else
1355 { 1366 {
1356 m_log.ErrorFormat( 1367 // can't find the Home region: Tell viewer and abort
1357 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1368 client.SendTeleportFailed("Your home region could not be found.");
1358 client.Name, client.AgentId);
1359 } 1369 }
1360 return false; 1370 return false;
1361 } 1371 }
@@ -1365,15 +1375,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1365 1375
1366 #region Agent Crossings 1376 #region Agent Crossings
1367 1377
1368 public bool Cross(ScenePresence agent, bool isFlying) 1378 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1369 { 1379 {
1370 Scene scene = agent.Scene; 1380 version = String.Empty;
1371 Vector3 pos = agent.AbsolutePosition; 1381 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1372 1382
1373// m_log.DebugFormat( 1383// m_log.DebugFormat(
1374// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1384// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1375 1385
1376 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1377 uint neighbourx = scene.RegionInfo.RegionLocX; 1386 uint neighbourx = scene.RegionInfo.RegionLocX;
1378 uint neighboury = scene.RegionInfo.RegionLocY; 1387 uint neighboury = scene.RegionInfo.RegionLocY;
1379 const float boundaryDistance = 1.7f; 1388 const float boundaryDistance = 1.7f;
@@ -1394,52 +1403,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1394 } 1403 }
1395 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1404 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1396 { 1405 {
1397 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1406 neighboury--;
1398 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1407 newpos.Y = Constants.RegionSize - enterDistance;
1399 {
1400 neighboury--;
1401 newpos.Y = Constants.RegionSize - enterDistance;
1402 }
1403 else
1404 {
1405 agent.IsInTransit = true;
1406
1407 neighboury = b.TriggerRegionY;
1408 neighbourx = b.TriggerRegionX;
1409
1410 Vector3 newposition = pos;
1411 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1412 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1413 agent.ControllingClient.SendAgentAlertMessage(
1414 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1415 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1416 return true;
1417 }
1418 }
1419
1420 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1421 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1422 {
1423 neighbourx--;
1424 newpos.X = Constants.RegionSize - enterDistance;
1425 }
1426 else
1427 {
1428 agent.IsInTransit = true;
1429
1430 neighboury = ba.TriggerRegionY;
1431 neighbourx = ba.TriggerRegionX;
1432
1433 Vector3 newposition = pos;
1434 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1435 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1436 agent.ControllingClient.SendAgentAlertMessage(
1437 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1438 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1439
1440 return true;
1441 } 1408 }
1442 1409
1410 neighbourx--;
1411 newpos.X = Constants.RegionSize - enterDistance;
1443 } 1412 }
1444 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1413 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1445 { 1414 {
@@ -1449,26 +1418,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1449 1418
1450 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1419 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1451 { 1420 {
1452 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1421 neighboury--;
1453 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1422 newpos.Y = Constants.RegionSize - enterDistance;
1454 {
1455 neighboury--;
1456 newpos.Y = Constants.RegionSize - enterDistance;
1457 }
1458 else
1459 {
1460 agent.IsInTransit = true;
1461
1462 neighboury = ba.TriggerRegionY;
1463 neighbourx = ba.TriggerRegionX;
1464 Vector3 newposition = pos;
1465 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1466 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1467 agent.ControllingClient.SendAgentAlertMessage(
1468 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1469 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1470 return true;
1471 }
1472 } 1423 }
1473 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1424 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1474 { 1425 {
@@ -1480,25 +1431,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1480 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1431 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1481 { 1432 {
1482 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1433 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1483 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1434 neighboury--;
1484 { 1435 newpos.Y = Constants.RegionSize - enterDistance;
1485 neighboury--;
1486 newpos.Y = Constants.RegionSize - enterDistance;
1487 }
1488 else
1489 {
1490 agent.IsInTransit = true;
1491
1492 neighboury = b.TriggerRegionY;
1493 neighbourx = b.TriggerRegionX;
1494 Vector3 newposition = pos;
1495 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1496 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1497 agent.ControllingClient.SendAgentAlertMessage(
1498 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1499 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1500 return true;
1501 }
1502 } 1436 }
1503 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1437 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1504 { 1438 {
@@ -1532,19 +1466,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1532 } 1466 }
1533 */ 1467 */
1534 1468
1535 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1469 xDest = neighbourx;
1470 yDest = neighboury;
1536 1471
1537 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1472 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1538 1473
1474 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1475
1539 ExpiringCache<ulong, DateTime> r; 1476 ExpiringCache<ulong, DateTime> r;
1540 DateTime banUntil; 1477 DateTime banUntil;
1541 1478
1542 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1479 if (m_bannedRegions.TryGetValue(agentID, out r))
1543 { 1480 {
1544 if (r.TryGetValue(neighbourHandle, out banUntil)) 1481 if (r.TryGetValue(neighbourHandle, out banUntil))
1545 { 1482 {
1546 if (DateTime.Now < banUntil) 1483 if (DateTime.Now < banUntil)
1547 return false; 1484 return null;
1548 r.Remove(neighbourHandle); 1485 r.Remove(neighbourHandle);
1549 } 1486 }
1550 } 1487 }
@@ -1556,28 +1493,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1556 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1493 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1557 1494
1558 string reason; 1495 string reason;
1559 string version; 1496 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1560 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1561 { 1497 {
1562 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1563 if (r == null) 1498 if (r == null)
1564 { 1499 {
1565 r = new ExpiringCache<ulong, DateTime>(); 1500 r = new ExpiringCache<ulong, DateTime>();
1566 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1501 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1567 1502
1568 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1503 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1569 } 1504 }
1570 else 1505 else
1571 { 1506 {
1572 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1507 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1573 } 1508 }
1509 return null;
1510 }
1511
1512 return neighbourRegion;
1513 }
1514
1515 public bool Cross(ScenePresence agent, bool isFlying)
1516 {
1517 uint x;
1518 uint y;
1519 Vector3 newpos;
1520 string version;
1521
1522 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1523 if (neighbourRegion == null)
1524 {
1525 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1574 return false; 1526 return false;
1575 } 1527 }
1576 1528
1577 agent.IsInTransit = true; 1529 agent.IsInTransit = true;
1578 1530
1579 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1531 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1580 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1532 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1581 1533
1582 return true; 1534 return true;
1583 } 1535 }
@@ -1659,52 +1611,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1659 icon.EndInvoke(iar); 1611 icon.EndInvoke(iar);
1660 } 1612 }
1661 1613
1662 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1614 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1615 {
1616 if (neighbourRegion == null)
1617 return false;
1618
1619 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1620
1621 agent.RemoveFromPhysicalScene();
1622
1623 return true;
1624 }
1663 1625
1664 /// <summary> 1626 /// <summary>
1665 /// This Closes child agents on neighbouring regions 1627 /// This Closes child agents on neighbouring regions
1666 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1628 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1667 /// </summary> 1629 /// </summary>
1668 protected ScenePresence CrossAgentToNewRegionAsync( 1630 public ScenePresence CrossAgentToNewRegionAsync(
1669 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1631 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1670 bool isFlying, string version) 1632 bool isFlying, string version)
1671 { 1633 {
1672 if (neighbourRegion == null) 1634 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1635 {
1636 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1673 return agent; 1637 return agent;
1638 }
1674 1639
1675 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1640 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1676 { 1641 {
1677 m_log.ErrorFormat( 1642 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1678 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1679 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1680 return agent; 1643 return agent;
1681 } 1644 }
1682 1645
1683 bool transitWasReset = false; 1646 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1647 return agent;
1648 }
1684 1649
1650 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1651 {
1685 try 1652 try
1686 { 1653 {
1687 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1654 AgentData cAgent = new AgentData();
1688
1689 m_log.DebugFormat(
1690 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1691 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1692
1693 Scene m_scene = agent.Scene;
1694
1695 if (!agent.ValidateAttachments())
1696 m_log.DebugFormat(
1697 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1698 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1699
1700 pos = pos + agent.Velocity;
1701 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1702
1703 agent.RemoveFromPhysicalScene();
1704
1705 AgentData cAgent = new AgentData();
1706 agent.CopyTo(cAgent); 1655 agent.CopyTo(cAgent);
1707 cAgent.Position = pos; 1656 cAgent.Position = pos + agent.Velocity;
1708 if (isFlying) 1657 if (isFlying)
1709 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1658 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1710 1659
@@ -1714,7 +1663,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1714 // Beyond this point, extra cleanup is needed beyond removing transit state 1663 // Beyond this point, extra cleanup is needed beyond removing transit state
1715 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1664 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1716 1665
1717 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1666 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1718 { 1667 {
1719 // region doesn't take it 1668 // region doesn't take it
1720 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1669 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1726,88 +1675,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1726 ReInstantiateScripts(agent); 1675 ReInstantiateScripts(agent);
1727 agent.AddToPhysicalScene(isFlying); 1676 agent.AddToPhysicalScene(isFlying);
1728 1677
1729 return agent; 1678 return false;
1730 } 1679 }
1731 1680
1732 //m_log.Debug("BEFORE CROSS"); 1681 }
1733 //Scene.DumpChildrenSeeds(UUID); 1682 catch (Exception e)
1734 //DumpKnownRegions(); 1683 {
1735 string agentcaps; 1684 m_log.ErrorFormat(
1736 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1685 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1737 { 1686 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1738 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1739 neighbourRegion.RegionHandle);
1740 return agent;
1741 }
1742 1687
1743 // No turning back 1688 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1744 agent.IsChildAgent = true; 1689 return false;
1690 }
1745 1691
1746 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1692 return true;
1693 }
1747 1694
1748 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1695 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1696 bool isFlying, string version)
1697 {
1698 agent.ControllingClient.RequestClientInfo();
1749 1699
1750 if (m_eqModule != null) 1700 string agentcaps;
1751 { 1701 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1752 m_eqModule.CrossRegion( 1702 {
1753 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1703 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1754 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1704 neighbourRegion.RegionHandle);
1755 } 1705 return;
1756 else 1706 }
1757 {
1758 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1759 capsPath);
1760 }
1761 1707
1762 // SUCCESS! 1708 // No turning back
1763 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1709 agent.IsChildAgent = true;
1764 1710
1765 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1711 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1766 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1767 1712
1768 agent.MakeChildAgent(); 1713 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1769 1714
1770 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1715 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1771 // but not sure yet what the side effects would be. 1716
1772 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1717 if (m_eqModule != null)
1773 transitWasReset = true; 1718 {
1719 m_eqModule.CrossRegion(
1720 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1721 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1722 }
1723 else
1724 {
1725 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1726 capsPath);
1727 }
1774 1728
1775 // now we have a child agent in this region. Request all interesting data about other (root) agents 1729 // SUCCESS!
1776 agent.SendOtherAgentsAvatarDataToMe(); 1730 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1777 agent.SendOtherAgentsAppearanceToMe();
1778 1731
1779 // Backwards compatibility. Best effort 1732 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1780 if (version == "Unknown" || version == string.Empty) 1733 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1781 {
1782 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1783 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1784 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1785 }
1786 1734
1787 // Next, let's close the child agent connections that are too far away. 1735 agent.MakeChildAgent();
1788 agent.CloseChildAgents(neighbourx, neighboury);
1789 1736
1790 AgentHasMovedAway(agent, false); 1737 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1791 1738 // but not sure yet what the side effects would be.
1792 //m_log.Debug("AFTER CROSS"); 1739 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1793 //Scene.DumpChildrenSeeds(UUID);
1794 //DumpKnownRegions();
1795 }
1796 catch (Exception e)
1797 {
1798 m_log.ErrorFormat(
1799 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1800 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1801 1740
1802 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1741 // now we have a child agent in this region. Request all interesting data about other (root) agents
1803 } 1742 agent.SendOtherAgentsAvatarDataToMe();
1804 finally 1743 agent.SendOtherAgentsAppearanceToMe();
1744
1745 // Backwards compatibility. Best effort
1746 if (version == "Unknown" || version == string.Empty)
1805 { 1747 {
1806 if (!transitWasReset) 1748 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1807 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1749 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1750 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1808 } 1751 }
1809 1752
1810 return agent; 1753 // Next, let's close the child agent connections that are too far away.
1754 uint neighbourx;
1755 uint neighboury;
1756
1757 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1758
1759 neighbourx /= Constants.RegionSize;
1760 neighboury /= Constants.RegionSize;
1761
1762 agent.CloseChildAgents(neighbourx, neighboury);
1763
1764 AgentHasMovedAway(agent, false);
1765
1766 // the user may change their profile information in other region,
1767 // so the userinfo in UserProfileCache is not reliable any more, delete it
1768 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1769// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1770// {
1771// m_log.DebugFormat(
1772// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1773// }
1774
1775 //m_log.Debug("AFTER CROSS");
1776 //Scene.DumpChildrenSeeds(UUID);
1777 //DumpKnownRegions();
1778
1779 return;
1811 } 1780 }
1812 1781
1813 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1782 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1878,10 +1847,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1878 agent.Id0 = currentAgentCircuit.Id0; 1847 agent.Id0 = currentAgentCircuit.Id0;
1879 } 1848 }
1880 1849
1881 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1850 IPEndPoint external = region.ExternalEndPoint;
1882 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1851 if (external != null)
1852 {
1853 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1854 d.BeginInvoke(sp, agent, region, external, true,
1883 InformClientOfNeighbourCompleted, 1855 InformClientOfNeighbourCompleted,
1884 d); 1856 d);
1857 }
1885 } 1858 }
1886 #endregion 1859 #endregion
1887 1860
@@ -2478,30 +2451,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2478 Utils.LongToUInts(newRegionHandle, out x, out y); 2451 Utils.LongToUInts(newRegionHandle, out x, out y);
2479 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2452 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2480 2453
2481 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2454 if (destination != null)
2482 { 2455 {
2483 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2456 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2457 return; // we did it
2458 }
2484 2459
2485 // We are going to move the object back to the old position so long as the old position 2460 // no one or failed lets go back and tell physics to go on
2486 // is in the region 2461 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2487 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2462 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2488 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2463 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2489 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2490 2464
2491 grp.RootPart.GroupPosition = oldGroupPosition; 2465 grp.AbsolutePosition = oldGroupPosition;
2466 grp.Velocity = Vector3.Zero;
2492 2467
2493 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2468 if (grp.RootPart.PhysActor != null)
2494 // move out of the region creating an infinite loop of failed attempts to cross 2469 grp.RootPart.PhysActor.CrossingFailure();
2495 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2496 2470
2497 if (grp.RootPart.KeyframeMotion != null) 2471 if (grp.RootPart.KeyframeMotion != null)
2498 grp.RootPart.KeyframeMotion.CrossingFailure(); 2472 grp.RootPart.KeyframeMotion.CrossingFailure();
2499 2473
2500 grp.ScheduleGroupForFullUpdate(); 2474 grp.ScheduleGroupForFullUpdate();
2501 }
2502 } 2475 }
2503 2476
2504 2477
2478
2505 /// <summary> 2479 /// <summary>
2506 /// Move the given scene object into a new region 2480 /// Move the given scene object into a new region
2507 /// </summary> 2481 /// </summary>
@@ -2552,17 +2526,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2552 grp, e); 2526 grp, e);
2553 } 2527 }
2554 } 2528 }
2529/*
2530 * done on caller ( not in attachments crossing for now)
2555 else 2531 else
2556 { 2532 {
2533
2557 if (!grp.IsDeleted) 2534 if (!grp.IsDeleted)
2558 { 2535 {
2559 PhysicsActor pa = grp.RootPart.PhysActor; 2536 PhysicsActor pa = grp.RootPart.PhysActor;
2560 if (pa != null) 2537 if (pa != null)
2538 {
2561 pa.CrossingFailure(); 2539 pa.CrossingFailure();
2540 if (grp.RootPart.KeyframeMotion != null)
2541 {
2542 // moved to KeyframeMotion.CrossingFailure
2543// grp.RootPart.Velocity = Vector3.Zero;
2544 grp.RootPart.KeyframeMotion.CrossingFailure();
2545// grp.SendGroupRootTerseUpdate();
2546 }
2547 }
2562 } 2548 }
2563 2549
2564 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2550 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2565 } 2551 }
2552 */
2566 } 2553 }
2567 else 2554 else
2568 { 2555 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index fc02916..e903383 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
294 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 294 id, m_mod.Scene.RegionInfo.RegionName, currentState));
295 } 295 }
296 296
297 int count = 200; 297 int count = 400;
298 298
299 // There should be no race condition here since no other code should be removing the agent transfer or 299 // There should be no race condition here since no other code should be removing the agent transfer or
300 // changing the state to another other than Transferring => ReceivedAtDestination. 300 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -349,4 +349,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
349 } 349 }
350 } 350 }
351 } 351 }
352} \ No newline at end of file 352}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 04a0db6..74b834a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -313,6 +313,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
313 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 313 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
314 } 314 }
315 315
316 public void TriggerTeleportHome(UUID id, IClientAPI client)
317 {
318 TeleportHome(id, client);
319 }
320
316 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) 321 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
317 { 322 {
318 reason = "Please wear your grid's allowed appearance before teleporting to another grid"; 323 reason = "Please wear your grid's allowed appearance before teleporting to another grid";
@@ -431,11 +436,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
431 // return base.UpdateAgent(reg, finalDestination, agentData, sp); 436 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
432 //} 437 //}
433 438
434 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
435 {
436 TeleportHome(id, client);
437 }
438
439 public override bool TeleportHome(UUID id, IClientAPI client) 439 public override bool TeleportHome(UUID id, IClientAPI client)
440 { 440 {
441 m_log.DebugFormat( 441 m_log.DebugFormat(
@@ -483,9 +483,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
483 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 483 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
484 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 484 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
485 485
486 DoTeleport( 486 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
487 sp, homeGatekeeper, finalDestination,
488 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
489 return true; 487 return true;
490 } 488 }
491 489
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 831922e..6251266 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -183,44 +183,49 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
183 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 183 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
184 return; 184 return;
185 185
186 if (transactionID == UUID.Zero) 186 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
187 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
188
189 if (folder == null || folder.Owner != remoteClient.AgentId)
190 return;
191
192 if (transactionID != UUID.Zero)
187 { 193 {
188 ScenePresence presence; 194 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
189 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 195 if (agentTransactions != null)
190 { 196 {
191 byte[] data = null; 197 if (agentTransactions.HandleItemCreationFromTransaction(
198 remoteClient, transactionID, folderID, callbackID, description,
199 name, invType, assetType, wearableType, nextOwnerMask))
200 return;
201 }
202 }
192 203
193 if (invType == (sbyte)InventoryType.Landmark && presence != null) 204 ScenePresence presence;
194 { 205 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
195 string suffix = string.Empty, prefix = string.Empty; 206 {
196 string strdata = GenerateLandmark(presence, out prefix, out suffix); 207 byte[] data = null;
197 data = Encoding.ASCII.GetBytes(strdata);
198 name = prefix + name;
199 description += suffix;
200 }
201 208
202 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); 209 if (invType == (sbyte)InventoryType.Landmark && presence != null)
203 m_Scene.AssetService.Store(asset);
204 m_Scene.CreateNewInventoryItem(
205 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
206 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
207 }
208 else
209 { 210 {
210 m_log.ErrorFormat( 211 string suffix = string.Empty, prefix = string.Empty;
211 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", 212 string strdata = GenerateLandmark(presence, out prefix, out suffix);
212 remoteClient.AgentId); 213 data = Encoding.ASCII.GetBytes(strdata);
214 name = prefix + name;
215 description += suffix;
213 } 216 }
217
218 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
219 m_Scene.AssetService.Store(asset);
220 m_Scene.CreateNewInventoryItem(
221 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
222 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID);
214 } 223 }
215 else 224 else
216 { 225 {
217 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; 226 m_log.ErrorFormat(
218 if (agentTransactions != null) 227 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
219 { 228 remoteClient.AgentId);
220 agentTransactions.HandleItemCreationFromTransaction(
221 remoteClient, transactionID, folderID, callbackID, description,
222 name, invType, assetType, wearableType, nextOwnerMask);
223 }
224 } 229 }
225 } 230 }
226 231
@@ -359,20 +364,42 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
359 { 364 {
360 if (objectGroup.RootPart.KeyframeMotion != null) 365 if (objectGroup.RootPart.KeyframeMotion != null)
361 objectGroup.RootPart.KeyframeMotion.Stop(); 366 objectGroup.RootPart.KeyframeMotion.Stop();
367 objectGroup.RootPart.SetForce(Vector3.Zero);
368 objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
362 objectGroup.RootPart.KeyframeMotion = null; 369 objectGroup.RootPart.KeyframeMotion = null;
363// Vector3 inventoryStoredPosition = new Vector3 370
364// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 371 Vector3 inventoryStoredPosition = new Vector3
365// ? 250 372 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
366// : objectGroup.AbsolutePosition.X) 373 ? 250
367// , 374 : objectGroup.AbsolutePosition.X)
368// (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize) 375 ,
369// ? 250 376 (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize)
370// : objectGroup.AbsolutePosition.Y, 377 ? 250
371// objectGroup.AbsolutePosition.Z); 378 : objectGroup.AbsolutePosition.Y,
372// 379 objectGroup.AbsolutePosition.Z);
373// originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 380
374// 381 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
375// objectGroup.AbsolutePosition = inventoryStoredPosition; 382 //originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
383
384 // Restore attachment data after trip through the sim
385 if (objectGroup.RootPart.AttachPoint > 0)
386 {
387 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
388 inventoryStoredRotation = objectGroup.RootPart.AttachRotation;
389 }
390
391 // Trees could be attached and it's been done, but it makes
392 // no sense. State must be preserved because it's the tree type
393 if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree &&
394 objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree)
395 {
396 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
397 if (objectGroup.RootPart.AttachPoint > 0)
398 objectGroup.RootPart.Shape.LastAttachPoint = objectGroup.RootPart.AttachPoint;
399 }
400
401 objectGroup.AbsolutePosition = inventoryStoredPosition;
402 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
376 403
377 // Make sure all bits but the ones we want are clear 404 // Make sure all bits but the ones we want are clear
378 // on take. 405 // on take.
@@ -491,8 +518,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
491 IClientAPI remoteClient) 518 IClientAPI remoteClient)
492 { 519 {
493 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; 520 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
521 // For the porposes of inventory, an object is modify if the prims
522 // are modify. This allows renaming an object that contains no
523 // mod items.
494 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 524 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
495 effectivePerms &= grp.GetEffectivePermissions(); 525 {
526 uint groupPerms = grp.GetEffectivePermissions(true);
527 if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0)
528 groupPerms |= (uint)PermissionMask.Modify;
529
530 effectivePerms &= groupPerms;
531 }
496 effectivePerms |= (uint)PermissionMask.Move; 532 effectivePerms |= (uint)PermissionMask.Move;
497 533
498 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 534 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
@@ -673,7 +709,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
673 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId) 709 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId)
674 { 710 {
675 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 711 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
676 folder = m_Scene.InventoryService.GetFolder(f); 712 if (f != null)
713 folder = m_Scene.InventoryService.GetFolder(f);
677 714
678 if(folder.Type == 14 || folder.Type == 16) 715 if(folder.Type == 14 || folder.Type == 16)
679 { 716 {
@@ -709,16 +746,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
709 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 746 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
710 { 747 {
711// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 748// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
712
713 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 749 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
714 item = m_Scene.InventoryService.GetItem(item); 750 item = m_Scene.InventoryService.GetItem(item);
715 751
716 if (item == null) 752 if (item == null)
717 { 753 {
718 m_log.WarnFormat(
719 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
720 itemID, remoteClient.Name);
721
722 return null; 754 return null;
723 } 755 }
724 756
@@ -782,12 +814,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
782 pos -= bbox / 2; 814 pos -= bbox / 2;
783 } 815 }
784 816
817 int primcount = 0;
818 foreach (SceneObjectGroup g in objlist)
819 primcount += g.PrimCount;
820
821 if (!m_Scene.Permissions.CanRezObject(
822 primcount, remoteClient.AgentId, pos)
823 && !attachment)
824 {
825 // The client operates in no fail mode. It will
826 // have already removed the item from the folder
827 // if it's no copy.
828 // Put it back if it's not an attachment
829 //
830 if (item != null)
831 {
832 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
833 remoteClient.SendBulkUpdateInventory(item);
834 }
835
836 return null;
837 }
838
785 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) 839 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
786 return null; 840 return null;
787 841
788 for (int i = 0; i < objlist.Count; i++) 842 for (int i = 0; i < objlist.Count; i++)
789 { 843 {
790 group = objlist[i]; 844 group = objlist[i];
845 SceneObjectPart rootPart = group.RootPart;
791 846
792// m_log.DebugFormat( 847// m_log.DebugFormat(
793// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 848// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -856,8 +911,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
856 911
857 if (!attachment) 912 if (!attachment)
858 { 913 {
859 SceneObjectPart rootPart = group.RootPart;
860
861 if (rootPart.Shape.PCode == (byte)PCode.Prim) 914 if (rootPart.Shape.PCode == (byte)PCode.Prim)
862 group.ClearPartAttachmentData(); 915 group.ClearPartAttachmentData();
863 916
@@ -875,6 +928,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
875// remoteClient.Name); 928// remoteClient.Name);
876 } 929 }
877 930
931 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
932
878 if (item != null) 933 if (item != null)
879 DoPostRezWhenFromItem(item, attachment); 934 DoPostRezWhenFromItem(item, attachment);
880 935
@@ -959,8 +1014,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
959 { 1014 {
960 rootPart.Name = item.Name; 1015 rootPart.Name = item.Name;
961 rootPart.Description = item.Description; 1016 rootPart.Description = item.Description;
962 rootPart.ObjectSaleType = item.SaleType; 1017 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
963 rootPart.SalePrice = item.SalePrice; 1018 {
1019 rootPart.ObjectSaleType = item.SaleType;
1020 rootPart.SalePrice = item.SalePrice;
1021 }
964 } 1022 }
965 1023
966 so.FromFolderID = item.Folder; 1024 so.FromFolderID = item.Folder;
@@ -970,7 +1028,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
970// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1028// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
971 1029
972 if ((rootPart.OwnerID != item.Owner) || 1030 if ((rootPart.OwnerID != item.Owner) ||
973 (item.CurrentPermissions & 16) != 0) 1031 (item.CurrentPermissions & 16) != 0 ||
1032 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
974 { 1033 {
975 //Need to kill the for sale here 1034 //Need to kill the for sale here
976 rootPart.ObjectSaleType = 0; 1035 rootPart.ObjectSaleType = 0;
@@ -980,31 +1039,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
980 { 1039 {
981 foreach (SceneObjectPart part in so.Parts) 1040 foreach (SceneObjectPart part in so.Parts)
982 { 1041 {
983 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
984 {
985 part.EveryoneMask = item.EveryOnePermissions;
986 part.NextOwnerMask = item.NextPermissions;
987 }
988 part.GroupMask = 0; // DO NOT propagate here 1042 part.GroupMask = 0; // DO NOT propagate here
1043
1044 part.LastOwnerID = part.OwnerID;
1045 part.OwnerID = item.Owner;
1046 part.Inventory.ChangeInventoryOwner(item.Owner);
989 } 1047 }
990 1048
991 so.ApplyNextOwnerPermissions(); 1049 so.ApplyNextOwnerPermissions();
1050
1051 // In case the user has changed flags on a received item
1052 // we have to apply those changes after the slam. Else we
1053 // get a net loss of permissions
1054 foreach (SceneObjectPart part in so.Parts)
1055 {
1056 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1057 {
1058 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1059 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1060 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1061 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1062 }
1063 }
992 } 1064 }
993 } 1065 }
994 1066 else
995 foreach (SceneObjectPart part in so.Parts)
996 { 1067 {
997 part.FromUserInventoryItemID = fromUserInventoryItemId; 1068 foreach (SceneObjectPart part in so.Parts)
998
999 if ((part.OwnerID != item.Owner) ||
1000 (item.CurrentPermissions & 16) != 0)
1001 { 1069 {
1002 part.Inventory.ChangeInventoryOwner(item.Owner); 1070 part.FromUserInventoryItemID = fromUserInventoryItemId;
1003 part.GroupMask = 0; // DO NOT propagate here 1071
1072 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1073 part.EveryoneMask = item.EveryOnePermissions;
1074 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1075 part.NextOwnerMask = item.NextPermissions;
1076 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1077 part.GroupMask = item.GroupPermissions;
1004 } 1078 }
1005
1006 part.EveryoneMask = item.EveryOnePermissions;
1007 part.NextOwnerMask = item.NextPermissions;
1008 } 1079 }
1009 1080
1010 rootPart.TrimPermissions(); 1081 rootPart.TrimPermissions();
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 79a409d..8946b5c 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -136,9 +136,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid
136 } 136 }
137 } 137 }
138 138
139 protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 139 protected override List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
140 { 140 {
141 List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); 141 List<MapBlockData> mapBlocks = base.GetAndSendBlocksInternal(remoteClient, minX, minY, maxX, maxY, flag);
142 lock (m_SeenMapBlocks) 142 lock (m_SeenMapBlocks)
143 { 143 {
144 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) 144 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index c3a8afd..5541063 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -28,15 +28,12 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Linq;
32using System.Net; 31using System.Net;
33using System.Net.Mail; 32using System.Net.Mail;
34using System.Net.Security; 33using System.Net.Security;
35using System.Reflection;
36using System.Text; 34using System.Text;
37using System.Threading; 35using System.Threading;
38using System.Security.Cryptography.X509Certificates; 36using System.Security.Cryptography.X509Certificates;
39using log4net;
40using Nini.Config; 37using Nini.Config;
41using OpenMetaverse; 38using OpenMetaverse;
42using OpenSim.Framework; 39using OpenSim.Framework;
@@ -45,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
47using Mono.Addins; 44using Mono.Addins;
45using Amib.Threading;
48 46
49/***************************************************** 47/*****************************************************
50 * 48 *
@@ -105,6 +103,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
105 private Dictionary<UUID, HttpRequestClass> m_pendingRequests; 103 private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
106 private Scene m_scene; 104 private Scene m_scene;
107 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 105 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
106 public static SmartThreadPool ThreadPool = null;
108 107
109 public HttpRequestModule() 108 public HttpRequestModule()
110 { 109 {
@@ -253,29 +252,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
253 return reqID; 252 return reqID;
254 } 253 }
255 254
256 public void StopHttpRequestsForScript(UUID id) 255 public void StopHttpRequest(uint m_localID, UUID m_itemID)
257 { 256 {
258 if (m_pendingRequests != null) 257 if (m_pendingRequests != null)
259 { 258 {
260 List<UUID> keysToRemove = null;
261
262 lock (HttpListLock) 259 lock (HttpListLock)
263 { 260 {
264 foreach (HttpRequestClass req in m_pendingRequests.Values) 261 HttpRequestClass tmpReq;
262 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
265 { 263 {
266 if (req.ItemID == id) 264 tmpReq.Stop();
267 { 265 m_pendingRequests.Remove(m_itemID);
268 req.Stop();
269
270 if (keysToRemove == null)
271 keysToRemove = new List<UUID>();
272
273 keysToRemove.Add(req.ReqID);
274 }
275 } 266 }
276
277 if (keysToRemove != null)
278 keysToRemove.ForEach(keyToRemove => m_pendingRequests.Remove(keyToRemove));
279 } 267 }
280 } 268 }
281 } 269 }
@@ -293,13 +281,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
293 { 281 {
294 lock (HttpListLock) 282 lock (HttpListLock)
295 { 283 {
296 foreach (HttpRequestClass req in m_pendingRequests.Values) 284 foreach (UUID luid in m_pendingRequests.Keys)
297 { 285 {
298 if (req.Finished) 286 HttpRequestClass tmpReq;
299 return req; 287
288 if (m_pendingRequests.TryGetValue(luid, out tmpReq))
289 {
290 if (tmpReq.Finished)
291 {
292 return tmpReq;
293 }
294 }
300 } 295 }
301 } 296 }
302
303 return null; 297 return null;
304 } 298 }
305 299
@@ -326,7 +320,30 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
326 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 320 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
327 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 321 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
328 322
323 int maxThreads = 50;
324
325 IConfig httpConfig = config.Configs["HttpRequestModule"];
326 if (httpConfig != null)
327 {
328 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
329 }
330
329 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 331 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
332
333 // First instance sets this up for all sims
334 if (ThreadPool == null)
335 {
336 STPStartInfo startInfo = new STPStartInfo();
337 startInfo.IdleTimeout = 20000;
338 startInfo.MaxWorkerThreads = maxThreads;
339 startInfo.MinWorkerThreads = 5;
340 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
341 startInfo.StartSuspended = true;
342
343 ThreadPool = new SmartThreadPool(startInfo);
344
345 ThreadPool.Start();
346 }
330 } 347 }
331 348
332 public void AddRegion(Scene scene) 349 public void AddRegion(Scene scene)
@@ -370,8 +387,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
370 387
371 public class HttpRequestClass: IServiceRequest 388 public class HttpRequestClass: IServiceRequest
372 { 389 {
373// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
374
375 // Constants for parameters 390 // Constants for parameters
376 // public const int HTTP_BODY_MAXLENGTH = 2; 391 // public const int HTTP_BODY_MAXLENGTH = 2;
377 // public const int HTTP_METHOD = 0; 392 // public const int HTTP_METHOD = 0;
@@ -392,6 +407,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
392 public string HttpMIMEType = "text/plain;charset=utf-8"; 407 public string HttpMIMEType = "text/plain;charset=utf-8";
393 public int HttpTimeout; 408 public int HttpTimeout;
394 public bool HttpVerifyCert = true; 409 public bool HttpVerifyCert = true;
410 public IWorkItemResult WorkItem = null;
411
395 //public bool HttpVerboseThrottle = true; // not implemented 412 //public bool HttpVerboseThrottle = true; // not implemented
396 public List<string> HttpCustomHeaders = null; 413 public List<string> HttpCustomHeaders = null;
397 public bool HttpPragmaNoCache = true; 414 public bool HttpPragmaNoCache = true;
@@ -419,7 +436,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
419 get { return _reqID; } 436 get { return _reqID; }
420 set { _reqID = value; } 437 set { _reqID = value; }
421 } 438 }
422 public WebRequest Request; 439 public HttpWebRequest Request;
423 public string ResponseBody; 440 public string ResponseBody;
424 public List<string> ResponseMetadata; 441 public List<string> ResponseMetadata;
425 public Dictionary<string, string> ResponseHeaders; 442 public Dictionary<string, string> ResponseHeaders;
@@ -428,14 +445,38 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
428 445
429 public void Process() 446 public void Process()
430 { 447 {
448 _finished = false;
449
450 lock (HttpRequestModule.ThreadPool)
451 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
452 }
453
454 private object StpSendWrapper(object o)
455 {
431 SendRequest(); 456 SendRequest();
457 return null;
432 } 458 }
433 459
460 /*
461 * TODO: More work on the response codes. Right now
462 * returning 200 for success or 499 for exception
463 */
464
434 public void SendRequest() 465 public void SendRequest()
435 { 466 {
467 HttpWebResponse response = null;
468 StringBuilder sb = new StringBuilder();
469 byte[] buf = new byte[8192];
470 string tempString = null;
471 int count = 0;
472
436 try 473 try
437 { 474 {
438 Request = WebRequest.Create(Url); 475 Request = (HttpWebRequest) WebRequest.Create(Url);
476
477 //This works around some buggy HTTP Servers like Lighttpd
478 Request.ServicePoint.Expect100Continue = false;
479
439 Request.Method = HttpMethod; 480 Request.Method = HttpMethod;
440 Request.ContentType = HttpMIMEType; 481 Request.ContentType = HttpMIMEType;
441 482
@@ -443,7 +484,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
443 { 484 {
444 // We could hijack Connection Group Name to identify 485 // We could hijack Connection Group Name to identify
445 // a desired security exception. But at the moment we'll use a dummy header instead. 486 // a desired security exception. But at the moment we'll use a dummy header instead.
446// Request.ConnectionGroupName = "NoVerify";
447 Request.Headers.Add("NoVerifyCert", "true"); 487 Request.Headers.Add("NoVerifyCert", "true");
448 } 488 }
449// else 489// else
@@ -473,14 +513,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
473 } 513 }
474 } 514 }
475 515
476 if (ResponseHeaders != null) 516 foreach (KeyValuePair<string, string> entry in ResponseHeaders)
477 { 517 if (entry.Key.ToLower().Equals("user-agent"))
478 foreach (KeyValuePair<string, string> entry in ResponseHeaders) 518 Request.UserAgent = entry.Value;
479 if (entry.Key.ToLower().Equals("user-agent") && Request is HttpWebRequest) 519 else
480 ((HttpWebRequest)Request).UserAgent = entry.Value; 520 Request.Headers[entry.Key] = entry.Value;
481 else
482 Request.Headers[entry.Key] = entry.Value;
483 }
484 521
485 // Encode outbound data 522 // Encode outbound data
486 if (!string.IsNullOrEmpty(OutboundBody)) 523 if (!string.IsNullOrEmpty(OutboundBody))
@@ -493,12 +530,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
493 bstream.Close(); 530 bstream.Close();
494 } 531 }
495 532
533 Request.Timeout = HttpTimeout;
496 try 534 try
497 { 535 {
498 IAsyncResult result = (IAsyncResult)Request.BeginGetResponse(ResponseCallback, null); 536 // execute the request
499 537 response = (HttpWebResponse) Request.GetResponse();
500 ThreadPool.RegisterWaitForSingleObject(
501 result.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), null, HttpTimeout, true);
502 } 538 }
503 catch (WebException e) 539 catch (WebException e)
504 { 540 {
@@ -506,82 +542,91 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
506 { 542 {
507 throw; 543 throw;
508 } 544 }
545 response = (HttpWebResponse)e.Response;
546 }
509 547
510 HttpWebResponse response = (HttpWebResponse)e.Response; 548 Status = (int)response.StatusCode;
511 549
512 Status = (int)response.StatusCode; 550 Stream resStream = response.GetResponseStream();
513 ResponseBody = response.StatusDescription;
514 _finished = true;
515 }
516 }
517 catch (Exception e)
518 {
519// m_log.Debug(
520// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on request to {0} for {1} ", Url, ItemID), e);
521 551
522 Status = (int)OSHttpStatusCode.ClientErrorJoker; 552 do
523 ResponseBody = e.Message; 553 {
524 _finished = true; 554 // fill the buffer with data
525 } 555 count = resStream.Read(buf, 0, buf.Length);
526 }
527 556
528 private void ResponseCallback(IAsyncResult ar) 557 // make sure we read some data
529 { 558 if (count != 0)
530 HttpWebResponse response = null; 559 {
560 // translate from bytes to ASCII text
561 tempString = Util.UTF8.GetString(buf, 0, count);
531 562
532 try 563 // continue building the string
564 sb.Append(tempString);
565 if (sb.Length > 2048)
566 break;
567 }
568 } while (count > 0); // any more data to read?
569
570 ResponseBody = sb.ToString().Replace("\r", "");
571 }
572 catch (WebException e)
533 { 573 {
534 try 574 if (e.Status == WebExceptionStatus.ProtocolError)
535 {
536 response = (HttpWebResponse)Request.EndGetResponse(ar);
537 }
538 catch (WebException e)
539 { 575 {
540 if (e.Status != WebExceptionStatus.ProtocolError) 576 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
577 Status = (int)webRsp.StatusCode;
578 try
541 { 579 {
542 throw; 580 using (Stream responseStream = webRsp.GetResponseStream())
581 {
582 ResponseBody = responseStream.GetStreamString();
583 }
584 }
585 catch
586 {
587 ResponseBody = webRsp.StatusDescription;
543 } 588 }
544 589 }
545 response = (HttpWebResponse)e.Response; 590 else
591 {
592 Status = (int)OSHttpStatusCode.ClientErrorJoker;
593 ResponseBody = e.Message;
546 } 594 }
547 595
548 Status = (int)response.StatusCode; 596 if (ResponseBody == null)
597 ResponseBody = String.Empty;
549 598
550 using (Stream stream = response.GetResponseStream()) 599 _finished = true;
551 { 600 return;
552 StreamReader reader = new StreamReader(stream, Encoding.UTF8);
553 ResponseBody = reader.ReadToEnd();
554 }
555 } 601 }
556 catch (Exception e) 602 catch (Exception e)
557 { 603 {
558 Status = (int)OSHttpStatusCode.ClientErrorJoker; 604 // Don't crash on anything else
559 ResponseBody = e.Message;
560
561// m_log.Debug(
562// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on response to {0} for {1} ", Url, ItemID), e);
563 } 605 }
564 finally 606 finally
565 { 607 {
566 if (response != null) 608 if (response != null)
567 response.Close(); 609 response.Close();
568
569 _finished = true;
570 } 610 }
571 }
572 611
573 private void TimeoutCallback(object state, bool timedOut) 612 if (ResponseBody == null)
574 { 613 ResponseBody = String.Empty;
575 if (timedOut) 614
576 Request.Abort(); 615 _finished = true;
577 } 616 }
578 617
579 public void Stop() 618 public void Stop()
580 { 619 {
581// m_log.DebugFormat("[SCRIPTS HTTP REQUESTS]: Stopping request to {0} for {1} ", Url, ItemID); 620 try
582 621 {
583 if (Request != null) 622 if (!WorkItem.Cancel())
584 Request.Abort(); 623 {
624 WorkItem.Cancel(true);
625 }
626 }
627 catch (Exception)
628 {
629 }
585 } 630 }
586 } 631 }
587} \ No newline at end of file 632}
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 99a3122..1983fed 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -42,40 +42,16 @@ using OpenSim.Region.Framework.Scenes;
42 42
43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp 43namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
44{ 44{
45 /// <summary>
46 /// Data describing an external URL set up by a script.
47 /// </summary>
48 public class UrlData 45 public class UrlData
49 { 46 {
50 /// <summary>
51 /// Scene object part hosting the script
52 /// </summary>
53 public UUID hostID; 47 public UUID hostID;
54
55 /// <summary>
56 /// The item ID of the script that requested the URL.
57 /// </summary>
58 public UUID itemID; 48 public UUID itemID;
59
60 /// <summary>
61 /// The script engine that runs the script.
62 /// </summary>
63 public IScriptModule engine; 49 public IScriptModule engine;
64
65 /// <summary>
66 /// The generated URL.
67 /// </summary>
68 public string url; 50 public string url;
69
70 /// <summary>
71 /// The random UUID component of the generated URL.
72 /// </summary>
73 public UUID urlcode; 51 public UUID urlcode;
74
75 /// <summary>
76 /// The external requests currently being processed or awaiting retrieval for this URL.
77 /// </summary>
78 public Dictionary<UUID, RequestData> requests; 52 public Dictionary<UUID, RequestData> requests;
53 public bool isSsl;
54 public Scene scene;
79 } 55 }
80 56
81 public class RequestData 57 public class RequestData
@@ -89,7 +65,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 65 //public ManualResetEvent ev;
90 public bool requestDone; 66 public bool requestDone;
91 public int startTime; 67 public int startTime;
68 public bool responseSent;
92 public string uri; 69 public string uri;
70 public bool allowResponseType = false;
71 public UUID hostID;
72 public Scene scene;
93 } 73 }
94 74
95 /// <summary> 75 /// <summary>
@@ -102,20 +82,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 82 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 83 MethodBase.GetCurrentMethod().DeclaringType);
104 84
105 /// <summary> 85 private Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 86 new Dictionary<UUID, UrlData>();
107 /// randomly generated when a request is received for this URL.
108 /// </summary>
109 /// <remarks>
110 /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
111 /// m_UrlMap
112 /// </remarks>
113 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
114 87
115 /// <summary> 88 private Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 89 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 90
120 private uint m_HttpsPort = 0; 91 private uint m_HttpsPort = 0;
121 private IHttpServer m_HttpServer = null; 92 private IHttpServer m_HttpServer = null;
@@ -126,7 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
126 /// <summary> 97 /// <summary>
127 /// The default maximum number of urls 98 /// The default maximum number of urls
128 /// </summary> 99 /// </summary>
129 public const int DefaultTotalUrls = 100; 100 public const int DefaultTotalUrls = 15000;
130 101
131 /// <summary> 102 /// <summary>
132 /// Maximum number of external urls that can be set up by this module. 103 /// Maximum number of external urls that can be set up by this module.
@@ -204,6 +175,17 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
204 175
205 public void RemoveRegion(Scene scene) 176 public void RemoveRegion(Scene scene)
206 { 177 {
178 // Drop references to that scene
179 foreach (KeyValuePair<string, UrlData> kvp in m_UrlMap)
180 {
181 if (kvp.Value.scene == scene)
182 kvp.Value.scene = null;
183 }
184 foreach (KeyValuePair<UUID, UrlData> kvp in m_RequestMap)
185 {
186 if (kvp.Value.scene == scene)
187 kvp.Value.scene = null;
188 }
207 } 189 }
208 190
209 public void Close() 191 public void Close()
@@ -221,7 +203,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 203 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
222 return urlcode; 204 return urlcode;
223 } 205 }
224 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 206 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
225 207
226 UrlData urlData = new UrlData(); 208 UrlData urlData = new UrlData();
227 urlData.hostID = host.UUID; 209 urlData.hostID = host.UUID;
@@ -229,20 +211,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 211 urlData.engine = engine;
230 urlData.url = url; 212 urlData.url = url;
231 urlData.urlcode = urlcode; 213 urlData.urlcode = urlcode;
214 urlData.isSsl = false;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 215 urlData.requests = new Dictionary<UUID, RequestData>();
233 216 urlData.scene = host.ParentGroup.Scene;
217
234 m_UrlMap[url] = urlData; 218 m_UrlMap[url] = urlData;
235 219
236 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 220 string uri = "/lslhttp/" + urlcode.ToString();
237 221
238 PollServiceEventArgs args 222 PollServiceEventArgs args
239 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 223 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
240 args.Type = PollServiceEventArgs.EventType.LslHttp; 224 args.Type = PollServiceEventArgs.EventType.LslHttp;
241 m_HttpServer.AddPollServiceHTTPHandler(uri, args); 225 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
242 226
243 m_log.DebugFormat( 227// m_log.DebugFormat(
244 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 228// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
245 uri, itemID, host.Name, host.LocalId); 229// uri, itemID, host.Name, host.LocalId);
246 230
247 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 231 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
248 } 232 }
@@ -267,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
267 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 251 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
268 return urlcode; 252 return urlcode;
269 } 253 }
270 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 254 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
271 255
272 UrlData urlData = new UrlData(); 256 UrlData urlData = new UrlData();
273 urlData.hostID = host.UUID; 257 urlData.hostID = host.UUID;
@@ -275,20 +259,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
275 urlData.engine = engine; 259 urlData.engine = engine;
276 urlData.url = url; 260 urlData.url = url;
277 urlData.urlcode = urlcode; 261 urlData.urlcode = urlcode;
262 urlData.isSsl = true;
278 urlData.requests = new Dictionary<UUID, RequestData>(); 263 urlData.requests = new Dictionary<UUID, RequestData>();
279 264
265
280 m_UrlMap[url] = urlData; 266 m_UrlMap[url] = urlData;
281 267
282 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 268 string uri = "/lslhttps/" + urlcode.ToString();
283 269
284 PollServiceEventArgs args 270 PollServiceEventArgs args
285 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); 271 = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000);
286 args.Type = PollServiceEventArgs.EventType.LslHttp; 272 args.Type = PollServiceEventArgs.EventType.LslHttp;
287 m_HttpsServer.AddPollServiceHTTPHandler(uri, args); 273 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
288 274
289 m_log.DebugFormat( 275// m_log.DebugFormat(
290 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 276// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
291 uri, itemID, host.Name, host.LocalId); 277// uri, itemID, host.Name, host.LocalId);
292 278
293 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 279 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
294 } 280 }
@@ -307,12 +293,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
307 return; 293 return;
308 } 294 }
309 295
310 foreach (UUID req in data.requests.Keys) 296 lock (m_RequestMap)
311 m_RequestMap.Remove(req); 297 {
312 298 foreach (UUID req in data.requests.Keys)
313 m_log.DebugFormat( 299 m_RequestMap.Remove(req);
314 "[URL MODULE]: Releasing url {0} for {1} in {2}", 300 }
315 url, data.itemID, data.hostID); 301
302// m_log.DebugFormat(
303// "[URL MODULE]: Releasing url {0} for {1} in {2}",
304// url, data.itemID, data.hostID);
316 305
317 RemoveUrl(data); 306 RemoveUrl(data);
318 m_UrlMap.Remove(url); 307 m_UrlMap.Remove(url);
@@ -337,29 +326,39 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
337 326
338 public void HttpResponse(UUID request, int status, string body) 327 public void HttpResponse(UUID request, int status, string body)
339 { 328 {
340 lock (m_UrlMap) 329 lock (m_RequestMap)
341 { 330 {
342 if (m_RequestMap.ContainsKey(request)) 331 if (m_RequestMap.ContainsKey(request))
343 { 332 {
344 UrlData urlData = m_RequestMap[request]; 333 UrlData urlData = m_RequestMap[request];
345 string responseBody = body; 334 if (!urlData.requests[request].responseSent)
346 if (urlData.requests[request].responseType.Equals("text/plain"))
347 { 335 {
348 string value; 336 string responseBody = body;
349 if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) 337
338 // If we have no OpenID from built-in browser, disable this
339 if (!urlData.requests[request].allowResponseType)
340 urlData.requests[request].responseType = "text/plain";
341
342 if (urlData.requests[request].responseType.Equals("text/plain"))
350 { 343 {
351 if (value != null && value.IndexOf("MSIE") >= 0) 344 string value;
345 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
352 { 346 {
353 // wrap the html escaped response if the target client is IE 347 if (value != null && value.IndexOf("MSIE") >= 0)
354 // It ignores "text/plain" if the body is html 348 {
355 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>"; 349 // wrap the html escaped response if the target client is IE
350 // It ignores "text/plain" if the body is html
351 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
352 }
356 } 353 }
357 } 354 }
355
356 urlData.requests[request].responseCode = status;
357 urlData.requests[request].responseBody = body;
358 //urlData.requests[request].ev.Set();
359 urlData.requests[request].requestDone = true;
360 urlData.requests[request].responseSent = true;
358 } 361 }
359 urlData.requests[request].responseCode = status;
360 urlData.requests[request].responseBody = responseBody;
361 //urlData.requests[request].ev.Set();
362 urlData.requests[request].requestDone =true;
363 } 362 }
364 else 363 else
365 { 364 {
@@ -370,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
370 369
371 public string GetHttpHeader(UUID requestId, string header) 370 public string GetHttpHeader(UUID requestId, string header)
372 { 371 {
373 lock (m_UrlMap) 372 lock (m_RequestMap)
374 { 373 {
375 if (m_RequestMap.ContainsKey(requestId)) 374 if (m_RequestMap.ContainsKey(requestId))
376 { 375 {
@@ -384,7 +383,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
384 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 383 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
385 } 384 }
386 } 385 }
387
388 return String.Empty; 386 return String.Empty;
389 } 387 }
390 388
@@ -408,8 +406,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
408 { 406 {
409 RemoveUrl(url.Value); 407 RemoveUrl(url.Value);
410 removeURLs.Add(url.Key); 408 removeURLs.Add(url.Key);
411 foreach (UUID req in url.Value.requests.Keys) 409 lock (m_RequestMap)
412 m_RequestMap.Remove(req); 410 {
411 foreach (UUID req in url.Value.requests.Keys)
412 m_RequestMap.Remove(req);
413 }
413 } 414 }
414 } 415 }
415 416
@@ -430,9 +431,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
430 { 431 {
431 RemoveUrl(url.Value); 432 RemoveUrl(url.Value);
432 removeURLs.Add(url.Key); 433 removeURLs.Add(url.Key);
433 434 lock (m_RequestMap)
434 foreach (UUID req in url.Value.requests.Keys) 435 {
435 m_RequestMap.Remove(req); 436 foreach (UUID req in url.Value.requests.Keys)
437 m_RequestMap.Remove(req);
438 }
436 } 439 }
437 } 440 }
438 441
@@ -441,123 +444,128 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
441 } 444 }
442 } 445 }
443 446
447
444 private void RemoveUrl(UrlData data) 448 private void RemoveUrl(UrlData data)
445 { 449 {
446 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 450 if (data.isSsl)
451 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
452 else
453 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
447 } 454 }
448 455
449 private Hashtable NoEvents(UUID requestID, UUID sessionID) 456 private Hashtable NoEvents(UUID requestID, UUID sessionID)
450 { 457 {
451 Hashtable response = new Hashtable(); 458 Hashtable response = new Hashtable();
452 UrlData urlData; 459 UrlData url;
453 460 int startTime = 0;
454 lock (m_UrlMap) 461 lock (m_RequestMap)
455 { 462 {
456 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
457 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
458 // for the request ID.
459 if (!m_RequestMap.ContainsKey(requestID)) 463 if (!m_RequestMap.ContainsKey(requestID))
460 {
461 response["int_response_code"] = 404;
462 response["str_response_string"] = "";
463 response["keepalive"] = false;
464 response["reusecontext"] = false;
465
466 return response; 464 return response;
467 } 465 url = m_RequestMap[requestID];
466 startTime = url.requests[requestID].startTime;
467 }
468 468
469 urlData = m_RequestMap[requestID]; 469 if (System.Environment.TickCount - startTime > 25000)
470 {
471 response["int_response_code"] = 500;
472 response["str_response_string"] = "Script timeout";
473 response["content_type"] = "text/plain";
474 response["keepalive"] = false;
475 response["reusecontext"] = false;
470 476
471 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 477 //remove from map
478 lock (url.requests)
479 {
480 url.requests.Remove(requestID);
481 }
482 lock (m_RequestMap)
472 { 483 {
473 response["int_response_code"] = 500;
474 response["str_response_string"] = "Script timeout";
475 response["content_type"] = "text/plain";
476 response["keepalive"] = false;
477 response["reusecontext"] = false;
478
479 //remove from map
480 urlData.requests.Remove(requestID);
481 m_RequestMap.Remove(requestID); 484 m_RequestMap.Remove(requestID);
482
483 return response;
484 } 485 }
486
487 return response;
485 } 488 }
486 489
490
487 return response; 491 return response;
488 } 492 }
489 493
490 private bool HasEvents(UUID requestID, UUID sessionID) 494 private bool HasEvents(UUID requestID, UUID sessionID)
491 { 495 {
492 lock (m_UrlMap) 496 UrlData url=null;
497
498 lock (m_RequestMap)
493 { 499 {
494 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
495 // can still make it through to HttpRequestHandler(). That will return without setting up a request
496 // when it detects that the URL has been removed. The poller, however, will continue to ask for
497 // events for that request, so here we will signal that there are events and in GetEvents we will
498 // return a 404.
499 if (!m_RequestMap.ContainsKey(requestID)) 500 if (!m_RequestMap.ContainsKey(requestID))
500 { 501 {
501 return true; 502 return false;
502 } 503 }
503 504 url = m_RequestMap[requestID];
504 UrlData urlData = m_RequestMap[requestID]; 505 }
505 506 lock (url.requests)
506 if (!urlData.requests.ContainsKey(requestID)) 507 {
508 if (!url.requests.ContainsKey(requestID))
507 { 509 {
508 return true; 510 return false;
509 } 511 }
510 512 else
511 // Trigger return of timeout response.
512 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
513 { 513 {
514 return true; 514 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
515 {
516 return true;
517 }
518 if (url.requests[requestID].requestDone)
519 return true;
520 else
521 return false;
515 } 522 }
516
517 return urlData.requests[requestID].requestDone;
518 } 523 }
519 } 524 }
520
521 private Hashtable GetEvents(UUID requestID, UUID sessionID) 525 private Hashtable GetEvents(UUID requestID, UUID sessionID)
522 { 526 {
523 Hashtable response; 527 UrlData url = null;
528 RequestData requestData = null;
524 529
525 lock (m_UrlMap) 530 lock (m_RequestMap)
526 { 531 {
527 UrlData url = null;
528 RequestData requestData = null;
529
530 if (!m_RequestMap.ContainsKey(requestID)) 532 if (!m_RequestMap.ContainsKey(requestID))
531 return NoEvents(requestID, sessionID); 533 return NoEvents(requestID,sessionID);
532
533 url = m_RequestMap[requestID]; 534 url = m_RequestMap[requestID];
535 }
536 lock (url.requests)
537 {
534 requestData = url.requests[requestID]; 538 requestData = url.requests[requestID];
539 }
540
541 if (!requestData.requestDone)
542 return NoEvents(requestID,sessionID);
543
544 Hashtable response = new Hashtable();
535 545
536 if (!requestData.requestDone) 546 if (System.Environment.TickCount - requestData.startTime > 25000)
537 return NoEvents(requestID, sessionID); 547 {
538 548 response["int_response_code"] = 500;
539 response = new Hashtable(); 549 response["str_response_string"] = "Script timeout";
540 550 response["content_type"] = "text/plain";
541 if (System.Environment.TickCount - requestData.startTime > 25000)
542 {
543 response["int_response_code"] = 500;
544 response["str_response_string"] = "Script timeout";
545 response["content_type"] = "text/plain";
546 response["keepalive"] = false;
547 response["reusecontext"] = false;
548 return response;
549 }
550
551 //put response
552 response["int_response_code"] = requestData.responseCode;
553 response["str_response_string"] = requestData.responseBody;
554 response["content_type"] = requestData.responseType;
555 // response["content_type"] = "text/plain";
556 response["keepalive"] = false; 551 response["keepalive"] = false;
557 response["reusecontext"] = false; 552 response["reusecontext"] = false;
558 553 return response;
559 //remove from map 554 }
555 //put response
556 response["int_response_code"] = requestData.responseCode;
557 response["str_response_string"] = requestData.responseBody;
558 response["content_type"] = requestData.responseType;
559 response["keepalive"] = false;
560 response["reusecontext"] = false;
561
562 //remove from map
563 lock (url.requests)
564 {
560 url.requests.Remove(requestID); 565 url.requests.Remove(requestID);
566 }
567 lock (m_RequestMap)
568 {
561 m_RequestMap.Remove(requestID); 569 m_RequestMap.Remove(requestID);
562 } 570 }
563 571
@@ -566,41 +574,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
566 574
567 public void HttpRequestHandler(UUID requestID, Hashtable request) 575 public void HttpRequestHandler(UUID requestID, Hashtable request)
568 { 576 {
569 string uri = request["uri"].ToString(); 577 lock (request)
570 bool is_ssl = uri.Contains("lslhttps");
571
572 try
573 { 578 {
574 Hashtable headers = (Hashtable)request["headers"]; 579 string uri = request["uri"].ToString();
580 bool is_ssl = uri.Contains("lslhttps");
575 581
576// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 582 try
577
578 int pos1 = uri.IndexOf("/");// /lslhttp
579 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
580 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
581 string uri_tmp = uri.Substring(0, pos3 + 1);
582 //HTTP server code doesn't provide us with QueryStrings
583 string pathInfo;
584 string queryString;
585 queryString = "";
586
587 pathInfo = uri.Substring(pos3);
588
589 UrlData urlData = null;
590
591 lock (m_UrlMap)
592 { 583 {
593 string url; 584 Hashtable headers = (Hashtable)request["headers"];
594 585
595 if (is_ssl) 586// string uri_full = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
596 url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 587
588 int pos1 = uri.IndexOf("/");// /lslhttp
589 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
590 int pos3 = pos2 + 37; // /lslhttp/urlcode
591 string uri_tmp = uri.Substring(0, pos3);
592 //HTTP server code doesn't provide us with QueryStrings
593 string pathInfo;
594 string queryString;
595 queryString = "";
596
597 pathInfo = uri.Substring(pos3);
598
599 UrlData url = null;
600 string urlkey;
601 if (!is_ssl)
602 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
603 //m_UrlMap[];
597 else 604 else
598 url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 605 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
599 606
600 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 607 if (m_UrlMap.ContainsKey(urlkey))
601 // request was being processed. 608 {
602 if (!m_UrlMap.TryGetValue(url, out urlData)) 609 url = m_UrlMap[urlkey];
610 }
611 else
612 {
613 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
603 return; 614 return;
615 }
604 616
605 //for llGetHttpHeader support we need to store original URI here 617 //for llGetHttpHeader support we need to store original URI here
606 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 618 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -611,6 +623,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
611 requestData.requestDone = false; 623 requestData.requestDone = false;
612 requestData.startTime = System.Environment.TickCount; 624 requestData.startTime = System.Environment.TickCount;
613 requestData.uri = uri; 625 requestData.uri = uri;
626 requestData.hostID = url.hostID;
627 requestData.scene = url.scene;
614 if (requestData.headers == null) 628 if (requestData.headers == null)
615 requestData.headers = new Dictionary<string, string>(); 629 requestData.headers = new Dictionary<string, string>();
616 630
@@ -619,8 +633,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
619 string key = (string)header.Key; 633 string key = (string)header.Key;
620 string value = (string)header.Value; 634 string value = (string)header.Value;
621 requestData.headers.Add(key, value); 635 requestData.headers.Add(key, value);
636 if (key == "cookie")
637 {
638 string[] parts = value.Split(new char[] {'='});
639 if (parts[0] == "agni_sl_session_id" && parts.Length > 1)
640 {
641 string cookie = Uri.UnescapeDataString(parts[1]);
642 string[] crumbs = cookie.Split(new char[] {':'});
643 UUID owner;
644 if (crumbs.Length == 2 && UUID.TryParse(crumbs[0], out owner))
645 {
646 if (crumbs[1].Length == 32)
647 {
648 Scene scene = requestData.scene;
649 if (scene != null)
650 {
651 SceneObjectPart host = scene.GetSceneObjectPart(requestData.hostID);
652 if (host != null)
653 {
654 if (host.OwnerID == owner)
655 requestData.allowResponseType = true;
656 }
657 }
658 }
659 }
660 }
661 }
622 } 662 }
623
624 foreach (DictionaryEntry de in request) 663 foreach (DictionaryEntry de in request)
625 { 664 {
626 if (de.Key.ToString() == "querystringkeys") 665 if (de.Key.ToString() == "querystringkeys")
@@ -631,13 +670,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
631 if (request.ContainsKey(key)) 670 if (request.ContainsKey(key))
632 { 671 {
633 string val = (String)request[key]; 672 string val = (String)request[key];
634 queryString = queryString + key + "=" + val + "&"; 673 if (key != "")
674 {
675 queryString = queryString + key + "=" + val + "&";
676 }
677 else
678 {
679 queryString = queryString + val + "&";
680 }
635 } 681 }
636 } 682 }
637
638 if (queryString.Length > 1) 683 if (queryString.Length > 1)
639 queryString = queryString.Substring(0, queryString.Length - 1); 684 queryString = queryString.Substring(0, queryString.Length - 1);
685
640 } 686 }
687
641 } 688 }
642 689
643 //if this machine is behind DNAT/port forwarding, currently this is being 690 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -645,23 +692,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
645 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 692 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
646 requestData.headers["x-path-info"] = pathInfo; 693 requestData.headers["x-path-info"] = pathInfo;
647 requestData.headers["x-query-string"] = queryString; 694 requestData.headers["x-query-string"] = queryString;
648 requestData.headers["x-script-url"] = urlData.url; 695 requestData.headers["x-script-url"] = url.url;
649 696
650 urlData.requests.Add(requestID, requestData); 697 //requestData.ev = new ManualResetEvent(false);
651 m_RequestMap.Add(requestID, urlData); 698 lock (url.requests)
652 } 699 {
700 url.requests.Add(requestID, requestData);
701 }
702 lock (m_RequestMap)
703 {
704 //add to request map
705 m_RequestMap.Add(requestID, url);
706 }
653 707
654 urlData.engine.PostScriptEvent( 708 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
655 urlData.itemID, 709
656 "http_request", 710 //send initial response?
657 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 711// Hashtable response = new Hashtable();
658 } 712
659 catch (Exception we) 713 return;
660 { 714
661 //Hashtable response = new Hashtable(); 715 }
662 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 716 catch (Exception we)
663 m_log.Warn(we.Message); 717 {
664 m_log.Warn(we.StackTrace); 718 //Hashtable response = new Hashtable();
719 m_log.Warn("[HttpRequestHandler]: http-in request failed");
720 m_log.Warn(we.Message);
721 m_log.Warn(we.StackTrace);
722 }
665 } 723 }
666 } 724 }
667 725
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 6da2222..ad33f23 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -271,6 +271,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
271 return "modInvokeR"; 271 return "modInvokeR";
272 else if (sid.ReturnType == typeof(object[])) 272 else if (sid.ReturnType == typeof(object[]))
273 return "modInvokeL"; 273 return "modInvokeL";
274 else if (sid.ReturnType == typeof(void))
275 return "modInvokeN";
274 276
275 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); 277 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
276 } 278 }
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 4cecd85..2fc89fc 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -861,4 +861,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
861 return null; 861 return null;
862 } 862 }
863 } 863 }
864} \ No newline at end of file 864}
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 2c2c99c..87a0537 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -96,6 +96,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
96 // private static readonly ILog m_log = 96 // private static readonly ILog m_log =
97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
98 98
99 private const int DEBUG_CHANNEL = 2147483647;
100
99 private ListenerManager m_listenerManager; 101 private ListenerManager m_listenerManager;
100 private Queue m_pending; 102 private Queue m_pending;
101 private Queue m_pendingQ; 103 private Queue m_pendingQ;
@@ -366,67 +368,60 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
366 /// <param name='msg'> 368 /// <param name='msg'>
367 /// Message. 369 /// Message.
368 /// </param> 370 /// </param>
369 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, 371 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error)
370 string name, UUID id, string msg)
371 { 372 {
373 error = null;
374
375 if (channel == DEBUG_CHANNEL)
376 return true;
377
372 // Is id an avatar? 378 // Is id an avatar?
373 ScenePresence sp = m_scene.GetScenePresence(target); 379 ScenePresence sp = m_scene.GetScenePresence(target);
374 380
375 if (sp != null) 381 if (sp != null)
376 { 382 {
377 // ignore if a child agent this is restricted to inside one 383 // Send message to avatar
378 // region
379 if (sp.IsChildAgent)
380 return;
381
382 // Send message to the avatar.
383 // Channel zero only goes to the avatar
384 // non zero channel messages only go to the attachments
385 if (channel == 0) 384 if (channel == 0)
386 { 385 {
387 m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), 386 // Channel 0 goes to viewer ONLY
388 pos, name, id, false); 387 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
388 return true;
389 } 389 }
390 else
391 {
392 List<SceneObjectGroup> attachments = sp.GetAttachments();
393 if (attachments.Count == 0)
394 return;
395 390
396 // Get uuid of attachments 391 List<SceneObjectGroup> attachments = sp.GetAttachments();
397 List<UUID> targets = new List<UUID>();
398 foreach (SceneObjectGroup sog in attachments)
399 {
400 if (!sog.IsDeleted)
401 targets.Add(sog.UUID);
402 }
403 392
404 // Need to check each attachment 393 if (attachments.Count == 0)
405 foreach (ListenerInfo li 394 return true;
406 in m_listenerManager.GetListeners(UUID.Zero,
407 channel, name, id, msg))
408 {
409 if (li.GetHostID().Equals(id))
410 continue;
411 395
412 if (m_scene.GetSceneObjectPart( 396 // Get uuid of attachments
413 li.GetHostID()) == null) 397 List<UUID> targets = new List<UUID>();
414 { 398 foreach (SceneObjectGroup sog in attachments)
415 continue; 399 {
416 } 400 if (!sog.IsDeleted)
401 targets.Add(sog.UUID);
402 }
417 403
418 if (targets.Contains(li.GetHostID())) 404 // Need to check each attachment
419 QueueMessage(new ListenerInfo(li, name, id, msg)); 405 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
420 } 406 {
407 if (li.GetHostID().Equals(id))
408 continue;
409
410 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
411 continue;
412
413 if (targets.Contains(li.GetHostID()))
414 QueueMessage(new ListenerInfo(li, name, id, msg));
421 } 415 }
422 416
423 return; 417 return true;
424 } 418 }
425 419
426 // No avatar found so look for an object 420 SceneObjectPart part = m_scene.GetSceneObjectPart(target);
427 foreach (ListenerInfo li 421 if (part == null) // Not even an object
428 in m_listenerManager.GetListeners(UUID.Zero, channel, 422 return true; // No error
429 name, id, msg)) 423
424 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
430 { 425 {
431 // Dont process if this message is from yourself! 426 // Dont process if this message is from yourself!
432 if (li.GetHostID().Equals(id)) 427 if (li.GetHostID().Equals(id))
@@ -444,7 +439,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
444 } 439 }
445 } 440 }
446 441
447 return; 442 return true;
448 } 443 }
449 444
450 protected void QueueMessage(ListenerInfo li) 445 protected void QueueMessage(ListenerInfo li)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
index 16f42a7..f027810 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
@@ -139,6 +139,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
139 139
140 #region IAuthenticationService 140 #region IAuthenticationService
141 141
142 public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
143 {
144 // Not implemented at the regions
145 realID = UUID.Zero;
146 return string.Empty;
147 }
148
142 public string Authenticate(UUID principalID, string password, int lifetime) 149 public string Authenticate(UUID principalID, string password, int lifetime)
143 { 150 {
144 // Not implemented at the regions 151 // Not implemented at the regions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 26d22b8..b61062f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -92,8 +92,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
92 if (config == null) 92 if (config == null)
93 return; 93 return;
94 94
95 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); 95 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime", "-1"));
96 if (refreshminutes <= 0) 96 if (refreshminutes < 0)
97 { 97 {
98 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); 98 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
99 return; 99 return;
@@ -116,12 +116,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
116 return; 116 return;
117 } 117 }
118 118
119 m_refreshTimer.Enabled = true; 119 if (m_refreshtime > 0)
120 m_refreshTimer.AutoReset = true; 120 {
121 m_refreshTimer.Interval = m_refreshtime; 121 m_refreshTimer.Enabled = true;
122 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); 122 m_refreshTimer.AutoReset = true;
123 m_refreshTimer.Interval = m_refreshtime;
124 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
125 }
123 126
124 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", 127 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0} min and service object {1}",
125 refreshminutes, service); 128 refreshminutes, service);
126 129
127 m_enabled = true; 130 m_enabled = true;
@@ -231,4 +234,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
231 } 234 }
232 } 235 }
233 } 236 }
234} \ No newline at end of file 237}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 678f3dc..3be80eb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -314,7 +314,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
314 m_scenes[destination.RegionID].CloseAgent(id, false, auth_token); 314 m_scenes[destination.RegionID].CloseAgent(id, false, auth_token);
315 return true; 315 return true;
316 } 316 }
317
318 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 317 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
319 return false; 318 return false;
320 } 319 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index f45f560..8bd1d10 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -239,7 +239,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
239 return false; 239 return false;
240 } 240 }
241 241
242
243 public bool CloseAgent(GridRegion destination, UUID id, string auth_token) 242 public bool CloseAgent(GridRegion destination, UUID id, string auth_token)
244 { 243 {
245 if (destination == null) 244 if (destination == null)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
index 529bfd7..ea4ade5 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
129 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner 129 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner
130 // user account service?! 130 // user account service?!
131 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService); 131 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService);
132 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
132 } 133 }
133 134
134 public void RemoveRegion(Scene scene) 135 public void RemoveRegion(Scene scene)
@@ -181,6 +182,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
181 return UserAccountService.GetUserAccount(scopeID, Email); 182 return UserAccountService.GetUserAccount(scopeID, Email);
182 } 183 }
183 184
185 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
186 {
187 return null;
188 }
189
184 public List<UserAccount> GetUserAccounts(UUID scopeID, string query) 190 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
185 { 191 {
186 return UserAccountService.GetUserAccounts(scopeID, query); 192 return UserAccountService.GetUserAccounts(scopeID, query);
@@ -195,4 +201,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
195 201
196 #endregion 202 #endregion
197 } 203 }
198} \ No newline at end of file 204}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
index 5aa87d3..afbba30 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
@@ -34,6 +34,7 @@ using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
36using OpenSim.Services.Connectors; 36using OpenSim.Services.Connectors;
37using OpenSim.Framework;
37 38
38using OpenMetaverse; 39using OpenMetaverse;
39 40
@@ -103,6 +104,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
103 return; 104 return;
104 105
105 scene.RegisterModuleInterface<IUserAccountService>(this); 106 scene.RegisterModuleInterface<IUserAccountService>(this);
107 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
108
109 scene.EventManager.OnNewClient += OnNewClient;
106 } 110 }
107 111
108 public void RemoveRegion(Scene scene) 112 public void RemoveRegion(Scene scene)
@@ -117,6 +121,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
117 return; 121 return;
118 } 122 }
119 123
124 // When a user actually enters the sim, clear them from
125 // cache so the sim will have the current values for
126 // flags, title, etc. And country, don't forget country!
127 private void OnNewClient(IClientAPI client)
128 {
129 m_Cache.Remove(client.Name);
130 }
131
120 #region Overwritten methods from IUserAccountService 132 #region Overwritten methods from IUserAccountService
121 133
122 public override UserAccount GetUserAccount(UUID scopeID, UUID userID) 134 public override UserAccount GetUserAccount(UUID scopeID, UUID userID)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
index ddef75f..cbe2eaa 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
@@ -34,7 +34,7 @@ using log4net;
34 34
35namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts 35namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
36{ 36{
37 public class UserAccountCache 37 public class UserAccountCache : IUserAccountCacheModule
38 { 38 {
39 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours! 39 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours!
40 40
@@ -92,5 +92,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
92 92
93 return null; 93 return null;
94 } 94 }
95
96 public void Remove(string name)
97 {
98 if (!m_NameCache.Contains(name))
99 return;
100
101 UUID uuid = UUID.Zero;
102 if (m_NameCache.TryGetValue(name, out uuid))
103 {
104 m_NameCache.Remove(name);
105 m_UUIDCache.Remove(uuid);
106 }
107 }
95 } 108 }
96} 109}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index d451b9e..efc4998 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -490,6 +490,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
490 // being no copy/no mod for everyone 490 // being no copy/no mod for everyone
491 lock (part.TaskInventory) 491 lock (part.TaskInventory)
492 { 492 {
493 if (!ResolveUserUuid(scene, part.CreatorID))
494 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
495
496 if (!ResolveUserUuid(scene, part.OwnerID))
497 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
498
499 if (!ResolveUserUuid(scene, part.LastOwnerID))
500 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
501
502 // And zap any troublesome sit target information
503 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
504 part.SitTargetPosition = new Vector3(0, 0, 0);
505
506 // Fix ownership/creator of inventory items
507 // Not doing so results in inventory items
508 // being no copy/no mod for everyone
509 part.TaskInventory.LockItemsForRead(true);
493 TaskInventoryDictionary inv = part.TaskInventory; 510 TaskInventoryDictionary inv = part.TaskInventory;
494 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 511 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
495 { 512 {
@@ -510,6 +527,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
510 if (!ResolveGroupUuid(kvp.Value.GroupID)) 527 if (!ResolveGroupUuid(kvp.Value.GroupID))
511 kvp.Value.GroupID = UUID.Zero; 528 kvp.Value.GroupID = UUID.Zero;
512 } 529 }
530 part.TaskInventory.LockItemsForRead(false);
513 } 531 }
514 } 532 }
515 533
@@ -899,4 +917,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
899 return dearchivedScenes; 917 return dearchivedScenes;
900 } 918 }
901 } 919 }
902} \ No newline at end of file 920}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 9600023..ada7ecc 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -271,18 +271,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
271 271
272 if (asset != null) 272 if (asset != null)
273 { 273 {
274 if (m_options.ContainsKey("verbose")) 274// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
275 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
276
277 m_foundAssetUuids.Add(asset.FullID); 275 m_foundAssetUuids.Add(asset.FullID);
278 276
279 m_assetsArchiver.WriteAsset(PostProcess(asset)); 277 m_assetsArchiver.WriteAsset(PostProcess(asset));
280 } 278 }
281 else 279 else
282 { 280 {
283 if (m_options.ContainsKey("verbose")) 281// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
284 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
285
286 m_notFoundAssetUuids.Add(new UUID(id)); 282 m_notFoundAssetUuids.Add(new UUID(id));
287 } 283 }
288 284
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 17387da..4750b46 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -331,6 +331,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
332 if (restartModule != null) 332 if (restartModule != null)
333 { 333 {
334 if (timeInSeconds == -1)
335 {
336 m_delayCount++;
337 if (m_delayCount > 3)
338 return;
339
340 restartModule.DelayRestart(3600, "Restart delayed by region manager");
341 return;
342 }
343
334 List<int> times = new List<int>(); 344 List<int> times = new List<int>();
335 while (timeInSeconds > 0) 345 while (timeInSeconds > 0)
336 { 346 {
@@ -1256,6 +1266,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1256 flags |= RegionFlags.AllowParcelChanges; 1266 flags |= RegionFlags.AllowParcelChanges;
1257 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1267 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1258 flags |= RegionFlags.BlockParcelSearch; 1268 flags |= RegionFlags.BlockParcelSearch;
1269 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1270 flags |= (RegionFlags)(1 << 11);
1271 if (Scene.RegionInfo.RegionSettings.Casino)
1272 flags |= (RegionFlags)(1 << 10);
1259 1273
1260 if (Scene.RegionInfo.RegionSettings.FixedSun) 1274 if (Scene.RegionInfo.RegionSettings.FixedSun)
1261 flags |= RegionFlags.SunFixed; 1275 flags |= RegionFlags.SunFixed;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 73c4d6c..399e9b0 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -87,19 +87,21 @@ namespace OpenSim.Region.CoreModules.World.Land
87 /// <value> 87 /// <value>
88 /// Land objects keyed by local id 88 /// Land objects keyed by local id
89 /// </value> 89 /// </value>
90 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 90// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
91
92 //ubit: removed the readonly so i can move it around
93 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
91 94
92 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 95 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
93 96
94 private bool m_allowedForcefulBans = true; 97 private bool m_allowedForcefulBans = true;
98 private UUID DefaultGodParcelGroup;
99 private string DefaultGodParcelName;
95 100
96 // caches ExtendedLandData 101 // caches ExtendedLandData
97 private Cache parcelInfoCache; 102 private Cache parcelInfoCache;
98 103 private Dictionary<UUID, Vector3> forcedPosition =
99 /// <summary> 104 new Dictionary<UUID, Vector3>();
100 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
101 /// </summary>
102 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
103 105
104 #region INonSharedRegionModule Members 106 #region INonSharedRegionModule Members
105 107
@@ -110,6 +112,12 @@ namespace OpenSim.Region.CoreModules.World.Land
110 112
111 public void Initialise(IConfigSource source) 113 public void Initialise(IConfigSource source)
112 { 114 {
115 IConfig cnf = source.Configs["LandManagement"];
116 if (cnf != null)
117 {
118 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
119 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
120 }
113 } 121 }
114 122
115 public void AddRegion(Scene scene) 123 public void AddRegion(Scene scene)
@@ -187,7 +195,6 @@ namespace OpenSim.Region.CoreModules.World.Land
187 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 195 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
188 client.OnSetStartLocationRequest += ClientOnSetHome; 196 client.OnSetStartLocationRequest += ClientOnSetHome;
189 197
190
191 EntityBase presenceEntity; 198 EntityBase presenceEntity;
192 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 199 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
193 { 200 {
@@ -203,48 +210,6 @@ namespace OpenSim.Region.CoreModules.World.Land
203 210
204 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 211 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
205 { 212 {
206 //If we are forcing a position for them to go
207 if (forcedPosition.ContainsKey(remoteClient.AgentId))
208 {
209 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
210
211 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
212 //When the avatar walks into a ban line on the ground, it prevents getting stuck
213 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
214
215 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
216 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
217 {
218// m_log.DebugFormat(
219// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
220// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
221
222 forcedPosition.Remove(remoteClient.AgentId);
223 }
224 //if we are far away, teleport
225 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
226 {
227 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
228// m_log.DebugFormat(
229// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
230// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
231
232 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
233 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
234
235 forcedPosition.Remove(remoteClient.AgentId);
236 }
237 else
238 {
239// m_log.DebugFormat(
240// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
241// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
242
243 //Forces them toward the forced position we want if they aren't there yet
244 agentData.UseClientAgentPosition = true;
245 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
246 }
247 }
248 } 213 }
249 214
250 public void Close() 215 public void Close()
@@ -269,6 +234,7 @@ namespace OpenSim.Region.CoreModules.World.Land
269 { 234 {
270 LandData newData = data.Copy(); 235 LandData newData = data.Copy();
271 newData.LocalID = local_id; 236 newData.LocalID = local_id;
237 ILandObject landobj = null;
272 238
273 ILandObject land; 239 ILandObject land;
274 lock (m_landList) 240 lock (m_landList)
@@ -308,14 +274,14 @@ namespace OpenSim.Region.CoreModules.World.Land
308 protected ILandObject CreateDefaultParcel() 274 protected ILandObject CreateDefaultParcel()
309 { 275 {
310 m_log.DebugFormat( 276 m_log.DebugFormat(
311 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 277 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
312 278
313 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 279 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
314 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 280 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
315 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 281 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
316 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 282 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
317 283
318 return AddLandObject(fullSimParcel); 284 return AddLandObject(fullSimParcel);
319 } 285 }
320 286
321 public List<ILandObject> AllParcels() 287 public List<ILandObject> AllParcels()
@@ -364,10 +330,16 @@ namespace OpenSim.Region.CoreModules.World.Land
364 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 330 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
365 { 331 {
366 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 332 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
367 if (position.HasValue) 333
368 { 334 if (!position.HasValue)
369 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 335 return;
370 } 336
337 bool isFlying = avatar.PhysicsActor.Flying;
338 avatar.RemoveFromPhysicalScene();
339
340 avatar.AbsolutePosition = (Vector3)position;
341
342 avatar.AddToPhysicalScene(isFlying);
371 } 343 }
372 344
373 public void SendYouAreRestrictedNotice(ScenePresence avatar) 345 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -387,29 +359,7 @@ namespace OpenSim.Region.CoreModules.World.Land
387 } 359 }
388 360
389 if (parcelAvatarIsEntering != null) 361 if (parcelAvatarIsEntering != null)
390 { 362 EnforceBans(parcelAvatarIsEntering, avatar);
391 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
392 {
393 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
394 {
395 SendYouAreBannedNotice(avatar);
396 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
397 }
398 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
399 {
400 SendYouAreRestrictedNotice(avatar);
401 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
402 }
403 else
404 {
405 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
406 }
407 }
408 else
409 {
410 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
411 }
412 }
413 } 363 }
414 } 364 }
415 365
@@ -438,30 +388,51 @@ namespace OpenSim.Region.CoreModules.World.Land
438 388
439 public void SendLandUpdate(ScenePresence avatar, bool force) 389 public void SendLandUpdate(ScenePresence avatar, bool force)
440 { 390 {
391
392 /* stop sendind same data twice
393 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
394 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
395
396 if (over != null)
397 {
398
399 if (force)
400 {
401 if (!avatar.IsChildAgent)
402 {
403 over.SendLandUpdateToClient(avatar.ControllingClient);
404 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
405 m_scene.RegionInfo.RegionID);
406 }
407 }
408
409 if (avatar.currentParcelUUID != over.LandData.GlobalID)
410 {
411 if (!avatar.IsChildAgent)
412 {
413 over.SendLandUpdateToClient(avatar.ControllingClient);
414 avatar.currentParcelUUID = over.LandData.GlobalID;
415 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
416 m_scene.RegionInfo.RegionID);
417 }
418 }
419 */
420 if (avatar.IsChildAgent)
421 return;
422
441 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 423 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
442 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 424 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
443 425
444 if (over != null) 426 if (over != null)
445 { 427 {
446 if (force) 428 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
447 { 429 if (force || NotsameID)
448 if (!avatar.IsChildAgent)
449 {
450 over.SendLandUpdateToClient(avatar.ControllingClient);
451 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
452 m_scene.RegionInfo.RegionID);
453 }
454 }
455
456 if (avatar.currentParcelUUID != over.LandData.GlobalID)
457 { 430 {
458 if (!avatar.IsChildAgent) 431 over.SendLandUpdateToClient(avatar.ControllingClient);
459 { 432 if (NotsameID)
460 over.SendLandUpdateToClient(avatar.ControllingClient);
461 avatar.currentParcelUUID = over.LandData.GlobalID; 433 avatar.currentParcelUUID = over.LandData.GlobalID;
462 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 434 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
463 m_scene.RegionInfo.RegionID); 435 m_scene.RegionInfo.RegionID);
464 }
465 } 436 }
466 } 437 }
467 } 438 }
@@ -513,6 +484,7 @@ namespace OpenSim.Region.CoreModules.World.Land
513 //when we are finally in a safe place, lets release the forced position lock 484 //when we are finally in a safe place, lets release the forced position lock
514 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 485 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
515 } 486 }
487 EnforceBans(parcel, clientAvatar);
516 } 488 }
517 } 489 }
518 490
@@ -663,27 +635,28 @@ namespace OpenSim.Region.CoreModules.World.Land
663 /// </summary> 635 /// </summary>
664 public void Clear(bool setupDefaultParcel) 636 public void Clear(bool setupDefaultParcel)
665 { 637 {
666 List<ILandObject> parcels; 638 Dictionary<int, ILandObject> landworkList;
639 // move to work pointer since we are deleting it all
667 lock (m_landList) 640 lock (m_landList)
668 { 641 {
669 parcels = new List<ILandObject>(m_landList.Values); 642 landworkList = m_landList;
643 m_landList = new Dictionary<int, ILandObject>();
670 } 644 }
671 645
672 foreach (ILandObject lo in parcels) 646 // this 2 methods have locks (now)
647 ResetSimLandObjects();
648
649 if (setupDefaultParcel)
650 CreateDefaultParcel();
651
652 // fire outside events unlocked
653 foreach (ILandObject lo in landworkList.Values)
673 { 654 {
674 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 655 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
675 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 656 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
676 } 657 }
658 landworkList.Clear();
677 659
678 lock (m_landList)
679 {
680 m_landList.Clear();
681
682 ResetSimLandObjects();
683 }
684
685 if (setupDefaultParcel)
686 CreateDefaultParcel();
687 } 660 }
688 661
689 private void performFinalLandJoin(ILandObject master, ILandObject slave) 662 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -730,7 +703,7 @@ namespace OpenSim.Region.CoreModules.World.Land
730 int x; 703 int x;
731 int y; 704 int y;
732 705
733 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 706 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
734 return null; 707 return null;
735 708
736 try 709 try
@@ -780,14 +753,13 @@ namespace OpenSim.Region.CoreModules.World.Land
780 { 753 {
781 try 754 try
782 { 755 {
783 return m_landList[m_landIDList[x / 4, y / 4]]; 756 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
757 return m_landList[m_landIDList[x / 4, y / 4]];
758 //else
759 // return null;
784 } 760 }
785 catch (IndexOutOfRangeException) 761 catch (IndexOutOfRangeException)
786 { 762 {
787// m_log.WarnFormat(
788// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
789// x, y, m_scene.RegionInfo.RegionName);
790
791 return null; 763 return null;
792 } 764 }
793 } 765 }
@@ -946,6 +918,8 @@ namespace OpenSim.Region.CoreModules.World.Land
946 newLand.LandData.Name = newLand.LandData.Name; 918 newLand.LandData.Name = newLand.LandData.Name;
947 newLand.LandData.GlobalID = UUID.Random(); 919 newLand.LandData.GlobalID = UUID.Random();
948 newLand.LandData.Dwell = 0; 920 newLand.LandData.Dwell = 0;
921 // Clear "Show in search" on the cut out parcel to prevent double-charging
922 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
949 923
950 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 924 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
951 925
@@ -1071,6 +1045,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1071 //Owner Flag 1045 //Owner Flag
1072 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1046 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1073 } 1047 }
1048 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1049 {
1050 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1051 }
1074 else if (currentParcelBlock.LandData.SalePrice > 0 && 1052 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1075 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1053 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1076 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1054 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1151,8 +1129,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1151 { 1129 {
1152 if (!temp.Contains(currentParcel)) 1130 if (!temp.Contains(currentParcel))
1153 { 1131 {
1154 currentParcel.ForceUpdateLandInfo(); 1132 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1155 temp.Add(currentParcel); 1133 {
1134 currentParcel.ForceUpdateLandInfo();
1135 temp.Add(currentParcel);
1136 }
1156 } 1137 }
1157 } 1138 }
1158 } 1139 }
@@ -1371,8 +1352,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1371 1352
1372 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1353 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1373 { 1354 {
1374// m_log.DebugFormat( 1355 Dictionary<int, ILandObject> landworkList;
1375// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); 1356 // move to work pointer since we are deleting it all
1357 lock (m_landList)
1358 {
1359 landworkList = m_landList;
1360 m_landList = new Dictionary<int, ILandObject>();
1361 }
1362
1363 //Remove all the land objects in the sim and then process our new data
1364 foreach (int n in landworkList.Keys)
1365 {
1366 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1367 }
1368 landworkList.Clear();
1369
1370 lock (m_landList)
1371 {
1372 m_landIDList.Initialize();
1373 m_landList.Clear();
1374 }
1376 1375
1377 for (int i = 0; i < data.Count; i++) 1376 for (int i = 0; i < data.Count; i++)
1378 IncomingLandObjectFromStorage(data[i]); 1377 IncomingLandObjectFromStorage(data[i]);
@@ -1380,10 +1379,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1380 1379
1381 public void IncomingLandObjectFromStorage(LandData data) 1380 public void IncomingLandObjectFromStorage(LandData data)
1382 { 1381 {
1382
1383 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1383 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1384 new_land.LandData = data.Copy(); 1384 new_land.LandData = data.Copy();
1385 new_land.SetLandBitmapFromByteArray(); 1385 new_land.SetLandBitmapFromByteArray();
1386 AddLandObject(new_land); 1386 AddLandObject(new_land);
1387 new_land.SendLandUpdateToAvatarsOverMe();
1387 } 1388 }
1388 1389
1389 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1390 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1714,7 +1715,86 @@ namespace OpenSim.Region.CoreModules.World.Land
1714 1715
1715 UpdateLandObject(localID, land.LandData); 1716 UpdateLandObject(localID, land.LandData);
1716 } 1717 }
1717 1718
1719 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1720 {
1721 ILandObject land = null;
1722 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1723 foreach (ILandObject landObject in Land)
1724 {
1725 if (landObject.LandData.LocalID == landID)
1726 {
1727 land = landObject;
1728 }
1729 }
1730 land.DeedToGroup(DefaultGodParcelGroup);
1731 land.LandData.Name = DefaultGodParcelName;
1732 land.SendLandUpdateToAvatarsOverMe();
1733 }
1734
1735 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1736 {
1737 ScenePresence SP;
1738 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1739 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1740 if (SP.UserLevel != 0)
1741 {
1742 if (flags == 0) //All parcels, scripted or not
1743 {
1744 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1745 {
1746 if (e.OwnerID == targetID)
1747 {
1748 returns.Add(e);
1749 }
1750 }
1751 );
1752 }
1753 if (flags == 4) //All parcels, scripted object
1754 {
1755 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1756 {
1757 if (e.OwnerID == targetID)
1758 {
1759 if (e.ContainsScripts())
1760 {
1761 returns.Add(e);
1762 }
1763 }
1764 }
1765 );
1766 }
1767 if (flags == 4) //not target parcel, scripted object
1768 {
1769 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1770 {
1771 if (e.OwnerID == targetID)
1772 {
1773 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1774 if (landobject.LandData.OwnerID != e.OwnerID)
1775 {
1776 if (e.ContainsScripts())
1777 {
1778 returns.Add(e);
1779 }
1780 }
1781 }
1782 }
1783 );
1784 }
1785 foreach (SceneObjectGroup ol in returns)
1786 {
1787 ReturnObject(ol, client);
1788 }
1789 }
1790 }
1791 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1792 {
1793 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1794 objs[0] = obj;
1795 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1796 }
1797
1718 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 1798 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1719 1799
1720 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1800 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1750,7 +1830,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1750 } 1830 }
1751 } 1831 }
1752 } 1832 }
1753
1754 private void OnEndParcelFrozen(object avatar) 1833 private void OnEndParcelFrozen(object avatar)
1755 { 1834 {
1756 ScenePresence targetAvatar = (ScenePresence)avatar; 1835 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -1761,6 +1840,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1761 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); 1840 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1762 } 1841 }
1763 1842
1843
1764 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1844 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1765 { 1845 {
1766 ScenePresence targetAvatar = null; 1846 ScenePresence targetAvatar = null;
@@ -1780,12 +1860,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1780 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 1860 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1781 !m_scene.Permissions.IsAdministrator(client.AgentId)) 1861 !m_scene.Permissions.IsAdministrator(client.AgentId))
1782 return; 1862 return;
1863
1783 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 1864 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1784 1865
1785 targetAvatar.TeleportWithMomentum(pos, null); 1866 targetAvatar.TeleportWithMomentum(pos, null);
1786 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 1867 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1787 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 1868 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1788 1869
1789 if ((flags & 1) != 0) // Ban TODO: Remove magic number 1870 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1790 { 1871 {
1791 LandAccessEntry entry = new LandAccessEntry(); 1872 LandAccessEntry entry = new LandAccessEntry();
@@ -1942,6 +2023,30 @@ namespace OpenSim.Region.CoreModules.World.Land
1942 ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, m_userManager.GetUserName(ld.OwnerID)); 2023 ld.Name, ld.LocalID, ld.Area, lo.StartPoint, lo.EndPoint, m_userManager.GetUserName(ld.OwnerID));
1943 } 2024 }
1944 } 2025 }
2026
2027 MainConsole.Instance.Output(report.ToString());
2028 }
2029
2030 public void EnforceBans(ILandObject land, ScenePresence avatar)
2031 {
2032 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
2033 return;
2034
2035 if (land.IsEitherBannedOrRestricted(avatar.UUID))
2036 {
2037 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
2038 {
2039 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
2040 if (pos == null)
2041 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
2042 else
2043 ForceAvatarToPosition(avatar, (Vector3)pos);
2044 }
2045 else
2046 {
2047 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
2048 }
2049 }
1945 } 2050 }
1946 2051
1947 private void AppendParcelReport(StringBuilder report, ILandObject lo) 2052 private void AppendParcelReport(StringBuilder report, ILandObject lo)
@@ -2007,4 +2112,4 @@ namespace OpenSim.Region.CoreModules.World.Land
2007 cdl.AddToStringBuilder(report); 2112 cdl.AddToStringBuilder(report);
2008 } 2113 }
2009 } 2114 }
2010} \ No newline at end of file 2115}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index e55c9ed..ce4bd0f 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -51,6 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land
51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 51 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
52 52
53 private int m_lastSeqId = 0; 53 private int m_lastSeqId = 0;
54 private int m_expiryCounter = 0;
54 55
55 protected LandData m_landData = new LandData(); 56 protected LandData m_landData = new LandData();
56 protected Scene m_scene; 57 protected Scene m_scene;
@@ -136,6 +137,8 @@ namespace OpenSim.Region.CoreModules.World.Land
136 else 137 else
137 LandData.GroupID = UUID.Zero; 138 LandData.GroupID = UUID.Zero;
138 LandData.IsGroupOwned = is_group_owned; 139 LandData.IsGroupOwned = is_group_owned;
140
141 m_scene.EventManager.OnFrame += OnFrame;
139 } 142 }
140 143
141 #endregion 144 #endregion
@@ -194,10 +197,27 @@ namespace OpenSim.Region.CoreModules.World.Land
194 else 197 else
195 { 198 {
196 // Normal Calculations 199 // Normal Calculations
197 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 200 int parcelMax = (int)((long)LandData.Area
198 * (float)m_scene.RegionInfo.ObjectCapacity 201 * (long)m_scene.RegionInfo.ObjectCapacity
199 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 202 * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
200 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 203 / 65536L);
204 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
205 return parcelMax;
206 }
207 }
208
209 private int GetParcelBasePrimCount()
210 {
211 if (overrideParcelMaxPrimCount != null)
212 {
213 return overrideParcelMaxPrimCount(this);
214 }
215 else
216 {
217 // Normal Calculations
218 int parcelMax = (int)((long)LandData.Area
219 * (long)m_scene.RegionInfo.ObjectCapacity
220 / 65536L);
201 return parcelMax; 221 return parcelMax;
202 } 222 }
203 } 223 }
@@ -211,8 +231,9 @@ namespace OpenSim.Region.CoreModules.World.Land
211 else 231 else
212 { 232 {
213 //Normal Calculations 233 //Normal Calculations
214 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 234 int simMax = (int)((long)LandData.SimwideArea
215 * (float)m_scene.RegionInfo.ObjectCapacity); 235 * (long)m_scene.RegionInfo.ObjectCapacity / 65536L);
236 // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
216 return simMax; 237 return simMax;
217 } 238 }
218 } 239 }
@@ -242,7 +263,7 @@ namespace OpenSim.Region.CoreModules.World.Land
242 remote_client.SendLandProperties(seq_id, 263 remote_client.SendLandProperties(seq_id,
243 snap_selection, request_result, this, 264 snap_selection, request_result, this,
244 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 265 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
245 GetParcelMaxPrimCount(), 266 GetParcelBasePrimCount(),
246 GetSimulatorMaxPrimCount(), regionFlags); 267 GetSimulatorMaxPrimCount(), regionFlags);
247 } 268 }
248 269
@@ -302,7 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Land
302 323
303 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 324 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
304 ParcelFlags.AllowPublish | 325 ParcelFlags.AllowPublish |
305 ParcelFlags.MaturePublish); 326 ParcelFlags.MaturePublish) | (uint)(1 << 23);
306 } 327 }
307 328
308 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 329 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity))
@@ -414,6 +435,19 @@ namespace OpenSim.Region.CoreModules.World.Land
414 return false; 435 return false;
415 } 436 }
416 437
438 public bool CanBeOnThisLand(UUID avatar, float posHeight)
439 {
440 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
441 {
442 return false;
443 }
444 else if (IsRestrictedFromLand(avatar))
445 {
446 return false;
447 }
448 return true;
449 }
450
417 public bool HasGroupAccess(UUID avatar) 451 public bool HasGroupAccess(UUID avatar)
418 { 452 {
419 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 453 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
@@ -1178,6 +1212,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1178 1212
1179 #endregion 1213 #endregion
1180 1214
1215 private void OnFrame()
1216 {
1217 m_expiryCounter++;
1218
1219 if (m_expiryCounter >= 50)
1220 {
1221 ExpireAccessList();
1222 m_expiryCounter = 0;
1223 }
1224 }
1225
1181 private void ExpireAccessList() 1226 private void ExpireAccessList()
1182 { 1227 {
1183 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1228 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1188,7 +1233,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1188 delete.Add(entry); 1233 delete.Add(entry);
1189 } 1234 }
1190 foreach (LandAccessEntry entry in delete) 1235 foreach (LandAccessEntry entry in delete)
1236 {
1191 LandData.ParcelAccessList.Remove(entry); 1237 LandData.ParcelAccessList.Remove(entry);
1238 ScenePresence presence;
1239
1240 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1241 {
1242 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1243 if (land.LandData.LocalID == LandData.LocalID)
1244 {
1245 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1246 presence.TeleportWithMomentum(pos, null);
1247 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1248 }
1249 }
1250 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1251 }
1192 1252
1193 if (delete.Count > 0) 1253 if (delete.Count > 0)
1194 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1254 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this);
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 9b51cc8..771fdd2 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -207,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Land
207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) 207 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
208 { 208 {
209 UUID landOwner = landData.OwnerID; 209 UUID landOwner = landData.OwnerID;
210 int partCount = obj.Parts.Length; 210 int partCount = obj.GetPartCount();
211 211
212 m_SimwideCounts[landOwner] += partCount; 212 m_SimwideCounts[landOwner] += partCount;
213 if (parcelCounts.Users.ContainsKey(obj.OwnerID)) 213 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
@@ -597,4 +597,4 @@ namespace OpenSim.Region.CoreModules.World.Land
597 } 597 }
598 } 598 }
599 } 599 }
600} \ No newline at end of file 600}
diff --git a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
index 0a4e83e..f13d648 100644
--- a/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
+++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
@@ -190,6 +190,9 @@ namespace OpenSim.Region.CoreModules.World.LightShare
190 190
191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl) 191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl)
192 { 192 {
193 if (client == null)
194 return;
195
193 if (m_enableWindlight) 196 if (m_enableWindlight)
194 { 197 {
195 if (m_scene.RegionInfo.WindlightSettings.valid) 198 if (m_scene.RegionInfo.WindlightSettings.valid)
@@ -207,8 +210,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
207 210
208 private void EventManager_OnMakeRootAgent(ScenePresence presence) 211 private void EventManager_OnMakeRootAgent(ScenePresence presence)
209 { 212 {
210// m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client {0}", presence.Name); 213 if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
211 214 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
212 SendProfileToClient(presence.ControllingClient); 215 SendProfileToClient(presence.ControllingClient);
213 } 216 }
214 217
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index 22a53a8..28daf2f 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -177,6 +177,13 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
177 return false; 177 return false;
178 } 178 }
179 179
180 if ((perms & (uint)PermissionMask.Copy) == 0)
181 {
182 if (m_dialogModule != null)
183 m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system");
184 return false;
185 }
186
180 AssetBase asset = m_scene.CreateAsset( 187 AssetBase asset = m_scene.CreateAsset(
181 group.GetPartName(localID), 188 group.GetPartName(localID),
182 group.GetPartDescription(localID), 189 group.GetPartDescription(localID),
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index f8e93e1..50855fe 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -42,8 +42,8 @@ using PermissionMask = OpenSim.Framework.PermissionMask;
42 42
43namespace OpenSim.Region.CoreModules.World.Permissions 43namespace OpenSim.Region.CoreModules.World.Permissions
44{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PermissionsModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultPermissionsModule")]
46 public class PermissionsModule : INonSharedRegionModule, IPermissionsModule 46 public class DefaultPermissionsModule : INonSharedRegionModule, IPermissionsModule
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
@@ -348,7 +348,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
348 348
349 public string Name 349 public string Name
350 { 350 {
351 get { return "PermissionsModule"; } 351 get { return "DefaultPermissionsModule"; }
352 } 352 }
353 353
354 public Type ReplaceableInterface 354 public Type ReplaceableInterface
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 75a8295..0c74b49 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -29,6 +29,8 @@ using System;
29using System.Linq; 29using System.Linq;
30using System.Reflection; 30using System.Reflection;
31using System.Timers; 31using System.Timers;
32using System.IO;
33using System.Diagnostics;
32using System.Threading; 34using System.Threading;
33using System.Collections.Generic; 35using System.Collections.Generic;
34using log4net; 36using log4net;
@@ -57,13 +59,24 @@ namespace OpenSim.Region.CoreModules.World.Region
57 protected UUID m_Initiator; 59 protected UUID m_Initiator;
58 protected bool m_Notice = false; 60 protected bool m_Notice = false;
59 protected IDialogModule m_DialogModule = null; 61 protected IDialogModule m_DialogModule = null;
62 protected string m_MarkerPath = String.Empty;
63 private int[] m_CurrentAlerts = null;
60 64
61 public void Initialise(IConfigSource config) 65 public void Initialise(IConfigSource config)
62 { 66 {
67 IConfig restartConfig = config.Configs["RestartModule"];
68 if (restartConfig != null)
69 {
70 m_MarkerPath = restartConfig.GetString("MarkerPath", String.Empty);
71 }
63 } 72 }
64 73
65 public void AddRegion(Scene scene) 74 public void AddRegion(Scene scene)
66 { 75 {
76 if (m_MarkerPath != String.Empty)
77 File.Delete(Path.Combine(m_MarkerPath,
78 scene.RegionInfo.RegionID.ToString()));
79
67 m_Scene = scene; 80 m_Scene = scene;
68 81
69 scene.RegisterModuleInterface<IRestartModule>(this); 82 scene.RegisterModuleInterface<IRestartModule>(this);
@@ -122,6 +135,7 @@ namespace OpenSim.Region.CoreModules.World.Region
122 135
123 if (alerts == null) 136 if (alerts == null)
124 { 137 {
138 CreateMarkerFile();
125 m_Scene.RestartNow(); 139 m_Scene.RestartNow();
126 return; 140 return;
127 } 141 }
@@ -129,25 +143,28 @@ namespace OpenSim.Region.CoreModules.World.Region
129 m_Message = message; 143 m_Message = message;
130 m_Initiator = initiator; 144 m_Initiator = initiator;
131 m_Notice = notice; 145 m_Notice = notice;
146 m_CurrentAlerts = alerts;
132 m_Alerts = new List<int>(alerts); 147 m_Alerts = new List<int>(alerts);
133 m_Alerts.Sort(); 148 m_Alerts.Sort();
134 m_Alerts.Reverse(); 149 m_Alerts.Reverse();
135 150
136 if (m_Alerts[0] == 0) 151 if (m_Alerts[0] == 0)
137 { 152 {
153 CreateMarkerFile();
138 m_Scene.RestartNow(); 154 m_Scene.RestartNow();
139 return; 155 return;
140 } 156 }
141 157
142 int nextInterval = DoOneNotice(); 158 int nextInterval = DoOneNotice(true);
143 159
144 SetTimer(nextInterval); 160 SetTimer(nextInterval);
145 } 161 }
146 162
147 public int DoOneNotice() 163 public int DoOneNotice(bool sendOut)
148 { 164 {
149 if (m_Alerts.Count == 0 || m_Alerts[0] == 0) 165 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
150 { 166 {
167 CreateMarkerFile();
151 m_Scene.RestartNow(); 168 m_Scene.RestartNow();
152 return 0; 169 return 0;
153 } 170 }
@@ -168,34 +185,37 @@ namespace OpenSim.Region.CoreModules.World.Region
168 185
169 m_Alerts.RemoveAt(0); 186 m_Alerts.RemoveAt(0);
170 187
171 int minutes = currentAlert / 60; 188 if (sendOut)
172 string currentAlertString = String.Empty;
173 if (minutes > 0)
174 { 189 {
175 if (minutes == 1) 190 int minutes = currentAlert / 60;
176 currentAlertString += "1 minute"; 191 string currentAlertString = String.Empty;
177 else 192 if (minutes > 0)
178 currentAlertString += String.Format("{0} minutes", minutes); 193 {
194 if (minutes == 1)
195 currentAlertString += "1 minute";
196 else
197 currentAlertString += String.Format("{0} minutes", minutes);
198 if ((currentAlert % 60) != 0)
199 currentAlertString += " and ";
200 }
179 if ((currentAlert % 60) != 0) 201 if ((currentAlert % 60) != 0)
180 currentAlertString += " and "; 202 {
181 } 203 int seconds = currentAlert % 60;
182 if ((currentAlert % 60) != 0) 204 if (seconds == 1)
183 { 205 currentAlertString += "1 second";
184 int seconds = currentAlert % 60; 206 else
185 if (seconds == 1) 207 currentAlertString += String.Format("{0} seconds", seconds);
186 currentAlertString += "1 second"; 208 }
187 else
188 currentAlertString += String.Format("{0} seconds", seconds);
189 }
190 209
191 string msg = String.Format(m_Message, currentAlertString); 210 string msg = String.Format(m_Message, currentAlertString);
192 211
193 if (m_DialogModule != null && msg != String.Empty) 212 if (m_DialogModule != null && msg != String.Empty)
194 { 213 {
195 if (m_Notice) 214 if (m_Notice)
196 m_DialogModule.SendGeneralAlert(msg); 215 m_DialogModule.SendGeneralAlert(msg);
197 else 216 else
198 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg); 217 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
218 }
199 } 219 }
200 220
201 return currentAlert - nextAlert; 221 return currentAlert - nextAlert;
@@ -226,7 +246,27 @@ namespace OpenSim.Region.CoreModules.World.Region
226 246
227 private void OnTimer(object source, ElapsedEventArgs e) 247 private void OnTimer(object source, ElapsedEventArgs e)
228 { 248 {
229 SetTimer(DoOneNotice()); 249 int nextInterval = DoOneNotice(true);
250
251 SetTimer(nextInterval);
252 }
253
254 public void DelayRestart(int seconds, string message)
255 {
256 if (m_CountdownTimer == null)
257 return;
258
259 m_CountdownTimer.Stop();
260 m_CountdownTimer = null;
261
262 m_Alerts = new List<int>(m_CurrentAlerts);
263 m_Alerts.Add(seconds);
264 m_Alerts.Sort();
265 m_Alerts.Reverse();
266
267 int nextInterval = DoOneNotice(false);
268
269 SetTimer(nextInterval);
230 } 270 }
231 271
232 public void AbortRestart(string message) 272 public void AbortRestart(string message)
@@ -238,6 +278,9 @@ namespace OpenSim.Region.CoreModules.World.Region
238 if (m_DialogModule != null && message != String.Empty) 278 if (m_DialogModule != null && message != String.Empty)
239 m_DialogModule.SendGeneralAlert(message); 279 m_DialogModule.SendGeneralAlert(message);
240 } 280 }
281 if (m_MarkerPath != String.Empty)
282 File.Delete(Path.Combine(m_MarkerPath,
283 m_Scene.RegionInfo.RegionID.ToString()));
241 } 284 }
242 285
243 private void HandleRegionRestart(string module, string[] args) 286 private void HandleRegionRestart(string module, string[] args)
@@ -282,5 +325,25 @@ namespace OpenSim.Region.CoreModules.World.Region
282 325
283 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 326 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
284 } 327 }
328
329 protected void CreateMarkerFile()
330 {
331 if (m_MarkerPath == String.Empty)
332 return;
333
334 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
335 try
336 {
337 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
338 FileStream fs = File.Create(path);
339 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
340 Byte[] buf = enc.GetBytes(pidstring);
341 fs.Write(buf, 0, buf.Length);
342 fs.Close();
343 }
344 catch (Exception)
345 {
346 }
347 }
285 } 348 }
286} \ No newline at end of file 349}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index fd30c46..4d738a5 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -644,6 +644,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
644 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); 644 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
645 m_scene.SaveTerrain(); 645 m_scene.SaveTerrain();
646 646
647 m_scene.EventManager.TriggerTerrainUpdate();
648
647 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. 649 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out.
648 //m_scene.CreateTerrainTexture(true); 650 //m_scene.CreateTerrainTexture(true);
649 } 651 }
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index ed2b06a..d38f34b 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -65,6 +65,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
65 private bool m_useAntiAliasing = false; // TODO: Make this a config option 65 private bool m_useAntiAliasing = false; // TODO: Make this a config option
66 private bool m_Enabled = false; 66 private bool m_Enabled = false;
67 67
68 private Bitmap lastImage = null;
69 private DateTime lastImageTime = DateTime.MinValue;
70
68 #region Region Module interface 71 #region Region Module interface
69 72
70 public void Initialise(IConfigSource source) 73 public void Initialise(IConfigSource source)
@@ -87,14 +90,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
87 90
88 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 91 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
89 if (renderers.Count > 0) 92 if (renderers.Count > 0)
90 { 93 m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]);
91 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
92 m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher);
93 }
94 else 94 else
95 { 95 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
96 m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled");
97 }
98 96
99 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 97 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
100 } 98 }
@@ -127,9 +125,25 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
127 125
128 public Bitmap CreateMapTile() 126 public Bitmap CreateMapTile()
129 { 127 {
128 if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
129 {
130 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
131 }
132
133 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
134 if (renderers.Count > 0)
135 {
136 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
137 }
138
130 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); 139 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f);
131 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); 140 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize);
132 return CreateMapTile(viewport, false); 141 Bitmap tile = CreateMapTile(viewport, false);
142 m_primMesher = null;
143
144 lastImage = tile;
145 lastImageTime = DateTime.Now;
146 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
133 } 147 }
134 148
135 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) 149 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 708a9a2..14deeb6 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -128,85 +128,93 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
128 128
129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
130 { 130 {
131 List<MapBlockData> blocks = new List<MapBlockData>(); 131 Util.FireAndForget(x =>
132 MapBlockData data;
133 if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4))
134 { 132 {
133 if (mapName.Length < 2)
134 {
135 remoteClient.SendAlertMessage("Use a search string with at least 2 characters");
136 return;
137 }
138
139 //m_log.DebugFormat("MAP NAME=({0})", mapName);
140
141 // Hack to get around the fact that ll V3 now drops the port from the
142 // map name. See https://jira.secondlife.com/browse/VWR-28570
143 //
144 // Caller, use this magic form instead:
145 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
146 // or url encode if possible.
147 // the hacks we do with this viewer...
148 //
149 string mapNameOrig = mapName;
150 if (mapName.Contains("|"))
151 mapName = mapName.Replace('|', ':');
152 if (mapName.Contains("+"))
153 mapName = mapName.Replace('+', ' ');
154 if (mapName.Contains("!"))
155 mapName = mapName.Replace('!', '/');
156
157 // try to fetch from GridServer
158 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
159 // if (regionInfos.Count == 0)
160 // remoteClient.SendAlertMessage("Hyperlink could not be established.");
161
162 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
163 List<MapBlockData> blocks = new List<MapBlockData>();
164
165 MapBlockData data;
166 if (regionInfos.Count > 0)
167 {
168 foreach (GridRegion info in regionInfos)
169 {
170 data = new MapBlockData();
171 data.Agents = 0;
172 data.Access = info.Access;
173 if (flags == 2) // V2 sends this
174 data.MapImageId = UUID.Zero;
175 else
176 data.MapImageId = info.TerrainImage;
177 // ugh! V2-3 is very sensitive about the result being
178 // exactly the same as the requested name
179 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
180 data.Name = mapNameOrig;
181 else
182 data.Name = info.RegionName;
183 data.RegionFlags = 0; // TODO not used?
184 data.WaterHeight = 0; // not used
185 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
186 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
187 blocks.Add(data);
188 }
189 }
190
135 // final block, closing the search result 191 // final block, closing the search result
136 AddFinalBlock(blocks); 192 data = new MapBlockData();
193 data.Agents = 0;
194 data.Access = 255;
195 data.MapImageId = UUID.Zero;
196 data.Name = mapName;
197 data.RegionFlags = 0;
198 data.WaterHeight = 0; // not used
199 data.X = 0;
200 data.Y = 0;
201 blocks.Add(data);
137 202
138 // flags are agent flags sent from the viewer. 203 // flags are agent flags sent from the viewer.
139 // they have different values depending on different viewers, apparently 204 // they have different values depending on different viewers, apparently
140 remoteClient.SendMapBlock(blocks, flags); 205 remoteClient.SendMapBlock(blocks, flags);
141 remoteClient.SendAlertMessage("Use a search string with at least 3 characters");
142 return;
143 }
144
145 206
146 //m_log.DebugFormat("MAP NAME=({0})", mapName); 207 // send extra user messages for V3
147 208 // because the UI is very confusing
148 // Hack to get around the fact that ll V3 now drops the port from the 209 // while we don't fix the hard-coded urls
149 // map name. See https://jira.secondlife.com/browse/VWR-28570 210 if (flags == 2)
150 //
151 // Caller, use this magic form instead:
152 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
153 // or url encode if possible.
154 // the hacks we do with this viewer...
155 //
156 string mapNameOrig = mapName;
157 if (mapName.Contains("|"))
158 mapName = mapName.Replace('|', ':');
159 if (mapName.Contains("+"))
160 mapName = mapName.Replace('+', ' ');
161 if (mapName.Contains("!"))
162 mapName = mapName.Replace('!', '/');
163
164 // try to fetch from GridServer
165 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
166
167 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags);
168 if (regionInfos.Count > 0)
169 {
170 foreach (GridRegion info in regionInfos)
171 { 211 {
172 data = new MapBlockData(); 212 if (regionInfos.Count == 0)
173 data.Agents = 0; 213 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
174 data.Access = info.Access; 214// else if (regionInfos.Count == 1)
175 if (flags == 2) // V2 sends this 215// remoteClient.SendAgentAlertMessage("Region found!", false);
176 data.MapImageId = UUID.Zero;
177 else
178 data.MapImageId = info.TerrainImage;
179 // ugh! V2-3 is very sensitive about the result being
180 // exactly the same as the requested name
181 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
182 data.Name = mapNameOrig;
183 else
184 data.Name = info.RegionName;
185 data.RegionFlags = 0; // TODO not used?
186 data.WaterHeight = 0; // not used
187 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
188 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
189 blocks.Add(data);
190 } 216 }
191 } 217 });
192
193 // final block, closing the search result
194 AddFinalBlock(blocks);
195
196 // flags are agent flags sent from the viewer.
197 // they have different values depending on different viewers, apparently
198 remoteClient.SendMapBlock(blocks, flags);
199
200 // send extra user messages for V3
201 // because the UI is very confusing
202 // while we don't fix the hard-coded urls
203 if (flags == 2)
204 {
205 if (regionInfos.Count == 0)
206 remoteClient.SendAlertMessage("No regions found with that name.");
207 else if (regionInfos.Count == 1)
208 remoteClient.SendAlertMessage("Region found!");
209 }
210 } 218 }
211 219
212 private void AddFinalBlock(List<MapBlockData> blocks) 220 private void AddFinalBlock(List<MapBlockData> blocks)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index cdf1467..98fa763 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -66,7 +66,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
66 private static readonly UUID STOP_UUID = UUID.Random(); 66 private static readonly UUID STOP_UUID = UUID.Random();
67 private static readonly string m_mapLayerPath = "0001/"; 67 private static readonly string m_mapLayerPath = "0001/";
68 68
69 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 69 private ManualResetEvent queueEvent = new ManualResetEvent(false);
70 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
71
72 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
73 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
70 74
71 protected Scene m_scene; 75 protected Scene m_scene;
72 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 76 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
@@ -74,15 +78,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
74 private int blacklistTimeout = 10*60*1000; // 10 minutes 78 private int blacklistTimeout = 10*60*1000; // 10 minutes
75 private byte[] myMapImageJPEG; 79 private byte[] myMapImageJPEG;
76 protected volatile bool m_Enabled = false; 80 protected volatile bool m_Enabled = false;
77 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
78 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 81 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
79 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 82 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
80 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 83 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
81 private List<UUID> m_rootAgents = new List<UUID>(); 84 private List<UUID> m_rootAgents = new List<UUID>();
82 private volatile bool threadrunning = false; 85 private volatile bool threadrunning = false;
83 86
84 private IServiceThrottleModule m_ServiceThrottle;
85
86 //private int CacheRegionsDistance = 256; 87 //private int CacheRegionsDistance = 256;
87 88
88 #region INonSharedRegionModule Members 89 #region INonSharedRegionModule Members
@@ -93,7 +94,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
93 if (Util.GetConfigVarFromSections<string>( 94 if (Util.GetConfigVarFromSections<string>(
94 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") 95 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap")
95 m_Enabled = true; 96 m_Enabled = true;
96 97
97 blacklistTimeout 98 blacklistTimeout
98 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; 99 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000;
99 } 100 }
@@ -133,10 +134,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
133 134
134 public virtual void RegionLoaded (Scene scene) 135 public virtual void RegionLoaded (Scene scene)
135 { 136 {
136 if (!m_Enabled)
137 return;
138
139 m_ServiceThrottle = scene.RequestModuleInterface<IServiceThrottleModule>();
140 } 137 }
141 138
142 139
@@ -185,13 +182,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
185 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 182 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
186 m_scene.EventManager.OnRegionUp += OnRegionUp; 183 m_scene.EventManager.OnRegionUp += OnRegionUp;
187 184
188// StartThread(new object()); 185 StartThread(new object());
189 } 186 }
190 187
191 // this has to be called with a lock on m_scene 188 // this has to be called with a lock on m_scene
192 protected virtual void RemoveHandlers() 189 protected virtual void RemoveHandlers()
193 { 190 {
194// StopThread(); 191 StopThread();
195 192
196 m_scene.EventManager.OnRegionUp -= OnRegionUp; 193 m_scene.EventManager.OnRegionUp -= OnRegionUp;
197 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 194 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
@@ -249,54 +246,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
249 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 246 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
250 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 247 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
251 248
252 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 249 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
253 { 250 //{
254 ScenePresence avatarPresence = null; 251 // ScenePresence avatarPresence = null;
255 252
256 m_scene.TryGetScenePresence(agentID, out avatarPresence); 253 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
257 254
258 if (avatarPresence != null) 255 // if (avatarPresence != null)
259 { 256 // {
260 bool lookup = false; 257 // bool lookup = false;
261 258
262 lock (cachedMapBlocks) 259 // lock (cachedMapBlocks)
263 { 260 // {
264 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 261 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
265 { 262 // {
266 List<MapBlockData> mapBlocks; 263 // List<MapBlockData> mapBlocks;
267 264
268 mapBlocks = cachedMapBlocks; 265 // mapBlocks = cachedMapBlocks;
269 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 266 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
270 } 267 // }
271 else 268 // else
272 { 269 // {
273 lookup = true; 270 // lookup = true;
274 } 271 // }
275 } 272 // }
276 if (lookup) 273 // if (lookup)
277 { 274 // {
278 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 275 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
279 276
280 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 277 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
281 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 278 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
282 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 279 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
283 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 280 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
284 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 281 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
285 foreach (GridRegion r in regions) 282 // foreach (GridRegion r in regions)
286 { 283 // {
287 MapBlockData block = new MapBlockData(); 284 // MapBlockData block = new MapBlockData();
288 MapBlockFromGridRegion(block, r, 0); 285 // MapBlockFromGridRegion(block, r, 0);
289 mapBlocks.Add(block); 286 // mapBlocks.Add(block);
290 } 287 // }
291 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 288 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
292 289
293 lock (cachedMapBlocks) 290 // lock (cachedMapBlocks)
294 cachedMapBlocks = mapBlocks; 291 // cachedMapBlocks = mapBlocks;
295 292
296 cachedTime = Util.UnixTimeSinceEpoch(); 293 // cachedTime = Util.UnixTimeSinceEpoch();
297 } 294 // }
298 } 295 // }
299 } 296 //}
300 297
301 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 298 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
302 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 299 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -323,8 +320,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
323 protected static OSDMapLayer GetOSDMapLayerResponse() 320 protected static OSDMapLayer GetOSDMapLayerResponse()
324 { 321 {
325 OSDMapLayer mapLayer = new OSDMapLayer(); 322 OSDMapLayer mapLayer = new OSDMapLayer();
326 mapLayer.Right = 5000; 323 mapLayer.Right = 2048;
327 mapLayer.Top = 5000; 324 mapLayer.Top = 2048;
328 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 325 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
329 326
330 return mapLayer; 327 return mapLayer;
@@ -353,6 +350,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
353 { 350 {
354 m_rootAgents.Remove(AgentId); 351 m_rootAgents.Remove(AgentId);
355 } 352 }
353 lock (m_mapBlockRequestEvent)
354 {
355 if (m_mapBlockRequests.ContainsKey(AgentId))
356 m_mapBlockRequests.Remove(AgentId);
357 }
356 } 358 }
357 #endregion 359 #endregion
358 360
@@ -375,6 +377,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
375 ThreadPriority.BelowNormal, 377 ThreadPriority.BelowNormal,
376 true, 378 true,
377 true); 379 true);
380 Watchdog.StartThread(
381 MapBlockSendThread,
382 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
383 ThreadPriority.BelowNormal,
384 true,
385 true);
378 } 386 }
379 387
380 /// <summary> 388 /// <summary>
@@ -390,7 +398,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
390 st.itemtype=0; 398 st.itemtype=0;
391 st.regionhandle=0; 399 st.regionhandle=0;
392 400
393 requests.Enqueue(st); 401 lock (requests)
402 {
403 queueEvent.Set();
404 requests.Enqueue(st);
405 }
406
407 MapBlockRequestData req = new MapBlockRequestData();
408
409 req.client = null;
410 req.minX = 0;
411 req.maxX = 0;
412 req.minY = 0;
413 req.maxY = 0;
414 req.flags = 0;
415
416 lock (m_mapBlockRequestEvent)
417 {
418 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
419 m_mapBlockRequests[UUID.Zero].Enqueue(req);
420 m_mapBlockRequestEvent.Set();
421 }
394 } 422 }
395 423
396 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 424 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -541,12 +569,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
541 /// </summary> 569 /// </summary>
542 public void process() 570 public void process()
543 { 571 {
544 //const int MAX_ASYNC_REQUESTS = 20; 572 const int MAX_ASYNC_REQUESTS = 20;
545 try 573 try
546 { 574 {
547 while (true) 575 while (true)
548 { 576 {
549 MapRequestState st = requests.Dequeue(1000); 577 MapRequestState st = new MapRequestState();
578 bool valid = false;
579 queueEvent.WaitOne();
580 lock (requests)
581 {
582 if (requests.Count > 0)
583 {
584 st = requests.Dequeue();
585 valid = true;
586 }
587 if (requests.Count == 0)
588 queueEvent.Reset();
589 }
590 if (!valid)
591 continue;
550 592
551 // end gracefully 593 // end gracefully
552 if (st.agentID == STOP_UUID) 594 if (st.agentID == STOP_UUID)
@@ -564,13 +606,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
564 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 606 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
565 { 607 {
566 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 608 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
567 Thread.Sleep(80); 609 Thread.Sleep(100);
568 610
569 RequestMapItemsDelegate d = RequestMapItemsAsync;
570 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
571 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
572 //RequestMapItemsCompleted(response);
573 Interlocked.Increment(ref nAsyncRequests); 611 Interlocked.Increment(ref nAsyncRequests);
612 Util.FireAndForget(x =>
613 {
614 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
615 });
574 } 616 }
575 } 617 }
576 618
@@ -586,147 +628,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
586 Watchdog.RemoveThread(); 628 Watchdog.RemoveThread();
587 } 629 }
588 630
589 const int MAX_ASYNC_REQUESTS = 20;
590
591 /// <summary> 631 /// <summary>
592 /// Enqueues the map item request into the services throttle processing thread 632 /// Enqueues the map item request into the processing thread
593 /// </summary> 633 /// </summary>
594 /// <param name="state"></param> 634 /// <param name="state"></param>
595 public void EnqueueMapItemRequest(MapRequestState st) 635 public void EnqueueMapItemRequest(MapRequestState state)
596 {
597
598 m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate
599 {
600 if (st.agentID != UUID.Zero)
601 {
602 bool dorequest = true;
603 lock (m_rootAgents)
604 {
605 if (!m_rootAgents.Contains(st.agentID))
606 dorequest = false;
607 }
608
609 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
610 {
611 if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
612 {
613 // AH!!! Recursive !
614 // Put this request back in the queue and return
615 EnqueueMapItemRequest(st);
616 return;
617 }
618
619 RequestMapItemsDelegate d = RequestMapItemsAsync;
620 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
621 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
622 //RequestMapItemsCompleted(response);
623 Interlocked.Increment(ref nAsyncRequests);
624 }
625 }
626 });
627 }
628
629 /// <summary>
630 /// Sends the mapitem response to the IClientAPI
631 /// </summary>
632 /// <param name="response">The OSDMap Response for the mapitem</param>
633 private void RequestMapItemsCompleted(IAsyncResult iar)
634 { 636 {
635 AsyncResult result = (AsyncResult)iar; 637 lock (requests)
636 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
637
638 OSDMap response = (OSDMap)icon.EndInvoke(iar);
639
640 Interlocked.Decrement(ref nAsyncRequests);
641
642 if (!response.ContainsKey("requestID"))
643 return;
644
645 UUID requestID = response["requestID"].AsUUID();
646
647 if (requestID != UUID.Zero)
648 { 638 {
649 MapRequestState mrs = new MapRequestState(); 639 queueEvent.Set();
650 mrs.agentID = UUID.Zero; 640 requests.Enqueue(state);
651 lock (m_openRequests)
652 {
653 if (m_openRequests.ContainsKey(requestID))
654 {
655 mrs = m_openRequests[requestID];
656 m_openRequests.Remove(requestID);
657 }
658 }
659
660 if (mrs.agentID != UUID.Zero)
661 {
662 ScenePresence av = null;
663 m_scene.TryGetScenePresence(mrs.agentID, out av);
664 if (av != null)
665 {
666 if (response.ContainsKey(mrs.itemtype.ToString()))
667 {
668 List<mapItemReply> returnitems = new List<mapItemReply>();
669 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
670 for (int i = 0; i < itemarray.Count; i++)
671 {
672 OSDMap mapitem = (OSDMap)itemarray[i];
673 mapItemReply mi = new mapItemReply();
674 mi.x = (uint)mapitem["X"].AsInteger();
675 mi.y = (uint)mapitem["Y"].AsInteger();
676 mi.id = mapitem["ID"].AsUUID();
677 mi.Extra = mapitem["Extra"].AsInteger();
678 mi.Extra2 = mapitem["Extra2"].AsInteger();
679 mi.name = mapitem["Name"].AsString();
680 returnitems.Add(mi);
681 }
682 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
683 }
684
685 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
686 uint itemtype = 7;
687
688 if (response.ContainsKey(itemtype.ToString()))
689 {
690 List<mapItemReply> returnitems = new List<mapItemReply>();
691 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
692 for (int i = 0; i < itemarray.Count; i++)
693 {
694 OSDMap mapitem = (OSDMap)itemarray[i];
695 mapItemReply mi = new mapItemReply();
696 mi.x = (uint)mapitem["X"].AsInteger();
697 mi.y = (uint)mapitem["Y"].AsInteger();
698 mi.id = mapitem["ID"].AsUUID();
699 mi.Extra = mapitem["Extra"].AsInteger();
700 mi.Extra2 = mapitem["Extra2"].AsInteger();
701 mi.name = mapitem["Name"].AsString();
702 returnitems.Add(mi);
703 }
704 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
705 }
706
707 // Service 1 (MAP_ITEM_TELEHUB)
708 itemtype = 1;
709
710 if (response.ContainsKey(itemtype.ToString()))
711 {
712 List<mapItemReply> returnitems = new List<mapItemReply>();
713 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
714 for (int i = 0; i < itemarray.Count; i++)
715 {
716 OSDMap mapitem = (OSDMap)itemarray[i];
717 mapItemReply mi = new mapItemReply();
718 mi.x = (uint)mapitem["X"].AsInteger();
719 mi.y = (uint)mapitem["Y"].AsInteger();
720 mi.id = mapitem["ID"].AsUUID();
721 mi.Extra = mapitem["Extra"].AsInteger();
722 mi.Extra2 = mapitem["Extra2"].AsInteger();
723 mi.name = mapitem["Name"].AsString();
724 returnitems.Add(mi);
725 }
726 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
727 }
728 }
729 }
730 } 641 }
731 } 642 }
732 643
@@ -753,8 +664,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
753 EnqueueMapItemRequest(st); 664 EnqueueMapItemRequest(st);
754 } 665 }
755 666
756 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
757 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
758 /// <summary> 667 /// <summary>
759 /// Does the actual remote mapitem request 668 /// Does the actual remote mapitem request
760 /// This should be called from an asynchronous thread 669 /// This should be called from an asynchronous thread
@@ -769,7 +678,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
769 /// <param name="itemtype">passed in from packet</param> 678 /// <param name="itemtype">passed in from packet</param>
770 /// <param name="regionhandle">Region we're looking up</param> 679 /// <param name="regionhandle">Region we're looking up</param>
771 /// <returns></returns> 680 /// <returns></returns>
772 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 681 private void RequestMapItemsAsync(UUID id, uint flags,
773 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 682 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
774 { 683 {
775// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 684// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -792,7 +701,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
792 } 701 }
793 702
794 if (blacklisted) 703 if (blacklisted)
795 return new OSDMap(); 704 {
705 Interlocked.Decrement(ref nAsyncRequests);
706 return;
707 }
796 708
797 UUID requestID = UUID.Random(); 709 UUID requestID = UUID.Random();
798 lock (m_cachedRegionMapItemsAddress) 710 lock (m_cachedRegionMapItemsAddress)
@@ -800,6 +712,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
800 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 712 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
801 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 713 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
802 } 714 }
715
803 if (httpserver.Length == 0) 716 if (httpserver.Length == 0)
804 { 717 {
805 uint x = 0, y = 0; 718 uint x = 0, y = 0;
@@ -844,18 +757,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
844 757
845 // Can't find the http server 758 // Can't find the http server
846 if (httpserver.Length == 0 || blacklisted) 759 if (httpserver.Length == 0 || blacklisted)
847 return new OSDMap(); 760 {
848 761 Interlocked.Decrement(ref nAsyncRequests);
849 MapRequestState mrs = new MapRequestState(); 762 return;
850 mrs.agentID = id; 763 }
851 mrs.EstateID = EstateID;
852 mrs.flags = flags;
853 mrs.godlike = godlike;
854 mrs.itemtype=itemtype;
855 mrs.regionhandle = regionhandle;
856
857 lock (m_openRequests)
858 m_openRequests.Add(requestID, mrs);
859 764
860 WebRequest mapitemsrequest = null; 765 WebRequest mapitemsrequest = null;
861 try 766 try
@@ -865,7 +770,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
865 catch (Exception e) 770 catch (Exception e)
866 { 771 {
867 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 772 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
868 return new OSDMap(); 773 Interlocked.Decrement(ref nAsyncRequests);
774 return;
869 } 775 }
870 776
871 mapitemsrequest.Method = "POST"; 777 mapitemsrequest.Method = "POST";
@@ -890,7 +796,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
890 catch (WebException ex) 796 catch (WebException ex)
891 { 797 {
892 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 798 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
893 responseMap["connect"] = OSD.FromBoolean(false);
894 lock (m_blacklistedurls) 799 lock (m_blacklistedurls)
895 { 800 {
896 if (!m_blacklistedurls.ContainsKey(httpserver)) 801 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -899,13 +804,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
899 804
900 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 805 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
901 806
902 return responseMap; 807 Interlocked.Decrement(ref nAsyncRequests);
808 return;
903 } 809 }
904 catch 810 catch
905 { 811 {
906 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 812 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
907 responseMap["connect"] = OSD.FromBoolean(false); 813 Interlocked.Decrement(ref nAsyncRequests);
908 return responseMap; 814 return;
909 } 815 }
910 finally 816 finally
911 { 817 {
@@ -914,26 +820,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
914 } 820 }
915 821
916 string response_mapItems_reply = null; 822 string response_mapItems_reply = null;
917 { 823 { // get the response
824 StreamReader sr = null;
918 try 825 try
919 { 826 {
920 using (WebResponse webResponse = mapitemsrequest.GetResponse()) 827 WebResponse webResponse = mapitemsrequest.GetResponse();
828 if (webResponse != null)
921 { 829 {
922 if (webResponse != null) 830 sr = new StreamReader(webResponse.GetResponseStream());
923 { 831 response_mapItems_reply = sr.ReadToEnd().Trim();
924 using (Stream s = webResponse.GetResponseStream()) 832 }
925 using (StreamReader sr = new StreamReader(s)) 833 else
926 response_mapItems_reply = sr.ReadToEnd().Trim(); 834 {
927 } 835 Interlocked.Decrement(ref nAsyncRequests);
928 else 836 return;
929 { 837 }
930 return new OSDMap();
931 }
932 }
933 } 838 }
934 catch (WebException) 839 catch (WebException)
935 { 840 {
936 responseMap["connect"] = OSD.FromBoolean(false);
937 lock (m_blacklistedurls) 841 lock (m_blacklistedurls)
938 { 842 {
939 if (!m_blacklistedurls.ContainsKey(httpserver)) 843 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -942,19 +846,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
942 846
943 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 847 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
944 848
945 return responseMap; 849 Interlocked.Decrement(ref nAsyncRequests);
850 return;
946 } 851 }
947 catch 852 catch
948 { 853 {
949 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 854 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
950 responseMap["connect"] = OSD.FromBoolean(false);
951 lock (m_blacklistedregions) 855 lock (m_blacklistedregions)
952 { 856 {
953 if (!m_blacklistedregions.ContainsKey(regionhandle)) 857 if (!m_blacklistedregions.ContainsKey(regionhandle))
954 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 858 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
955 } 859 }
956 860
957 return responseMap; 861 Interlocked.Decrement(ref nAsyncRequests);
862 return;
863 }
864 finally
865 {
866 if (sr != null)
867 sr.Close();
958 } 868 }
959 869
960 OSD rezResponse = null; 870 OSD rezResponse = null;
@@ -968,15 +878,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
968 catch (Exception ex) 878 catch (Exception ex)
969 { 879 {
970 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 880 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
971 responseMap["connect"] = OSD.FromBoolean(false);
972
973 lock (m_blacklistedregions) 881 lock (m_blacklistedregions)
974 { 882 {
975 if (!m_blacklistedregions.ContainsKey(regionhandle)) 883 if (!m_blacklistedregions.ContainsKey(regionhandle))
976 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 884 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
977 } 885 }
978 886
979 return responseMap; 887 Interlocked.Decrement(ref nAsyncRequests);
888 return;
980 } 889 }
981 } 890 }
982 891
@@ -990,7 +899,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
990 } 899 }
991 } 900 }
992 901
993 return responseMap; 902 Interlocked.Decrement(ref nAsyncRequests);
903
904 if (id != UUID.Zero)
905 {
906 ScenePresence av = null;
907 m_scene.TryGetScenePresence(id, out av);
908 if (av != null)
909 {
910 if (responseMap.ContainsKey(itemtype.ToString()))
911 {
912 List<mapItemReply> returnitems = new List<mapItemReply>();
913 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
914 for (int i = 0; i < itemarray.Count; i++)
915 {
916 OSDMap mapitem = (OSDMap)itemarray[i];
917 mapItemReply mi = new mapItemReply();
918 mi.x = (uint)mapitem["X"].AsInteger();
919 mi.y = (uint)mapitem["Y"].AsInteger();
920 mi.id = mapitem["ID"].AsUUID();
921 mi.Extra = mapitem["Extra"].AsInteger();
922 mi.Extra2 = mapitem["Extra2"].AsInteger();
923 mi.name = mapitem["Name"].AsString();
924 returnitems.Add(mi);
925 }
926 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
927 }
928
929 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
930 itemtype = 7;
931
932 if (responseMap.ContainsKey(itemtype.ToString()))
933 {
934 List<mapItemReply> returnitems = new List<mapItemReply>();
935 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
936 for (int i = 0; i < itemarray.Count; i++)
937 {
938 OSDMap mapitem = (OSDMap)itemarray[i];
939 mapItemReply mi = new mapItemReply();
940 mi.x = (uint)mapitem["X"].AsInteger();
941 mi.y = (uint)mapitem["Y"].AsInteger();
942 mi.id = mapitem["ID"].AsUUID();
943 mi.Extra = mapitem["Extra"].AsInteger();
944 mi.Extra2 = mapitem["Extra2"].AsInteger();
945 mi.name = mapitem["Name"].AsString();
946 returnitems.Add(mi);
947 }
948 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
949 }
950
951 // Service 1 (MAP_ITEM_TELEHUB)
952 itemtype = 1;
953
954 if (responseMap.ContainsKey(itemtype.ToString()))
955 {
956 List<mapItemReply> returnitems = new List<mapItemReply>();
957 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
958 for (int i = 0; i < itemarray.Count; i++)
959 {
960 OSDMap mapitem = (OSDMap)itemarray[i];
961 mapItemReply mi = new mapItemReply();
962 mi.x = (uint)mapitem["X"].AsInteger();
963 mi.y = (uint)mapitem["Y"].AsInteger();
964 mi.id = mapitem["ID"].AsUUID();
965 mi.Extra = mapitem["Extra"].AsInteger();
966 mi.Extra2 = mapitem["Extra2"].AsInteger();
967 mi.name = mapitem["Name"].AsString();
968 returnitems.Add(mi);
969 }
970 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
971 }
972 }
973 }
994 } 974 }
995 975
996 /// <summary> 976 /// <summary>
@@ -1000,7 +980,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1000 /// <param name="minY"></param> 980 /// <param name="minY"></param>
1001 /// <param name="maxX"></param> 981 /// <param name="maxX"></param>
1002 /// <param name="maxY"></param> 982 /// <param name="maxY"></param>
1003 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 983 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1004 { 984 {
1005 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 985 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
1006 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 986 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1053,21 +1033,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1053 1033
1054 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1034 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1055 { 1035 {
1036 MapBlockRequestData req = new MapBlockRequestData();
1037
1038 req.client = remoteClient;
1039 req.minX = minX;
1040 req.maxX = maxX;
1041 req.minY = minY;
1042 req.maxY = maxY;
1043 req.flags = flag;
1044
1045 lock (m_mapBlockRequestEvent)
1046 {
1047 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1048 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1049 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1050 m_mapBlockRequestEvent.Set();
1051 }
1052
1053 return new List<MapBlockData>();
1054 }
1055
1056 protected void MapBlockSendThread()
1057 {
1058 while (true)
1059 {
1060 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1061
1062 m_mapBlockRequestEvent.WaitOne();
1063 lock (m_mapBlockRequestEvent)
1064 {
1065 int total = 0;
1066 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1067 {
1068 if (q.Count > 0)
1069 thisRunData.Add(q.Dequeue());
1070
1071 total += q.Count;
1072 }
1073
1074 if (total == 0)
1075 m_mapBlockRequestEvent.Reset();
1076 }
1077
1078 foreach (MapBlockRequestData req in thisRunData)
1079 {
1080 // Null client stops thread
1081 if (req.client == null)
1082 return;
1083
1084 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1085 }
1086
1087 Thread.Sleep(50);
1088 }
1089 }
1090
1091 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1092 {
1093 List<MapBlockData> allBlocks = new List<MapBlockData>();
1056 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1094 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1057 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1095 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1058 (minX - 4) * (int)Constants.RegionSize, 1096 minX * (int)Constants.RegionSize,
1059 (maxX + 4) * (int)Constants.RegionSize, 1097 maxX * (int)Constants.RegionSize,
1060 (minY - 4) * (int)Constants.RegionSize, 1098 minY * (int)Constants.RegionSize,
1061 (maxY + 4) * (int)Constants.RegionSize); 1099 maxY * (int)Constants.RegionSize);
1100// (minX - 4) * (int)Constants.RegionSize,
1101// (maxX + 4) * (int)Constants.RegionSize,
1102// (minY - 4) * (int)Constants.RegionSize,
1103// (maxY + 4) * (int)Constants.RegionSize);
1062 foreach (GridRegion r in regions) 1104 foreach (GridRegion r in regions)
1063 { 1105 {
1064 MapBlockData block = new MapBlockData(); 1106 MapBlockData block = new MapBlockData();
1065 MapBlockFromGridRegion(block, r, flag); 1107 MapBlockFromGridRegion(block, r, flag);
1066 mapBlocks.Add(block); 1108 mapBlocks.Add(block);
1109 allBlocks.Add(block);
1110 if (mapBlocks.Count >= 10)
1111 {
1112 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1113 mapBlocks.Clear();
1114 Thread.Sleep(50);
1115 }
1067 } 1116 }
1068 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1117 if (mapBlocks.Count > 0)
1118 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1069 1119
1070 return mapBlocks; 1120 return allBlocks;
1071 } 1121 }
1072 1122
1073 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1123 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1301,7 +1351,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1301 } 1351 }
1302 else 1352 else
1303 { 1353 {
1304 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1354 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1305 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1355 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1306 { 1356 {
1307 OSDMap responsemapdata = new OSDMap(); 1357 OSDMap responsemapdata = new OSDMap();
@@ -1477,6 +1527,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1477 { 1527 {
1478 m_rootAgents.Remove(avatar.UUID); 1528 m_rootAgents.Remove(avatar.UUID);
1479 } 1529 }
1530
1531 lock (m_mapBlockRequestEvent)
1532 {
1533 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1534 m_mapBlockRequests.Remove(avatar.UUID);
1535 }
1480 } 1536 }
1481 1537
1482 public void OnRegionUp(GridRegion otherRegion) 1538 public void OnRegionUp(GridRegion otherRegion)
@@ -1521,9 +1577,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1521 Color background = Color.FromArgb(0, 0, 0, 0); 1577 Color background = Color.FromArgb(0, 0, 0, 0);
1522 SolidBrush transparent = new SolidBrush(background); 1578 SolidBrush transparent = new SolidBrush(background);
1523 Graphics g = Graphics.FromImage(overlay); 1579 Graphics g = Graphics.FromImage(overlay);
1524 g.FillRectangle(transparent, 0, 0, 256, 256); 1580 g.FillRectangle(transparent, 0, 0, 255, 255);
1525 1581
1526 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1582 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1583 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1527 1584
1528 foreach (ILandObject land in parcels) 1585 foreach (ILandObject land in parcels)
1529 { 1586 {
@@ -1531,8 +1588,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1531 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1588 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1532 { 1589 {
1533 landForSale = true; 1590 landForSale = true;
1591
1592 bool[,] landBitmap = land.GetLandBitmap();
1593
1594 for (int x = 0 ; x < 64 ; x++)
1595 {
1596 for (int y = 0 ; y < 64 ; y++)
1597 {
1598 if (landBitmap[x, y])
1599 {
1600 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1601
1602 if (x > 0)
1603 {
1604 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1605 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1606 }
1607 if (y > 0)
1608 {
1609 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1610 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1611 }
1612 if (x < 63)
1613 {
1614 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1615 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1616 }
1617 if (y < 63)
1618 {
1619 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1620 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1621 }
1622 }
1623 }
1624 }
1534 1625
1535 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1626 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1536 } 1627 }
1537 } 1628 }
1538 1629
@@ -1544,15 +1635,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1544 1635
1545 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1636 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1546 1637
1547 for (int x = 0 ; x < 64 ; x++)
1548 {
1549 for (int y = 0 ; y < 64 ; y++)
1550 {
1551 if (saleBitmap[x, y])
1552 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1553 }
1554 }
1555
1556 try 1638 try
1557 { 1639 {
1558 return OpenJPEG.EncodeFromImage(overlay, true); 1640 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1574,4 +1656,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1574 public uint itemtype; 1656 public uint itemtype;
1575 public ulong regionhandle; 1657 public ulong regionhandle;
1576 } 1658 }
1659
1660 public struct MapBlockRequestData
1661 {
1662 public IClientAPI client;
1663 public int minX;
1664 public int minY;
1665 public int maxX;
1666 public int maxY;
1667 public uint flags;
1668 }
1577} 1669}