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.cs107
-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.cs192
-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.cs168
-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.cs228
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs229
-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.cs359
-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.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs7
-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
54 files changed, 3164 insertions, 1775 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 0271738..da1ff2e 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -143,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
143 } 143 }
144 } 144 }
145 145
146 public void RequestCreateInventoryItem(IClientAPI remoteClient, 146 public bool RequestCreateInventoryItem(IClientAPI remoteClient,
147 UUID transactionID, UUID folderID, uint callbackID, 147 UUID transactionID, UUID folderID, uint callbackID,
148 string description, string name, sbyte invType, 148 string description, string name, sbyte invType,
149 sbyte type, byte wearableType, uint nextOwnerMask) 149 sbyte type, byte wearableType, uint nextOwnerMask)
@@ -153,6 +153,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
153 uploader.RequestCreateInventoryItem( 153 uploader.RequestCreateInventoryItem(
154 remoteClient, folderID, callbackID, 154 remoteClient, folderID, callbackID,
155 description, name, invType, type, wearableType, nextOwnerMask); 155 description, name, invType, type, wearableType, nextOwnerMask);
156
157 return true;
156 } 158 }
157 159
158 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, 160 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
@@ -172,4 +174,4 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
172 uploader.RequestUpdateInventoryItem(remoteClient, item); 174 uploader.RequestUpdateInventoryItem(remoteClient, item);
173 } 175 }
174 } 176 }
175} \ No newline at end of file 177}
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 2afe065..d510d82 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -251,57 +251,70 @@ namespace OpenSim.Region.CoreModules.Asset
251 251
252 private void UpdateFileCache(string key, AssetBase asset) 252 private void UpdateFileCache(string key, AssetBase asset)
253 { 253 {
254 string filename = GetFileName(asset.ID); 254 // TODO: Spawn this off to some seperate thread to do the actual writing
255 255 if (asset != null)
256 try
257 { 256 {
258 // If the file is already cached just update access time. 257 string filename = GetFileName(key);
259 if (File.Exists(filename)) 258
260 { 259 try
261 lock (m_CurrentlyWriting)
262 {
263 if (!m_CurrentlyWriting.Contains(filename))
264 File.SetLastAccessTime(filename, DateTime.Now);
265 }
266 }
267 else
268 { 260 {
269 // Once we start writing, make sure we flag that we're writing 261 // If the file is already cached, don't cache it, just touch it so access time is updated
270 // that object to the cache so that we don't try to write the 262 if (File.Exists(filename))
271 // same file multiple times.
272 lock (m_CurrentlyWriting)
273 { 263 {
274#if WAIT_ON_INPROGRESS_REQUESTS 264 // We don't really want to know about sharing
275 if (m_CurrentlyWriting.ContainsKey(filename)) 265 // violations here. If the file is locked, then
266 // the other thread has updated the time for us.
267 try
276 { 268 {
277 return; 269 lock (m_CurrentlyWriting)
270 {
271 if (!m_CurrentlyWriting.Contains(filename))
272 File.SetLastAccessTime(filename, DateTime.Now);
273 }
278 } 274 }
279 else 275 catch
280 {
281 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
282 }
283
284#else
285 if (m_CurrentlyWriting.Contains(filename))
286 { 276 {
287 return;
288 } 277 }
289 else 278 } else {
279
280 // Once we start writing, make sure we flag that we're writing
281 // that object to the cache so that we don't try to write the
282 // same file multiple times.
283 lock (m_CurrentlyWriting)
290 { 284 {
291 m_CurrentlyWriting.Add(filename); 285#if WAIT_ON_INPROGRESS_REQUESTS
292 } 286 if (m_CurrentlyWriting.ContainsKey(filename))
287 {
288 return;
289 }
290 else
291 {
292 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
293 }
294
295#else
296 if (m_CurrentlyWriting.Contains(filename))
297 {
298 return;
299 }
300 else
301 {
302 m_CurrentlyWriting.Add(filename);
303 }
293#endif 304#endif
294 }
295 305
296 Util.FireAndForget( 306 }
297 delegate { WriteFileCache(filename, asset); }); 307
308 Util.FireAndForget(
309 delegate { WriteFileCache(filename, asset); });
310 }
311 }
312 catch (Exception e)
313 {
314 m_log.ErrorFormat(
315 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
316 asset.ID, e.Message, e.StackTrace);
298 } 317 }
299 }
300 catch (Exception e)
301 {
302 m_log.WarnFormat(
303 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
304 asset.ID, e.Message, e.StackTrace);
305 } 318 }
306 } 319 }
307 320
@@ -335,6 +348,17 @@ namespace OpenSim.Region.CoreModules.Asset
335 return asset; 348 return asset;
336 } 349 }
337 350
351 private bool CheckFromMemoryCache(string id)
352 {
353 AssetBase asset = null;
354
355 if (m_MemoryCache.TryGetValue(id, out asset))
356 return true;
357
358 return false;
359 }
360
361
338 /// <summary> 362 /// <summary>
339 /// Try to get an asset from the file cache. 363 /// Try to get an asset from the file cache.
340 /// </summary> 364 /// </summary>
@@ -399,6 +423,7 @@ namespace OpenSim.Region.CoreModules.Asset
399 m_log.WarnFormat( 423 m_log.WarnFormat(
400 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 424 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
401 filename, id, e.Message, e.StackTrace); 425 filename, id, e.Message, e.StackTrace);
426
402 } 427 }
403 finally 428 finally
404 { 429 {
@@ -410,6 +435,50 @@ namespace OpenSim.Region.CoreModules.Asset
410 return asset; 435 return asset;
411 } 436 }
412 437
438 private bool CheckFromFileCache(string id)
439 {
440 bool found = false;
441
442 string filename = GetFileName(id);
443 if (File.Exists(filename))
444 {
445 // actually check if we can open it, and so update expire
446 FileStream stream = null;
447 try
448 {
449 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
450 if (stream != null)
451 {
452 found = true;
453 stream.Close();
454 }
455
456 }
457 catch (System.Runtime.Serialization.SerializationException e)
458 {
459 found = false;
460 m_log.ErrorFormat(
461 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
462 filename, id, e.Message, e.StackTrace);
463
464 // If there was a problem deserializing the asset, the asset may
465 // either be corrupted OR was serialized under an old format
466 // {different version of AssetBase} -- we should attempt to
467 // delete it and re-cache
468 File.Delete(filename);
469 }
470 catch (Exception e)
471 {
472 found = false;
473 m_log.ErrorFormat(
474 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
475 filename, id, e.Message, e.StackTrace);
476 }
477 }
478
479 return found;
480 }
481
413 public AssetBase Get(string id) 482 public AssetBase Get(string id)
414 { 483 {
415 m_Requests++; 484 m_Requests++;
@@ -446,11 +515,26 @@ namespace OpenSim.Region.CoreModules.Asset
446 return asset; 515 return asset;
447 } 516 }
448 517
518 public bool Check(string id)
519 {
520 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
521 return true;
522
523 if (m_FileCacheEnabled && CheckFromFileCache(id))
524 return true;
525 return false;
526 }
527
449 public AssetBase GetCached(string id) 528 public AssetBase GetCached(string id)
450 { 529 {
451 return Get(id); 530 return Get(id);
452 } 531 }
453 532
533 public AssetBase CheckCached(string id)
534 {
535 return Get(id);
536 }
537
454 public void Expire(string id) 538 public void Expire(string id)
455 { 539 {
456 if (m_LogLevel >= 2) 540 if (m_LogLevel >= 2)
@@ -966,6 +1050,11 @@ namespace OpenSim.Region.CoreModules.Asset
966 return asset.Data; 1050 return asset.Data;
967 } 1051 }
968 1052
1053 public bool CheckData(string id)
1054 {
1055 return Check(id); ;
1056 }
1057
969 public bool Get(string id, object sender, AssetRetrieved handler) 1058 public bool Get(string id, object sender, AssetRetrieved handler)
970 { 1059 {
971 AssetBase asset = Get(id); 1060 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 2818712..95cc6b7 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.
@@ -422,7 +482,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
422 attachPos = Vector3.Zero; 482 attachPos = Vector3.Zero;
423 } 483 }
424 484
425 // AttachmentPt 0 means the client chose to 'wear' the attachment. 485 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment.
426 if (attachmentPt == (uint)AttachmentPoint.Default) 486 if (attachmentPt == (uint)AttachmentPoint.Default)
427 { 487 {
428 // Check object for stored attachment point 488 // Check object for stored attachment point
@@ -437,9 +497,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
437 attachPos = Vector3.Zero; 497 attachPos = Vector3.Zero;
438 } 498 }
439 499
440 group.AttachmentPoint = attachmentPt;
441 group.AbsolutePosition = attachPos;
442
443 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 500 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
444 501
445 if (attachments.Contains(group)) 502 if (attachments.Contains(group))
@@ -472,6 +529,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
472 529
473 lock (sp.AttachmentsSyncLock) 530 lock (sp.AttachmentsSyncLock)
474 { 531 {
532 group.AttachmentPoint = attachmentPt;
533 group.AbsolutePosition = attachPos;
534
475 if (addToInventory && sp.PresenceType != PresenceType.Npc) 535 if (addToInventory && sp.PresenceType != PresenceType.Npc)
476 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); 536 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
477 537
@@ -502,7 +562,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
502 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); 562 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
503 } 563 }
504 564
505 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 565 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
566 {
567 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
568 }
569
570 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
506 { 571 {
507 if (!Enabled) 572 if (!Enabled)
508 return null; 573 return null;
@@ -540,7 +605,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
540 bool append = (AttachmentPt & 0x80) != 0; 605 bool append = (AttachmentPt & 0x80) != 0;
541 AttachmentPt &= 0x7f; 606 AttachmentPt &= 0x7f;
542 607
543 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); 608 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc);
544 } 609 }
545 610
546 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 611 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -617,7 +682,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 so.AttachedAvatar = UUID.Zero; 682 so.AttachedAvatar = UUID.Zero;
618 rootPart.SetParentLocalId(0); 683 rootPart.SetParentLocalId(0);
619 so.ClearPartAttachmentData(); 684 so.ClearPartAttachmentData();
620 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 685 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
621 so.HasGroupChanged = true; 686 so.HasGroupChanged = true;
622 rootPart.Rezzed = DateTime.Now; 687 rootPart.Rezzed = DateTime.Now;
623 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 688 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -950,7 +1015,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
950 } 1015 }
951 1016
952 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 1017 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
953 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) 1018 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc)
954 { 1019 {
955 if (m_invAccessModule == null) 1020 if (m_invAccessModule == null)
956 return null; 1021 return null;
@@ -994,7 +1059,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
994 // This will throw if the attachment fails 1059 // This will throw if the attachment fails
995 try 1060 try
996 { 1061 {
997 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); 1062 if (doc != null)
1063 {
1064 objatt.LoadScriptState(doc);
1065 objatt.ResetOwnerChangeFlag();
1066 }
1067
1068 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append);
998 } 1069 }
999 catch (Exception e) 1070 catch (Exception e)
1000 { 1071 {
@@ -1148,7 +1219,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1148 AttachmentPt &= 0x7f; 1219 AttachmentPt &= 0x7f;
1149 1220
1150 // Calls attach with a Zero position 1221 // Calls attach with a Zero position
1151 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) 1222 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, true, append))
1152 { 1223 {
1153 if (DebugLevel > 0) 1224 if (DebugLevel > 0)
1154 m_log.Debug( 1225 m_log.Debug(
@@ -1210,4 +1281,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1210 1281
1211 #endregion 1282 #endregion
1212 } 1283 }
1213} \ No newline at end of file 1284}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index fd493fc..62acd78 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 5229c08..917f164 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -50,7 +50,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
50 private int m_saydistance = 20; 50 private int m_saydistance = 20;
51 private int m_shoutdistance = 100; 51 private int m_shoutdistance = 100;
52 private int m_whisperdistance = 10; 52 private int m_whisperdistance = 10;
53 53 private List<Scene> m_scenes = new List<Scene>();
54 private List<string> FreezeCache = new List<string>();
55 private string m_adminPrefix = "";
54 internal object m_syncy = new object(); 56 internal object m_syncy = new object();
55 57
56 internal IConfig m_config; 58 internal IConfig m_config;
@@ -77,16 +79,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
77 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 79 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
78 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 80 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
79 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 81 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
82 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
80 } 83 }
81 84
82 public virtual void AddRegion(Scene scene) 85 public virtual void AddRegion(Scene scene)
83 { 86 {
84 if (!m_enabled) 87 if (!m_enabled) return;
85 return;
86 88
87 scene.EventManager.OnNewClient += OnNewClient; 89 lock (m_syncy)
88 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 90 {
89 scene.EventManager.OnChatBroadcast += OnChatBroadcast; 91 if (!m_scenes.Contains(scene))
92 {
93 m_scenes.Add(scene);
94 scene.EventManager.OnNewClient += OnNewClient;
95 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
96 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
97 }
98 }
90 99
91 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, 100 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
92 m_whisperdistance, m_saydistance, m_shoutdistance); 101 m_whisperdistance, m_saydistance, m_shoutdistance);
@@ -98,12 +107,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
98 107
99 public virtual void RemoveRegion(Scene scene) 108 public virtual void RemoveRegion(Scene scene)
100 { 109 {
101 if (!m_enabled) 110 if (!m_enabled) return;
102 return;
103 111
104 scene.EventManager.OnNewClient -= OnNewClient; 112 lock (m_syncy)
105 scene.EventManager.OnChatFromWorld -= OnChatFromWorld; 113 {
106 scene.EventManager.OnChatBroadcast -= OnChatBroadcast; 114 if (m_scenes.Contains(scene))
115 {
116 scene.EventManager.OnNewClient -= OnNewClient;
117 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
118 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
119 m_scenes.Remove(scene);
120 }
121 }
107 } 122 }
108 123
109 public virtual void Close() 124 public virtual void Close()
@@ -160,7 +175,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
160 return; 175 return;
161 } 176 }
162 177
163 DeliverChatToAvatars(ChatSourceType.Agent, c); 178 if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
179 {
180 if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
181 c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
182 }
183 else
184 {
185 DeliverChatToAvatars(ChatSourceType.Agent, c);
186 }
164 } 187 }
165 188
166 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 189 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -174,11 +197,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
174 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 197 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
175 { 198 {
176 string fromName = c.From; 199 string fromName = c.From;
200 string fromNamePrefix = "";
177 UUID fromID = UUID.Zero; 201 UUID fromID = UUID.Zero;
178 UUID ownerID = UUID.Zero; 202 UUID ownerID = UUID.Zero;
179 UUID targetID = c.TargetUUID;
180 string message = c.Message; 203 string message = c.Message;
181 Scene scene = (Scene)c.Scene; 204 IScene scene = c.Scene;
205 UUID destination = c.Destination;
182 Vector3 fromPos = c.Position; 206 Vector3 fromPos = c.Position;
183 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 207 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
184 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 208 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -188,10 +212,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
188 switch (sourceType) 212 switch (sourceType)
189 { 213 {
190 case ChatSourceType.Agent: 214 case ChatSourceType.Agent:
191 ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId); 215 if (!(scene is Scene))
216 {
217 m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
218 scene.RegionInfo.RegionName, c.Sender.AgentId);
219 return;
220 }
221 ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
192 fromPos = avatar.AbsolutePosition; 222 fromPos = avatar.AbsolutePosition;
193 fromName = avatar.Name; 223 fromName = avatar.Name;
194 fromID = c.Sender.AgentId; 224 fromID = c.Sender.AgentId;
225 if (avatar.GodLevel >= 200)
226 {
227 fromNamePrefix = m_adminPrefix;
228 }
229 destination = UUID.Zero; // Avatars cant "SayTo"
195 ownerID = c.Sender.AgentId; 230 ownerID = c.Sender.AgentId;
196 231
197 break; 232 break;
@@ -210,38 +245,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
210 message = message.Substring(0, 1000); 245 message = message.Substring(0, 1000);
211 246
212// m_log.DebugFormat( 247// m_log.DebugFormat(
213// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", 248// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}",
214// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 249// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
215 250
216 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 251 HashSet<UUID> receiverIDs = new HashSet<UUID>();
217 252
218 if (targetID == UUID.Zero) 253 foreach (Scene s in m_scenes)
219 { 254 {
220 // This should use ForEachClient, but clients don't have a position. 255 // This should use ForEachClient, but clients don't have a position.
221 // If camera is moved into client, then camera position can be used 256 // If camera is moved into client, then camera position can be used
222 scene.ForEachScenePresence( 257 // MT: No, it can't, as chat is heard from the avatar position, not
258 // the camera position.
259 s.ForEachScenePresence(
223 delegate(ScenePresence presence) 260 delegate(ScenePresence presence)
224 { 261 {
225 if (TrySendChatMessage( 262 if (destination != UUID.Zero && presence.UUID != destination)
226 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) 263 return;
227 receiverIDs.Add(presence.UUID); 264 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
265 if (Presencecheck != null)
266 {
267 // This will pass all chat from objects. Not
268 // perfect, but it will do. For now. Better
269 // than the prior behavior of muting all
270 // objects on a parcel with access restrictions
271 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
272 {
273 if (destination != UUID.Zero)
274 {
275 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
276 receiverIDs.Add(presence.UUID);
277 }
278 else
279 {
280 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
281 receiverIDs.Add(presence.UUID);
282 }
283 }
284 }
228 } 285 }
229 ); 286 );
230 } 287 }
231 else 288
232 { 289 (scene as Scene).EventManager.TriggerOnChatToClients(
233 // This is a send to a specific client eg from llRegionSayTo
234 // no need to check distance etc, jand send is as say
235 ScenePresence presence = scene.GetScenePresence(targetID);
236 if (presence != null && !presence.IsChildAgent)
237 {
238 if (TrySendChatMessage(
239 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
240 receiverIDs.Add(presence.UUID);
241 }
242 }
243
244 scene.EventManager.TriggerOnChatToClients(
245 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 290 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
246 } 291 }
247 292
@@ -280,28 +325,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
280 } 325 }
281 326
282 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 327 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
283
284 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 328 HashSet<UUID> receiverIDs = new HashSet<UUID>();
285 329
286 ((Scene)c.Scene).ForEachRootClient( 330 if (c.Scene != null)
287 delegate(IClientAPI client) 331 {
288 { 332 ((Scene)c.Scene).ForEachRootClient
289 // don't forward SayOwner chat from objects to 333 (
290 // non-owner agents 334 delegate(IClientAPI client)
291 if ((c.Type == ChatTypeEnum.Owner) && 335 {
292 (null != c.SenderObject) && 336 // don't forward SayOwner chat from objects to
293 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 337 // non-owner agents
294 return; 338 if ((c.Type == ChatTypeEnum.Owner) &&
295 339 (null != c.SenderObject) &&
296 client.SendChatMessage( 340 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
297 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 341 return;
298 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 342
299 343 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
300 receiverIDs.Add(client.AgentId); 344 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
301 }); 345 receiverIDs.Add(client.AgentId);
302 346 }
303 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 347 );
304 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 348 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
349 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
350 }
305 } 351 }
306 352
307 /// <summary> 353 /// <summary>
@@ -353,5 +399,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
353 399
354 return true; 400 return true;
355 } 401 }
402
403 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
404 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
405 {
406 System.Threading.Timer Timer;
407 if (flags == 0)
408 {
409 FreezeCache.Add(target.ToString());
410 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
411 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
412 Timers.Add(target, Timer);
413 }
414 else
415 {
416 FreezeCache.Remove(target.ToString());
417 Timers.TryGetValue(target, out Timer);
418 Timers.Remove(target);
419 Timer.Dispose();
420 }
421 }
422
423 private void OnEndParcelFrozen(object avatar)
424 {
425 UUID target = (UUID)avatar;
426 FreezeCache.Remove(target.ToString());
427 System.Threading.Timer Timer;
428 Timers.TryGetValue(target, out Timer);
429 Timers.Remove(target);
430 Timer.Dispose();
431 }
356 } 432 }
357} \ No newline at end of file 433}
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 0cd495c..6b14fa6 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 31c42d8..d56e469 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 1417a19..e285f21 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -164,8 +164,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
164 if (im.binaryBucket.Length < 17) // Invalid 164 if (im.binaryBucket.Length < 17) // Invalid
165 return; 165 return;
166 166
167 UUID receipientID = new UUID(im.toAgentID); 167 UUID recipientID = new UUID(im.toAgentID);
168 ScenePresence user = scene.GetScenePresence(receipientID); 168 ScenePresence user = scene.GetScenePresence(recipientID);
169 UUID copyID; 169 UUID copyID;
170 170
171 // First byte is the asset type 171 // First byte is the asset type
@@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
180 folderID, new UUID(im.toAgentID)); 180 folderID, new UUID(im.toAgentID));
181 181
182 InventoryFolderBase folderCopy 182 InventoryFolderBase folderCopy
183 = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); 183 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
184 184
185 if (folderCopy == null) 185 if (folderCopy == null)
186 { 186 {
@@ -239,6 +239,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
239 im.imSessionID = copyID.Guid; 239 im.imSessionID = copyID.Guid;
240 } 240 }
241 241
242 im.offline = 0;
243
242 // Send the IM to the recipient. The item is already 244 // Send the IM to the recipient. The item is already
243 // in their inventory, so it will not be lost if 245 // in their inventory, so it will not be lost if
244 // they are offline. 246 // they are offline.
@@ -258,8 +260,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
258 }); 260 });
259 } 261 }
260 } 262 }
261 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) 263 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
264 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
262 { 265 {
266 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
267 IInventoryService invService = scene.InventoryService;
268
269 // Special case: folder redirect.
270 // RLV uses this
271 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
272 {
273 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, client.AgentId);
274 folder = invService.GetFolder(folder);
275
276 if (folder != null)
277 {
278 if (im.binaryBucket.Length >= 16)
279 {
280 UUID destFolderID = new UUID(im.binaryBucket, 0);
281 if (destFolderID != UUID.Zero)
282 {
283 InventoryFolderBase destFolder = new InventoryFolderBase(destFolderID, client.AgentId);
284 destFolder = invService.GetFolder(destFolder);
285 if (destFolder != null)
286 {
287 if (folder.ParentID != destFolder.ID)
288 {
289 folder.ParentID = destFolder.ID;
290 invService.MoveFolder(folder);
291 client.SendBulkUpdateInventory(folder);
292 }
293 }
294 }
295 }
296 }
297 }
298
263 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 299 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
264 300
265 if (user != null) // Local 301 if (user != null) // Local
@@ -269,27 +305,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
269 else 305 else
270 { 306 {
271 if (m_TransferModule != null) 307 if (m_TransferModule != null)
272 m_TransferModule.SendInstantMessage(im, delegate(bool success) { 308 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
273
274 // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
275 // and is apparently supposed to fix bulk inventory updates after accepting items. But
276 // instead it appears to cause two copies of an accepted folder for the receiving user in
277 // at least some cases. Folder/item update is already done when the offer is made (see code above)
278
279// // Send BulkUpdateInventory
280// IInventoryService invService = scene.InventoryService;
281// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
282//
283// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
284// folder = invService.GetFolder(folder);
285//
286// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
287//
288// // If the user has left the scene by the time the message comes back then we can't send
289// // them the update.
290// if (fromUser != null)
291// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
292 });
293 } 309 }
294 } 310 }
295 311
@@ -402,6 +418,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
402 previousParentFolderID = folder.ParentID; 418 previousParentFolderID = folder.ParentID;
403 folder.ParentID = trashFolder.ID; 419 folder.ParentID = trashFolder.ID;
404 invService.MoveFolder(folder); 420 invService.MoveFolder(folder);
421 client.SendBulkUpdateInventory(folder);
405 } 422 }
406 } 423 }
407 424
@@ -451,22 +468,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
451 /// 468 ///
452 /// </summary> 469 /// </summary>
453 /// <param name="msg"></param> 470 /// <param name="msg"></param>
454 private void OnGridInstantMessage(GridInstantMessage msg) 471 private void OnGridInstantMessage(GridInstantMessage im)
455 { 472 {
456 // Check if this is ours to handle 473 // Check if this is ours to handle
457 // 474 //
458 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 475 Scene scene = FindClientScene(new UUID(im.toAgentID));
459 476
460 if (scene == null) 477 if (scene == null)
461 return; 478 return;
462 479
463 // Find agent to deliver to 480 // Find agent to deliver to
464 // 481 //
465 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 482 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
483 if (user == null)
484 return;
485
486 // This requires a little bit of processing because we have to make the
487 // new item visible in the recipient's inventory here
488 //
489 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
490 {
491 if (im.binaryBucket.Length < 17) // Invalid
492 return;
493
494 UUID recipientID = new UUID(im.toAgentID);
495
496 // First byte is the asset type
497 AssetType assetType = (AssetType)im.binaryBucket[0];
498
499 if (AssetType.Folder == assetType)
500 {
501 UUID folderID = new UUID(im.binaryBucket, 1);
502
503 InventoryFolderBase given =
504 new InventoryFolderBase(folderID, recipientID);
505 InventoryFolderBase folder =
506 scene.InventoryService.GetFolder(given);
507
508 if (folder != null)
509 user.ControllingClient.SendBulkUpdateInventory(folder);
510 }
511 else
512 {
513 UUID itemID = new UUID(im.binaryBucket, 1);
466 514
467 // Just forward to local handling 515 InventoryItemBase given =
468 OnInstantMessage(user.ControllingClient, msg); 516 new InventoryItemBase(itemID, recipientID);
517 InventoryItemBase item =
518 scene.InventoryService.GetItem(given);
519
520 if (item != null)
521 {
522 user.ControllingClient.SendBulkUpdateInventory(item);
523 }
524 }
525 user.ControllingClient.SendInstantMessage(im);
526 }
527 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
528 {
529 if (im.binaryBucket.Length < 1) // Invalid
530 return;
531
532 UUID recipientID = new UUID(im.toAgentID);
469 533
534 // Bucket is the asset type
535 AssetType assetType = (AssetType)im.binaryBucket[0];
536
537 if (AssetType.Folder == assetType)
538 {
539 UUID folderID = new UUID(im.imSessionID);
540
541 InventoryFolderBase given =
542 new InventoryFolderBase(folderID, recipientID);
543 InventoryFolderBase folder =
544 scene.InventoryService.GetFolder(given);
545
546 if (folder != null)
547 user.ControllingClient.SendBulkUpdateInventory(folder);
548 }
549 else
550 {
551 UUID itemID = new UUID(im.imSessionID);
552
553 InventoryItemBase given =
554 new InventoryItemBase(itemID, recipientID);
555 InventoryItemBase item =
556 scene.InventoryService.GetItem(given);
557
558 if (item != null)
559 {
560 user.ControllingClient.SendBulkUpdateInventory(item);
561 }
562 }
563
564 // Fix up binary bucket since this may be 17 chars long here
565 Byte[] bucket = new Byte[1];
566 bucket[0] = im.binaryBucket[0];
567 im.binaryBucket = bucket;
568
569 user.ControllingClient.SendInstantMessage(im);
570 }
571 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
572 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
573 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
574 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
575 {
576 user.ControllingClient.SendInstantMessage(im);
577 }
470 } 578 }
471 } 579 }
472} 580}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 7f4606b..0c64f19 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("TP invite with message {0}, type {1}", message, lureType); 168 m_log.DebugFormat("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 4219254..ed14c12 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
369 /// <param name="sp"></param> 369 /// <param name="sp"></param>
370 /// <param name="position"></param> 370 /// <param name="position"></param>
371 /// <param name="lookAt"></param> 371 /// <param name="lookAt"></param>
372 /// <param name="teleportFlags"></param 372 /// <param name="teleportFlags"></param>
373 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 373 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
374 { 374 {
375 m_log.DebugFormat( 375 m_log.DebugFormat(
@@ -404,11 +404,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
404 position.Z = newPosZ; 404 position.Z = newPosZ;
405 } 405 }
406 406
407 if (sp.Flying)
408 teleportFlags |= (uint)TeleportFlags.IsFlying;
409
407 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 410 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
408 411
409 sp.ControllingClient.SendTeleportStart(teleportFlags); 412 sp.ControllingClient.SendTeleportStart(teleportFlags);
410 413
411 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 414 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
415 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
412 sp.Velocity = Vector3.Zero; 416 sp.Velocity = Vector3.Zero;
413 sp.Teleport(position); 417 sp.Teleport(position);
414 418
@@ -609,8 +613,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
609 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 613 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
610 // it's actually doing a lot of work. 614 // it's actually doing a lot of work.
611 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 615 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
612 616 if (endPoint == null || endPoint.Address == null)
613 if (endPoint.Address == null)
614 { 617 {
615 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 618 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
616 619
@@ -647,6 +650,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
647 // both regions 650 // both regions
648 if (sp.ParentID != (uint)0) 651 if (sp.ParentID != (uint)0)
649 sp.StandUp(); 652 sp.StandUp();
653 else if (sp.Flying)
654 teleportFlags |= (uint)TeleportFlags.IsFlying;
650 655
651 if (DisableInterRegionTeleportCancellation) 656 if (DisableInterRegionTeleportCancellation)
652 teleportFlags |= (uint)TeleportFlags.DisableCancel; 657 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -1267,11 +1272,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1267 1272
1268 #region Teleport Home 1273 #region Teleport Home
1269 1274
1270 public virtual void TriggerTeleportHome(UUID id, IClientAPI client) 1275 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1271 { 1276 {
1272 TeleportHome(id, client); 1277 TeleportHome(id, client);
1273 } 1278 }
1274 1279
1275 public virtual bool TeleportHome(UUID id, IClientAPI client) 1280 public virtual bool TeleportHome(UUID id, IClientAPI client)
1276 { 1281 {
1277 m_log.DebugFormat( 1282 m_log.DebugFormat(
@@ -1282,6 +1287,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1282 1287
1283 if (uinfo != null) 1288 if (uinfo != null)
1284 { 1289 {
1290 if (uinfo.HomeRegionID == UUID.Zero)
1291 {
1292 // can't find the Home region: Tell viewer and abort
1293 client.SendTeleportFailed("You don't have a home position set.");
1294 return false;
1295 }
1285 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1296 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1286 if (regionInfo == null) 1297 if (regionInfo == null)
1287 { 1298 {
@@ -1301,9 +1312,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1301 } 1312 }
1302 else 1313 else
1303 { 1314 {
1304 m_log.ErrorFormat( 1315 // can't find the Home region: Tell viewer and abort
1305 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1316 client.SendTeleportFailed("Your home region could not be found.");
1306 client.Name, client.AgentId);
1307 } 1317 }
1308 return false; 1318 return false;
1309 } 1319 }
@@ -1313,15 +1323,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1313 1323
1314 #region Agent Crossings 1324 #region Agent Crossings
1315 1325
1316 public bool Cross(ScenePresence agent, bool isFlying) 1326 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1317 { 1327 {
1318 Scene scene = agent.Scene; 1328 version = String.Empty;
1319 Vector3 pos = agent.AbsolutePosition; 1329 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1320 1330
1321// m_log.DebugFormat( 1331// m_log.DebugFormat(
1322// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1332// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1323 1333
1324 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1325 uint neighbourx = scene.RegionInfo.RegionLocX; 1334 uint neighbourx = scene.RegionInfo.RegionLocX;
1326 uint neighboury = scene.RegionInfo.RegionLocY; 1335 uint neighboury = scene.RegionInfo.RegionLocY;
1327 const float boundaryDistance = 1.7f; 1336 const float boundaryDistance = 1.7f;
@@ -1342,52 +1351,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1342 } 1351 }
1343 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1352 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1344 { 1353 {
1345 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1354 neighboury--;
1346 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1355 newpos.Y = Constants.RegionSize - enterDistance;
1347 {
1348 neighboury--;
1349 newpos.Y = Constants.RegionSize - enterDistance;
1350 }
1351 else
1352 {
1353 agent.IsInTransit = true;
1354
1355 neighboury = b.TriggerRegionY;
1356 neighbourx = b.TriggerRegionX;
1357
1358 Vector3 newposition = pos;
1359 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1360 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1361 agent.ControllingClient.SendAgentAlertMessage(
1362 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1363 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1364 return true;
1365 }
1366 }
1367
1368 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1369 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1370 {
1371 neighbourx--;
1372 newpos.X = Constants.RegionSize - enterDistance;
1373 }
1374 else
1375 {
1376 agent.IsInTransit = true;
1377
1378 neighboury = ba.TriggerRegionY;
1379 neighbourx = ba.TriggerRegionX;
1380
1381 Vector3 newposition = pos;
1382 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1383 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1384 agent.ControllingClient.SendAgentAlertMessage(
1385 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1386 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1387
1388 return true;
1389 } 1356 }
1390 1357
1358 neighbourx--;
1359 newpos.X = Constants.RegionSize - enterDistance;
1391 } 1360 }
1392 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1361 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1393 { 1362 {
@@ -1397,26 +1366,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1397 1366
1398 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1367 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1399 { 1368 {
1400 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1369 neighboury--;
1401 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1370 newpos.Y = Constants.RegionSize - enterDistance;
1402 {
1403 neighboury--;
1404 newpos.Y = Constants.RegionSize - enterDistance;
1405 }
1406 else
1407 {
1408 agent.IsInTransit = true;
1409
1410 neighboury = ba.TriggerRegionY;
1411 neighbourx = ba.TriggerRegionX;
1412 Vector3 newposition = pos;
1413 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1414 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1415 agent.ControllingClient.SendAgentAlertMessage(
1416 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1417 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1418 return true;
1419 }
1420 } 1371 }
1421 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1372 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1422 { 1373 {
@@ -1428,25 +1379,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1428 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1379 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1429 { 1380 {
1430 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1381 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1431 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1382 neighboury--;
1432 { 1383 newpos.Y = Constants.RegionSize - enterDistance;
1433 neighboury--;
1434 newpos.Y = Constants.RegionSize - enterDistance;
1435 }
1436 else
1437 {
1438 agent.IsInTransit = true;
1439
1440 neighboury = b.TriggerRegionY;
1441 neighbourx = b.TriggerRegionX;
1442 Vector3 newposition = pos;
1443 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1444 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1445 agent.ControllingClient.SendAgentAlertMessage(
1446 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1447 InformClientToInitiateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1448 return true;
1449 }
1450 } 1384 }
1451 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1385 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1452 { 1386 {
@@ -1480,19 +1414,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1480 } 1414 }
1481 */ 1415 */
1482 1416
1483 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1417 xDest = neighbourx;
1418 yDest = neighboury;
1484 1419
1485 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1420 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1486 1421
1422 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1423
1487 ExpiringCache<ulong, DateTime> r; 1424 ExpiringCache<ulong, DateTime> r;
1488 DateTime banUntil; 1425 DateTime banUntil;
1489 1426
1490 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1427 if (m_bannedRegions.TryGetValue(agentID, out r))
1491 { 1428 {
1492 if (r.TryGetValue(neighbourHandle, out banUntil)) 1429 if (r.TryGetValue(neighbourHandle, out banUntil))
1493 { 1430 {
1494 if (DateTime.Now < banUntil) 1431 if (DateTime.Now < banUntil)
1495 return false; 1432 return null;
1496 r.Remove(neighbourHandle); 1433 r.Remove(neighbourHandle);
1497 } 1434 }
1498 } 1435 }
@@ -1504,28 +1441,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1504 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1441 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1505 1442
1506 string reason; 1443 string reason;
1507 string version; 1444 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1508 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1509 { 1445 {
1510 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1511 if (r == null) 1446 if (r == null)
1512 { 1447 {
1513 r = new ExpiringCache<ulong, DateTime>(); 1448 r = new ExpiringCache<ulong, DateTime>();
1514 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1449 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1515 1450
1516 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1451 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1517 } 1452 }
1518 else 1453 else
1519 { 1454 {
1520 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1455 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1521 } 1456 }
1457 return null;
1458 }
1459
1460 return neighbourRegion;
1461 }
1462
1463 public bool Cross(ScenePresence agent, bool isFlying)
1464 {
1465 uint x;
1466 uint y;
1467 Vector3 newpos;
1468 string version;
1469
1470 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1471 if (neighbourRegion == null)
1472 {
1473 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1522 return false; 1474 return false;
1523 } 1475 }
1524 1476
1525 agent.IsInTransit = true; 1477 agent.IsInTransit = true;
1526 1478
1527 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1479 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1528 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1480 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1529 1481
1530 return true; 1482 return true;
1531 } 1483 }
@@ -1607,52 +1559,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1607 icon.EndInvoke(iar); 1559 icon.EndInvoke(iar);
1608 } 1560 }
1609 1561
1610 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1562 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1563 {
1564 if (neighbourRegion == null)
1565 return false;
1566
1567 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1568
1569 agent.RemoveFromPhysicalScene();
1570
1571 return true;
1572 }
1611 1573
1612 /// <summary> 1574 /// <summary>
1613 /// This Closes child agents on neighbouring regions 1575 /// This Closes child agents on neighbouring regions
1614 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1576 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1615 /// </summary> 1577 /// </summary>
1616 protected ScenePresence CrossAgentToNewRegionAsync( 1578 public ScenePresence CrossAgentToNewRegionAsync(
1617 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1579 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1618 bool isFlying, string version) 1580 bool isFlying, string version)
1619 { 1581 {
1620 if (neighbourRegion == null) 1582 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1583 {
1584 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1621 return agent; 1585 return agent;
1586 }
1622 1587
1623 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1588 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1624 { 1589 {
1625 m_log.ErrorFormat( 1590 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1626 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1627 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1628 return agent; 1591 return agent;
1629 } 1592 }
1630 1593
1631 bool transitWasReset = false; 1594 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1595 return agent;
1596 }
1632 1597
1598 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1599 {
1633 try 1600 try
1634 { 1601 {
1635 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1602 AgentData cAgent = new AgentData();
1636
1637 m_log.DebugFormat(
1638 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1639 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1640
1641 Scene m_scene = agent.Scene;
1642
1643 if (!agent.ValidateAttachments())
1644 m_log.DebugFormat(
1645 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1646 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1647
1648 pos = pos + agent.Velocity;
1649 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1650
1651 agent.RemoveFromPhysicalScene();
1652
1653 AgentData cAgent = new AgentData();
1654 agent.CopyTo(cAgent); 1603 agent.CopyTo(cAgent);
1655 cAgent.Position = pos; 1604 cAgent.Position = pos + agent.Velocity;
1656 if (isFlying) 1605 if (isFlying)
1657 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1606 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1658 1607
@@ -1662,7 +1611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1662 // Beyond this point, extra cleanup is needed beyond removing transit state 1611 // Beyond this point, extra cleanup is needed beyond removing transit state
1663 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1612 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1664 1613
1665 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1614 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1666 { 1615 {
1667 // region doesn't take it 1616 // region doesn't take it
1668 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1617 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1674,88 +1623,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1674 ReInstantiateScripts(agent); 1623 ReInstantiateScripts(agent);
1675 agent.AddToPhysicalScene(isFlying); 1624 agent.AddToPhysicalScene(isFlying);
1676 1625
1677 return agent; 1626 return false;
1678 } 1627 }
1679 1628
1680 //m_log.Debug("BEFORE CROSS"); 1629 }
1681 //Scene.DumpChildrenSeeds(UUID); 1630 catch (Exception e)
1682 //DumpKnownRegions(); 1631 {
1683 string agentcaps; 1632 m_log.ErrorFormat(
1684 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1633 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1685 { 1634 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1686 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1687 neighbourRegion.RegionHandle);
1688 return agent;
1689 }
1690 1635
1691 // No turning back 1636 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1692 agent.IsChildAgent = true; 1637 return false;
1638 }
1693 1639
1694 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1640 return true;
1641 }
1695 1642
1696 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1643 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1644 bool isFlying, string version)
1645 {
1646 agent.ControllingClient.RequestClientInfo();
1697 1647
1698 if (m_eqModule != null) 1648 string agentcaps;
1699 { 1649 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1700 m_eqModule.CrossRegion( 1650 {
1701 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1651 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1702 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1652 neighbourRegion.RegionHandle);
1703 } 1653 return;
1704 else 1654 }
1705 {
1706 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1707 capsPath);
1708 }
1709 1655
1710 // SUCCESS! 1656 // No turning back
1711 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1657 agent.IsChildAgent = true;
1712 1658
1713 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1659 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1714 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1715 1660
1716 agent.MakeChildAgent(); 1661 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1717 1662
1718 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1663 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1719 // but not sure yet what the side effects would be. 1664
1720 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1665 if (m_eqModule != null)
1721 transitWasReset = true; 1666 {
1667 m_eqModule.CrossRegion(
1668 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1669 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1670 }
1671 else
1672 {
1673 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1674 capsPath);
1675 }
1722 1676
1723 // now we have a child agent in this region. Request all interesting data about other (root) agents 1677 // SUCCESS!
1724 agent.SendOtherAgentsAvatarDataToMe(); 1678 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1725 agent.SendOtherAgentsAppearanceToMe();
1726 1679
1727 // Backwards compatibility. Best effort 1680 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1728 if (version == "Unknown" || version == string.Empty) 1681 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1729 {
1730 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1731 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1732 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1733 }
1734 1682
1735 // Next, let's close the child agent connections that are too far away. 1683 agent.MakeChildAgent();
1736 agent.CloseChildAgents(neighbourx, neighboury);
1737 1684
1738 AgentHasMovedAway(agent, false); 1685 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1739 1686 // but not sure yet what the side effects would be.
1740 //m_log.Debug("AFTER CROSS"); 1687 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1741 //Scene.DumpChildrenSeeds(UUID);
1742 //DumpKnownRegions();
1743 }
1744 catch (Exception e)
1745 {
1746 m_log.ErrorFormat(
1747 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1748 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1749 1688
1750 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1689 // now we have a child agent in this region. Request all interesting data about other (root) agents
1751 } 1690 agent.SendOtherAgentsAvatarDataToMe();
1752 finally 1691 agent.SendOtherAgentsAppearanceToMe();
1692
1693 // Backwards compatibility. Best effort
1694 if (version == "Unknown" || version == string.Empty)
1753 { 1695 {
1754 if (!transitWasReset) 1696 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1755 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1697 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1698 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1756 } 1699 }
1757 1700
1758 return agent; 1701 // Next, let's close the child agent connections that are too far away.
1702 uint neighbourx;
1703 uint neighboury;
1704
1705 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1706
1707 neighbourx /= Constants.RegionSize;
1708 neighboury /= Constants.RegionSize;
1709
1710 agent.CloseChildAgents(neighbourx, neighboury);
1711
1712 AgentHasMovedAway(agent, false);
1713
1714 // the user may change their profile information in other region,
1715 // so the userinfo in UserProfileCache is not reliable any more, delete it
1716 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1717// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1718// {
1719// m_log.DebugFormat(
1720// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1721// }
1722
1723 //m_log.Debug("AFTER CROSS");
1724 //Scene.DumpChildrenSeeds(UUID);
1725 //DumpKnownRegions();
1726
1727 return;
1759 } 1728 }
1760 1729
1761 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1730 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1826,10 +1795,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1826 agent.Id0 = currentAgentCircuit.Id0; 1795 agent.Id0 = currentAgentCircuit.Id0;
1827 } 1796 }
1828 1797
1829 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1798 IPEndPoint external = region.ExternalEndPoint;
1830 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1799 if (external != null)
1800 {
1801 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1802 d.BeginInvoke(sp, agent, region, external, true,
1831 InformClientOfNeighbourCompleted, 1803 InformClientOfNeighbourCompleted,
1832 d); 1804 d);
1805 }
1833 } 1806 }
1834 #endregion 1807 #endregion
1835 1808
@@ -2426,30 +2399,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2426 Utils.LongToUInts(newRegionHandle, out x, out y); 2399 Utils.LongToUInts(newRegionHandle, out x, out y);
2427 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2400 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2428 2401
2429 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2402 if (destination != null)
2430 { 2403 {
2431 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2404 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2405 return; // we did it
2406 }
2432 2407
2433 // We are going to move the object back to the old position so long as the old position 2408 // no one or failed lets go back and tell physics to go on
2434 // is in the region 2409 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2435 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2410 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2436 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2411 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2437 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2438 2412
2439 grp.RootPart.GroupPosition = oldGroupPosition; 2413 grp.AbsolutePosition = oldGroupPosition;
2414 grp.Velocity = Vector3.Zero;
2440 2415
2441 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2416 if (grp.RootPart.PhysActor != null)
2442 // move out of the region creating an infinite loop of failed attempts to cross 2417 grp.RootPart.PhysActor.CrossingFailure();
2443 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2444 2418
2445 if (grp.RootPart.KeyframeMotion != null) 2419 if (grp.RootPart.KeyframeMotion != null)
2446 grp.RootPart.KeyframeMotion.CrossingFailure(); 2420 grp.RootPart.KeyframeMotion.CrossingFailure();
2447 2421
2448 grp.ScheduleGroupForFullUpdate(); 2422 grp.ScheduleGroupForFullUpdate();
2449 }
2450 } 2423 }
2451 2424
2452 2425
2426
2453 /// <summary> 2427 /// <summary>
2454 /// Move the given scene object into a new region 2428 /// Move the given scene object into a new region
2455 /// </summary> 2429 /// </summary>
@@ -2500,17 +2474,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2500 grp, e); 2474 grp, e);
2501 } 2475 }
2502 } 2476 }
2477/*
2478 * done on caller ( not in attachments crossing for now)
2503 else 2479 else
2504 { 2480 {
2481
2505 if (!grp.IsDeleted) 2482 if (!grp.IsDeleted)
2506 { 2483 {
2507 PhysicsActor pa = grp.RootPart.PhysActor; 2484 PhysicsActor pa = grp.RootPart.PhysActor;
2508 if (pa != null) 2485 if (pa != null)
2486 {
2509 pa.CrossingFailure(); 2487 pa.CrossingFailure();
2488 if (grp.RootPart.KeyframeMotion != null)
2489 {
2490 // moved to KeyframeMotion.CrossingFailure
2491// grp.RootPart.Velocity = Vector3.Zero;
2492 grp.RootPart.KeyframeMotion.CrossingFailure();
2493// grp.SendGroupRootTerseUpdate();
2494 }
2495 }
2510 } 2496 }
2511 2497
2512 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2498 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2513 } 2499 }
2500 */
2514 } 2501 }
2515 else 2502 else
2516 { 2503 {
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 76dbc72..1cf1884 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 68e4e26..89bb037 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,38 @@ 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 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
396
397 objectGroup.AbsolutePosition = inventoryStoredPosition;
398 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
376 399
377 // Make sure all bits but the ones we want are clear 400 // Make sure all bits but the ones we want are clear
378 // on take. 401 // on take.
@@ -491,8 +514,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
491 IClientAPI remoteClient) 514 IClientAPI remoteClient)
492 { 515 {
493 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; 516 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
517 // For the porposes of inventory, an object is modify if the prims
518 // are modify. This allows renaming an object that contains no
519 // mod items.
494 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 520 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
495 effectivePerms &= grp.GetEffectivePermissions(); 521 {
522 uint groupPerms = grp.GetEffectivePermissions(true);
523 if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0)
524 groupPerms |= (uint)PermissionMask.Modify;
525
526 effectivePerms &= groupPerms;
527 }
496 effectivePerms |= (uint)PermissionMask.Move; 528 effectivePerms |= (uint)PermissionMask.Move;
497 529
498 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 530 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
@@ -673,7 +705,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
673 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId) 705 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId)
674 { 706 {
675 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 707 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
676 folder = m_Scene.InventoryService.GetFolder(f); 708 if (f != null)
709 folder = m_Scene.InventoryService.GetFolder(f);
677 710
678 if(folder.Type == 14 || folder.Type == 16) 711 if(folder.Type == 14 || folder.Type == 16)
679 { 712 {
@@ -709,16 +742,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
709 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 742 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
710 { 743 {
711// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 744// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
712
713 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 745 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
714 item = m_Scene.InventoryService.GetItem(item); 746 item = m_Scene.InventoryService.GetItem(item);
715 747
716 if (item == null) 748 if (item == null)
717 { 749 {
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; 750 return null;
723 } 751 }
724 752
@@ -766,9 +794,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
766 XmlDocument doc = new XmlDocument(); 794 XmlDocument doc = new XmlDocument();
767 doc.LoadXml(xmlData); 795 doc.LoadXml(xmlData);
768 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); 796 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
797 Vector3 rez_pos;
769 if (e == null || attachment) // Single 798 if (e == null || attachment) // Single
770 { 799 {
771 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 800 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
801 if (!attachment)
802 {
803 g.RootPart.AttachPoint = g.RootPart.Shape.State;
804 g.RootPart.AttachOffset = g.AbsolutePosition;
805 g.RootPart.AttachRotation = g.GroupRotation;
806 if (g.RootPart.Shape.PCode != (byte)PCode.NewTree &&
807 g.RootPart.Shape.PCode != (byte)PCode.Tree)
808 g.RootPart.Shape.State = 0;
809 }
772 810
773 objlist.Add(g); 811 objlist.Add(g);
774 veclist.Add(Vector3.Zero); 812 veclist.Add(Vector3.Zero);
@@ -778,6 +816,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
778 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 816 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
779 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); 817 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false);
780 pos.Z += offsetHeight; 818 pos.Z += offsetHeight;
819 rez_pos = pos;
781 } 820 }
782 else 821 else
783 { 822 {
@@ -792,12 +831,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
792 BypassRayCast, bRayEndIsIntersection, true, 831 BypassRayCast, bRayEndIsIntersection, true,
793 bbox, false); 832 bbox, false);
794 833
834 rez_pos = pos;
835
795 pos -= bbox / 2; 836 pos -= bbox / 2;
796 837
797 XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); 838 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
798 foreach (XmlNode n in groups) 839 foreach (XmlNode n in groups)
799 { 840 {
800 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); 841 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
842 g.RootPart.AttachPoint = g.RootPart.Shape.State;
843 g.RootPart.AttachOffset = g.AbsolutePosition;
844 g.RootPart.AttachRotation = g.GroupRotation;
845 if (g.RootPart.Shape.PCode != (byte)PCode.NewTree &&
846 g.RootPart.Shape.PCode != (byte)PCode.Tree)
847 g.RootPart.Shape.State = 0;
801 848
802 objlist.Add(g); 849 objlist.Add(g);
803 XmlElement el = (XmlElement)n; 850 XmlElement el = (XmlElement)n;
@@ -817,12 +864,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
817 } 864 }
818 } 865 }
819 866
820 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) 867 int primcount = 0;
868 foreach (SceneObjectGroup g in objlist)
869 primcount += g.PrimCount;
870
871 if (!m_Scene.Permissions.CanRezObject(
872 primcount, remoteClient.AgentId, rez_pos)
873 && !attachment)
874 {
875 // The client operates in no fail mode. It will
876 // have already removed the item from the folder
877 // if it's no copy.
878 // Put it back if it's not an attachment
879 //
880 if (item != null)
881 {
882 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
883 remoteClient.SendBulkUpdateInventory(item);
884 }
885
886 return null;
887 }
888
889 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, rez_pos, veclist, attachment))
821 return null; 890 return null;
822 891
823 for (int i = 0; i < objlist.Count; i++) 892 for (int i = 0; i < objlist.Count; i++)
824 { 893 {
825 group = objlist[i]; 894 group = objlist[i];
895 SceneObjectPart rootPart = group.RootPart;
826 896
827// m_log.DebugFormat( 897// m_log.DebugFormat(
828// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 898// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -883,8 +953,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
883 953
884 if (!attachment) 954 if (!attachment)
885 { 955 {
886 SceneObjectPart rootPart = group.RootPart;
887
888 if (rootPart.Shape.PCode == (byte)PCode.Prim) 956 if (rootPart.Shape.PCode == (byte)PCode.Prim)
889 group.ClearPartAttachmentData(); 957 group.ClearPartAttachmentData();
890 958
@@ -902,6 +970,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
902// remoteClient.Name); 970// remoteClient.Name);
903 } 971 }
904 972
973 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
974
905 if (item != null) 975 if (item != null)
906 DoPostRezWhenFromItem(item, attachment); 976 DoPostRezWhenFromItem(item, attachment);
907 977
@@ -986,8 +1056,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
986 { 1056 {
987 rootPart.Name = item.Name; 1057 rootPart.Name = item.Name;
988 rootPart.Description = item.Description; 1058 rootPart.Description = item.Description;
989 rootPart.ObjectSaleType = item.SaleType; 1059 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
990 rootPart.SalePrice = item.SalePrice; 1060 {
1061 rootPart.ObjectSaleType = item.SaleType;
1062 rootPart.SalePrice = item.SalePrice;
1063 }
991 } 1064 }
992 1065
993 so.FromFolderID = item.Folder; 1066 so.FromFolderID = item.Folder;
@@ -997,7 +1070,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
997// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1070// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
998 1071
999 if ((rootPart.OwnerID != item.Owner) || 1072 if ((rootPart.OwnerID != item.Owner) ||
1000 (item.CurrentPermissions & 16) != 0) 1073 (item.CurrentPermissions & 16) != 0 ||
1074 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
1001 { 1075 {
1002 //Need to kill the for sale here 1076 //Need to kill the for sale here
1003 rootPart.ObjectSaleType = 0; 1077 rootPart.ObjectSaleType = 0;
@@ -1007,31 +1081,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1007 { 1081 {
1008 foreach (SceneObjectPart part in so.Parts) 1082 foreach (SceneObjectPart part in so.Parts)
1009 { 1083 {
1010 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1011 {
1012 part.EveryoneMask = item.EveryOnePermissions;
1013 part.NextOwnerMask = item.NextPermissions;
1014 }
1015 part.GroupMask = 0; // DO NOT propagate here 1084 part.GroupMask = 0; // DO NOT propagate here
1085
1086 part.LastOwnerID = part.OwnerID;
1087 part.OwnerID = item.Owner;
1088 part.Inventory.ChangeInventoryOwner(item.Owner);
1016 } 1089 }
1017 1090
1018 so.ApplyNextOwnerPermissions(); 1091 so.ApplyNextOwnerPermissions();
1092
1093 // In case the user has changed flags on a received item
1094 // we have to apply those changes after the slam. Else we
1095 // get a net loss of permissions
1096 foreach (SceneObjectPart part in so.Parts)
1097 {
1098 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1099 {
1100 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1101 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1102 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1103 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1104 }
1105 }
1019 } 1106 }
1020 } 1107 }
1021 1108 else
1022 foreach (SceneObjectPart part in so.Parts)
1023 { 1109 {
1024 part.FromUserInventoryItemID = fromUserInventoryItemId; 1110 foreach (SceneObjectPart part in so.Parts)
1025
1026 if ((part.OwnerID != item.Owner) ||
1027 (item.CurrentPermissions & 16) != 0)
1028 { 1111 {
1029 part.Inventory.ChangeInventoryOwner(item.Owner); 1112 part.FromUserInventoryItemID = fromUserInventoryItemId;
1030 part.GroupMask = 0; // DO NOT propagate here 1113
1114 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1115 part.EveryoneMask = item.EveryOnePermissions;
1116 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1117 part.NextOwnerMask = item.NextPermissions;
1118 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1119 part.GroupMask = item.GroupPermissions;
1031 } 1120 }
1032
1033 part.EveryoneMask = item.EveryOnePermissions;
1034 part.NextOwnerMask = item.NextPermissions;
1035 } 1121 }
1036 1122
1037 rootPart.TrimPermissions(); 1123 rootPart.TrimPermissions();
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 97227b3..f196973 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 1a62405..6eb25ef 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,17 +513,14 @@ 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 (OutboundBody != null && OutboundBody.Length > 0) 523 if (OutboundBody.Length > 0)
487 { 524 {
488 byte[] data = Util.UTF8.GetBytes(OutboundBody); 525 byte[] data = Util.UTF8.GetBytes(OutboundBody);
489 526
@@ -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 e86d186..a9aa73c 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].IncomingCloseAgent(id, false, auth_token); 314 m_scenes[destination.RegionID].IncomingCloseAgent(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 32d245f..fcfdf7c 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 31547a6..1808fdd 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 {
@@ -1249,6 +1259,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1249 flags |= RegionFlags.AllowParcelChanges; 1259 flags |= RegionFlags.AllowParcelChanges;
1250 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1260 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1251 flags |= RegionFlags.BlockParcelSearch; 1261 flags |= RegionFlags.BlockParcelSearch;
1262 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1263 flags |= (RegionFlags)(1 << 11);
1264 if (Scene.RegionInfo.RegionSettings.Casino)
1265 flags |= (RegionFlags)(1 << 10);
1252 1266
1253 if (Scene.RegionInfo.RegionSettings.FixedSun) 1267 if (Scene.RegionInfo.RegionSettings.FixedSun)
1254 flags |= RegionFlags.SunFixed; 1268 flags |= RegionFlags.SunFixed;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 1789d6d..dbc9296 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -89,19 +89,21 @@ namespace OpenSim.Region.CoreModules.World.Land
89 /// <value> 89 /// <value>
90 /// Land objects keyed by local id 90 /// Land objects keyed by local id
91 /// </value> 91 /// </value>
92 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 92// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
93
94 //ubit: removed the readonly so i can move it around
95 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
93 96
94 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 97 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
95 98
96 private bool m_allowedForcefulBans = true; 99 private bool m_allowedForcefulBans = true;
100 private UUID DefaultGodParcelGroup;
101 private string DefaultGodParcelName;
97 102
98 // caches ExtendedLandData 103 // caches ExtendedLandData
99 private Cache parcelInfoCache; 104 private Cache parcelInfoCache;
100 105 private Dictionary<UUID, Vector3> forcedPosition =
101 /// <summary> 106 new Dictionary<UUID, Vector3>();
102 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
103 /// </summary>
104 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
105 107
106 #region INonSharedRegionModule Members 108 #region INonSharedRegionModule Members
107 109
@@ -112,6 +114,12 @@ namespace OpenSim.Region.CoreModules.World.Land
112 114
113 public void Initialise(IConfigSource source) 115 public void Initialise(IConfigSource source)
114 { 116 {
117 IConfig cnf = source.Configs["LandManagement"];
118 if (cnf != null)
119 {
120 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
121 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
122 }
115 } 123 }
116 124
117 public void AddRegion(Scene scene) 125 public void AddRegion(Scene scene)
@@ -165,13 +173,6 @@ namespace OpenSim.Region.CoreModules.World.Land
165 m_scene.UnregisterModuleCommander(m_commander.Name); 173 m_scene.UnregisterModuleCommander(m_commander.Name);
166 } 174 }
167 175
168// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
169// {
170// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
171// reason = "You are not allowed to enter this sim.";
172// return nearestParcel != null;
173// }
174
175 /// <summary> 176 /// <summary>
176 /// Processes commandline input. Do not call directly. 177 /// Processes commandline input. Do not call directly.
177 /// </summary> 178 /// </summary>
@@ -216,7 +217,6 @@ namespace OpenSim.Region.CoreModules.World.Land
216 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 217 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
217 client.OnSetStartLocationRequest += ClientOnSetHome; 218 client.OnSetStartLocationRequest += ClientOnSetHome;
218 219
219
220 EntityBase presenceEntity; 220 EntityBase presenceEntity;
221 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 221 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
222 { 222 {
@@ -232,48 +232,6 @@ namespace OpenSim.Region.CoreModules.World.Land
232 232
233 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 233 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
234 { 234 {
235 //If we are forcing a position for them to go
236 if (forcedPosition.ContainsKey(remoteClient.AgentId))
237 {
238 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
239
240 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
241 //When the avatar walks into a ban line on the ground, it prevents getting stuck
242 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
243
244 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
245 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
246 {
247// m_log.DebugFormat(
248// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
249// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
250
251 forcedPosition.Remove(remoteClient.AgentId);
252 }
253 //if we are far away, teleport
254 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
255 {
256 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
257// m_log.DebugFormat(
258// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
259// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
260
261 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
262 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
263
264 forcedPosition.Remove(remoteClient.AgentId);
265 }
266 else
267 {
268// m_log.DebugFormat(
269// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
270// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
271
272 //Forces them toward the forced position we want if they aren't there yet
273 agentData.UseClientAgentPosition = true;
274 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
275 }
276 }
277 } 235 }
278 236
279 public void Close() 237 public void Close()
@@ -298,6 +256,7 @@ namespace OpenSim.Region.CoreModules.World.Land
298 { 256 {
299 LandData newData = data.Copy(); 257 LandData newData = data.Copy();
300 newData.LocalID = local_id; 258 newData.LocalID = local_id;
259 ILandObject landobj = null;
301 260
302 ILandObject land; 261 ILandObject land;
303 lock (m_landList) 262 lock (m_landList)
@@ -337,14 +296,14 @@ namespace OpenSim.Region.CoreModules.World.Land
337 protected ILandObject CreateDefaultParcel() 296 protected ILandObject CreateDefaultParcel()
338 { 297 {
339 m_log.DebugFormat( 298 m_log.DebugFormat(
340 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 299 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
341 300
342 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 301 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
343 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 302 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
344 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 303 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
345 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 304 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
346 305
347 return AddLandObject(fullSimParcel); 306 return AddLandObject(fullSimParcel);
348 } 307 }
349 308
350 public List<ILandObject> AllParcels() 309 public List<ILandObject> AllParcels()
@@ -393,10 +352,16 @@ namespace OpenSim.Region.CoreModules.World.Land
393 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 352 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
394 { 353 {
395 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 354 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
396 if (position.HasValue) 355
397 { 356 if (!position.HasValue)
398 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 357 return;
399 } 358
359 bool isFlying = avatar.PhysicsActor.Flying;
360 avatar.RemoveFromPhysicalScene();
361
362 avatar.AbsolutePosition = (Vector3)position;
363
364 avatar.AddToPhysicalScene(isFlying);
400 } 365 }
401 366
402 public void SendYouAreRestrictedNotice(ScenePresence avatar) 367 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -416,29 +381,7 @@ namespace OpenSim.Region.CoreModules.World.Land
416 } 381 }
417 382
418 if (parcelAvatarIsEntering != null) 383 if (parcelAvatarIsEntering != null)
419 { 384 EnforceBans(parcelAvatarIsEntering, avatar);
420 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
421 {
422 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
423 {
424 SendYouAreBannedNotice(avatar);
425 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
426 }
427 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
428 {
429 SendYouAreRestrictedNotice(avatar);
430 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
431 }
432 else
433 {
434 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
435 }
436 }
437 else
438 {
439 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
440 }
441 }
442 } 385 }
443 } 386 }
444 387
@@ -467,30 +410,51 @@ namespace OpenSim.Region.CoreModules.World.Land
467 410
468 public void SendLandUpdate(ScenePresence avatar, bool force) 411 public void SendLandUpdate(ScenePresence avatar, bool force)
469 { 412 {
413
414 /* stop sendind same data twice
415 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
416 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
417
418 if (over != null)
419 {
420
421 if (force)
422 {
423 if (!avatar.IsChildAgent)
424 {
425 over.SendLandUpdateToClient(avatar.ControllingClient);
426 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
427 m_scene.RegionInfo.RegionID);
428 }
429 }
430
431 if (avatar.currentParcelUUID != over.LandData.GlobalID)
432 {
433 if (!avatar.IsChildAgent)
434 {
435 over.SendLandUpdateToClient(avatar.ControllingClient);
436 avatar.currentParcelUUID = over.LandData.GlobalID;
437 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
438 m_scene.RegionInfo.RegionID);
439 }
440 }
441 */
442 if (avatar.IsChildAgent)
443 return;
444
470 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 445 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
471 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 446 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
472 447
473 if (over != null) 448 if (over != null)
474 { 449 {
475 if (force) 450 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
476 { 451 if (force || NotsameID)
477 if (!avatar.IsChildAgent)
478 {
479 over.SendLandUpdateToClient(avatar.ControllingClient);
480 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
481 m_scene.RegionInfo.RegionID);
482 }
483 }
484
485 if (avatar.currentParcelUUID != over.LandData.GlobalID)
486 { 452 {
487 if (!avatar.IsChildAgent) 453 over.SendLandUpdateToClient(avatar.ControllingClient);
488 { 454 if (NotsameID)
489 over.SendLandUpdateToClient(avatar.ControllingClient);
490 avatar.currentParcelUUID = over.LandData.GlobalID; 455 avatar.currentParcelUUID = over.LandData.GlobalID;
491 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 456 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
492 m_scene.RegionInfo.RegionID); 457 m_scene.RegionInfo.RegionID);
493 }
494 } 458 }
495 } 459 }
496 } 460 }
@@ -542,6 +506,7 @@ namespace OpenSim.Region.CoreModules.World.Land
542 //when we are finally in a safe place, lets release the forced position lock 506 //when we are finally in a safe place, lets release the forced position lock
543 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 507 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
544 } 508 }
509 EnforceBans(parcel, clientAvatar);
545 } 510 }
546 } 511 }
547 512
@@ -692,27 +657,28 @@ namespace OpenSim.Region.CoreModules.World.Land
692 /// </summary> 657 /// </summary>
693 public void Clear(bool setupDefaultParcel) 658 public void Clear(bool setupDefaultParcel)
694 { 659 {
695 List<ILandObject> parcels; 660 Dictionary<int, ILandObject> landworkList;
661 // move to work pointer since we are deleting it all
696 lock (m_landList) 662 lock (m_landList)
697 { 663 {
698 parcels = new List<ILandObject>(m_landList.Values); 664 landworkList = m_landList;
665 m_landList = new Dictionary<int, ILandObject>();
699 } 666 }
700 667
701 foreach (ILandObject lo in parcels) 668 // this 2 methods have locks (now)
669 ResetSimLandObjects();
670
671 if (setupDefaultParcel)
672 CreateDefaultParcel();
673
674 // fire outside events unlocked
675 foreach (ILandObject lo in landworkList.Values)
702 { 676 {
703 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 677 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
704 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 678 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
705 } 679 }
680 landworkList.Clear();
706 681
707 lock (m_landList)
708 {
709 m_landList.Clear();
710
711 ResetSimLandObjects();
712 }
713
714 if (setupDefaultParcel)
715 CreateDefaultParcel();
716 } 682 }
717 683
718 private void performFinalLandJoin(ILandObject master, ILandObject slave) 684 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -759,7 +725,7 @@ namespace OpenSim.Region.CoreModules.World.Land
759 int x; 725 int x;
760 int y; 726 int y;
761 727
762 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 728 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
763 return null; 729 return null;
764 730
765 try 731 try
@@ -809,14 +775,13 @@ namespace OpenSim.Region.CoreModules.World.Land
809 { 775 {
810 try 776 try
811 { 777 {
812 return m_landList[m_landIDList[x / 4, y / 4]]; 778 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
779 return m_landList[m_landIDList[x / 4, y / 4]];
780 //else
781 // return null;
813 } 782 }
814 catch (IndexOutOfRangeException) 783 catch (IndexOutOfRangeException)
815 { 784 {
816// m_log.WarnFormat(
817// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
818// x, y, m_scene.RegionInfo.RegionName);
819
820 return null; 785 return null;
821 } 786 }
822 } 787 }
@@ -975,6 +940,8 @@ namespace OpenSim.Region.CoreModules.World.Land
975 newLand.LandData.Name = newLand.LandData.Name; 940 newLand.LandData.Name = newLand.LandData.Name;
976 newLand.LandData.GlobalID = UUID.Random(); 941 newLand.LandData.GlobalID = UUID.Random();
977 newLand.LandData.Dwell = 0; 942 newLand.LandData.Dwell = 0;
943 // Clear "Show in search" on the cut out parcel to prevent double-charging
944 newLand.LandData.Flags &= ~(uint)ParcelFlags.ShowDirectory;
978 945
979 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 946 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
980 947
@@ -1100,6 +1067,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1100 //Owner Flag 1067 //Owner Flag
1101 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1068 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1102 } 1069 }
1070 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1071 {
1072 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1073 }
1103 else if (currentParcelBlock.LandData.SalePrice > 0 && 1074 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1104 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1075 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1105 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1076 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1180,8 +1151,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1180 { 1151 {
1181 if (!temp.Contains(currentParcel)) 1152 if (!temp.Contains(currentParcel))
1182 { 1153 {
1183 currentParcel.ForceUpdateLandInfo(); 1154 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1184 temp.Add(currentParcel); 1155 {
1156 currentParcel.ForceUpdateLandInfo();
1157 temp.Add(currentParcel);
1158 }
1185 } 1159 }
1186 } 1160 }
1187 } 1161 }
@@ -1400,8 +1374,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1400 1374
1401 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1375 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1402 { 1376 {
1403// m_log.DebugFormat( 1377 Dictionary<int, ILandObject> landworkList;
1404// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); 1378 // move to work pointer since we are deleting it all
1379 lock (m_landList)
1380 {
1381 landworkList = m_landList;
1382 m_landList = new Dictionary<int, ILandObject>();
1383 }
1384
1385 //Remove all the land objects in the sim and then process our new data
1386 foreach (int n in landworkList.Keys)
1387 {
1388 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1389 }
1390 landworkList.Clear();
1391
1392 lock (m_landList)
1393 {
1394 m_landIDList.Initialize();
1395 m_landList.Clear();
1396 }
1405 1397
1406 for (int i = 0; i < data.Count; i++) 1398 for (int i = 0; i < data.Count; i++)
1407 IncomingLandObjectFromStorage(data[i]); 1399 IncomingLandObjectFromStorage(data[i]);
@@ -1409,10 +1401,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1409 1401
1410 public void IncomingLandObjectFromStorage(LandData data) 1402 public void IncomingLandObjectFromStorage(LandData data)
1411 { 1403 {
1404
1412 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1405 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1413 new_land.LandData = data.Copy(); 1406 new_land.LandData = data.Copy();
1414 new_land.SetLandBitmapFromByteArray(); 1407 new_land.SetLandBitmapFromByteArray();
1415 AddLandObject(new_land); 1408 AddLandObject(new_land);
1409 new_land.SendLandUpdateToAvatarsOverMe();
1416 } 1410 }
1417 1411
1418 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1412 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1743,7 +1737,86 @@ namespace OpenSim.Region.CoreModules.World.Land
1743 1737
1744 UpdateLandObject(localID, land.LandData); 1738 UpdateLandObject(localID, land.LandData);
1745 } 1739 }
1746 1740
1741 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1742 {
1743 ILandObject land = null;
1744 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1745 foreach (ILandObject landObject in Land)
1746 {
1747 if (landObject.LandData.LocalID == landID)
1748 {
1749 land = landObject;
1750 }
1751 }
1752 land.DeedToGroup(DefaultGodParcelGroup);
1753 land.LandData.Name = DefaultGodParcelName;
1754 land.SendLandUpdateToAvatarsOverMe();
1755 }
1756
1757 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1758 {
1759 ScenePresence SP;
1760 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1761 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1762 if (SP.UserLevel != 0)
1763 {
1764 if (flags == 0) //All parcels, scripted or not
1765 {
1766 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1767 {
1768 if (e.OwnerID == targetID)
1769 {
1770 returns.Add(e);
1771 }
1772 }
1773 );
1774 }
1775 if (flags == 4) //All parcels, scripted object
1776 {
1777 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1778 {
1779 if (e.OwnerID == targetID)
1780 {
1781 if (e.ContainsScripts())
1782 {
1783 returns.Add(e);
1784 }
1785 }
1786 }
1787 );
1788 }
1789 if (flags == 4) //not target parcel, scripted object
1790 {
1791 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1792 {
1793 if (e.OwnerID == targetID)
1794 {
1795 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1796 if (landobject.LandData.OwnerID != e.OwnerID)
1797 {
1798 if (e.ContainsScripts())
1799 {
1800 returns.Add(e);
1801 }
1802 }
1803 }
1804 }
1805 );
1806 }
1807 foreach (SceneObjectGroup ol in returns)
1808 {
1809 ReturnObject(ol, client);
1810 }
1811 }
1812 }
1813 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1814 {
1815 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1816 objs[0] = obj;
1817 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1818 }
1819
1747 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>(); 1820 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1748 1821
1749 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1822 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
@@ -1779,7 +1852,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1779 } 1852 }
1780 } 1853 }
1781 } 1854 }
1782
1783 private void OnEndParcelFrozen(object avatar) 1855 private void OnEndParcelFrozen(object avatar)
1784 { 1856 {
1785 ScenePresence targetAvatar = (ScenePresence)avatar; 1857 ScenePresence targetAvatar = (ScenePresence)avatar;
@@ -1790,6 +1862,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1790 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); 1862 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1791 } 1863 }
1792 1864
1865
1793 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) 1866 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1794 { 1867 {
1795 ScenePresence targetAvatar = null; 1868 ScenePresence targetAvatar = null;
@@ -1809,12 +1882,13 @@ namespace OpenSim.Region.CoreModules.World.Land
1809 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) && 1882 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1810 !m_scene.Permissions.IsAdministrator(client.AgentId)) 1883 !m_scene.Permissions.IsAdministrator(client.AgentId))
1811 return; 1884 return;
1885
1812 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); 1886 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1813 1887
1814 targetAvatar.TeleportWithMomentum(pos, null); 1888 targetAvatar.TeleportWithMomentum(pos, null);
1815 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); 1889 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1816 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); 1890 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1817 1891
1818 if ((flags & 1) != 0) // Ban TODO: Remove magic number 1892 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1819 { 1893 {
1820 LandAccessEntry entry = new LandAccessEntry(); 1894 LandAccessEntry entry = new LandAccessEntry();
@@ -1872,7 +1946,6 @@ namespace OpenSim.Region.CoreModules.World.Land
1872 m_Dialog.SendAlertToUser(remoteClient, "You are not allowed to set your home location in this parcel."); 1946 m_Dialog.SendAlertToUser(remoteClient, "You are not allowed to set your home location in this parcel.");
1873 } 1947 }
1874 1948
1875
1876 protected void InstallInterfaces() 1949 protected void InstallInterfaces()
1877 { 1950 {
1878 Command clearCommand 1951 Command clearCommand
@@ -1934,5 +2007,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1934 2007
1935 MainConsole.Instance.Output(report.ToString()); 2008 MainConsole.Instance.Output(report.ToString());
1936 } 2009 }
2010
2011 public void EnforceBans(ILandObject land, ScenePresence avatar)
2012 {
2013 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
2014 return;
2015
2016 if (land.IsEitherBannedOrRestricted(avatar.UUID))
2017 {
2018 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
2019 {
2020 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
2021 if (pos == null)
2022 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
2023 else
2024 ForceAvatarToPosition(avatar, (Vector3)pos);
2025 }
2026 else
2027 {
2028 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
2029 }
2030 }
2031 }
1937 } 2032 }
1938} 2033}
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 89f3280..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,7 +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"); 213 if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
214 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
211 SendProfileToClient(presence.ControllingClient); 215 SendProfileToClient(presence.ControllingClient);
212 } 216 }
213 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/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 a26a5f0..bf18616 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
@@ -176,13 +173,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
176 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent; 173 m_scene.EventManager.OnMakeRootAgent += MakeRootAgent;
177 m_scene.EventManager.OnRegionUp += OnRegionUp; 174 m_scene.EventManager.OnRegionUp += OnRegionUp;
178 175
179// StartThread(new object()); 176 StartThread(new object());
180 } 177 }
181 178
182 // this has to be called with a lock on m_scene 179 // this has to be called with a lock on m_scene
183 protected virtual void RemoveHandlers() 180 protected virtual void RemoveHandlers()
184 { 181 {
185// StopThread(); 182 StopThread();
186 183
187 m_scene.EventManager.OnRegionUp -= OnRegionUp; 184 m_scene.EventManager.OnRegionUp -= OnRegionUp;
188 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent; 185 m_scene.EventManager.OnMakeRootAgent -= MakeRootAgent;
@@ -240,54 +237,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
240 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 237 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
241 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 238 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
242 239
243 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 240 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
244 { 241 //{
245 ScenePresence avatarPresence = null; 242 // ScenePresence avatarPresence = null;
246 243
247 m_scene.TryGetScenePresence(agentID, out avatarPresence); 244 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
248 245
249 if (avatarPresence != null) 246 // if (avatarPresence != null)
250 { 247 // {
251 bool lookup = false; 248 // bool lookup = false;
252 249
253 lock (cachedMapBlocks) 250 // lock (cachedMapBlocks)
254 { 251 // {
255 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 252 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
256 { 253 // {
257 List<MapBlockData> mapBlocks; 254 // List<MapBlockData> mapBlocks;
258 255
259 mapBlocks = cachedMapBlocks; 256 // mapBlocks = cachedMapBlocks;
260 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 257 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
261 } 258 // }
262 else 259 // else
263 { 260 // {
264 lookup = true; 261 // lookup = true;
265 } 262 // }
266 } 263 // }
267 if (lookup) 264 // if (lookup)
268 { 265 // {
269 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 266 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
270 267
271 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 268 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
272 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 269 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
273 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 270 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
274 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 271 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
275 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 272 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
276 foreach (GridRegion r in regions) 273 // foreach (GridRegion r in regions)
277 { 274 // {
278 MapBlockData block = new MapBlockData(); 275 // MapBlockData block = new MapBlockData();
279 MapBlockFromGridRegion(block, r, 0); 276 // MapBlockFromGridRegion(block, r, 0);
280 mapBlocks.Add(block); 277 // mapBlocks.Add(block);
281 } 278 // }
282 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 279 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
283 280
284 lock (cachedMapBlocks) 281 // lock (cachedMapBlocks)
285 cachedMapBlocks = mapBlocks; 282 // cachedMapBlocks = mapBlocks;
286 283
287 cachedTime = Util.UnixTimeSinceEpoch(); 284 // cachedTime = Util.UnixTimeSinceEpoch();
288 } 285 // }
289 } 286 // }
290 } 287 //}
291 288
292 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 289 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
293 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 290 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -314,8 +311,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
314 protected static OSDMapLayer GetOSDMapLayerResponse() 311 protected static OSDMapLayer GetOSDMapLayerResponse()
315 { 312 {
316 OSDMapLayer mapLayer = new OSDMapLayer(); 313 OSDMapLayer mapLayer = new OSDMapLayer();
317 mapLayer.Right = 5000; 314 mapLayer.Right = 2048;
318 mapLayer.Top = 5000; 315 mapLayer.Top = 2048;
319 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 316 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
320 317
321 return mapLayer; 318 return mapLayer;
@@ -344,6 +341,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
344 { 341 {
345 m_rootAgents.Remove(AgentId); 342 m_rootAgents.Remove(AgentId);
346 } 343 }
344 lock (m_mapBlockRequestEvent)
345 {
346 if (m_mapBlockRequests.ContainsKey(AgentId))
347 m_mapBlockRequests.Remove(AgentId);
348 }
347 } 349 }
348 #endregion 350 #endregion
349 351
@@ -366,6 +368,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
366 ThreadPriority.BelowNormal, 368 ThreadPriority.BelowNormal,
367 true, 369 true,
368 true); 370 true);
371 Watchdog.StartThread(
372 MapBlockSendThread,
373 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
374 ThreadPriority.BelowNormal,
375 true,
376 true);
369 } 377 }
370 378
371 /// <summary> 379 /// <summary>
@@ -381,7 +389,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
381 st.itemtype=0; 389 st.itemtype=0;
382 st.regionhandle=0; 390 st.regionhandle=0;
383 391
384 requests.Enqueue(st); 392 lock (requests)
393 {
394 queueEvent.Set();
395 requests.Enqueue(st);
396 }
397
398 MapBlockRequestData req = new MapBlockRequestData();
399
400 req.client = null;
401 req.minX = 0;
402 req.maxX = 0;
403 req.minY = 0;
404 req.maxY = 0;
405 req.flags = 0;
406
407 lock (m_mapBlockRequestEvent)
408 {
409 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
410 m_mapBlockRequests[UUID.Zero].Enqueue(req);
411 m_mapBlockRequestEvent.Set();
412 }
385 } 413 }
386 414
387 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 415 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -532,12 +560,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
532 /// </summary> 560 /// </summary>
533 public void process() 561 public void process()
534 { 562 {
535 //const int MAX_ASYNC_REQUESTS = 20; 563 const int MAX_ASYNC_REQUESTS = 20;
536 try 564 try
537 { 565 {
538 while (true) 566 while (true)
539 { 567 {
540 MapRequestState st = requests.Dequeue(1000); 568 MapRequestState st = new MapRequestState();
569 bool valid = false;
570 queueEvent.WaitOne();
571 lock (requests)
572 {
573 if (requests.Count > 0)
574 {
575 st = requests.Dequeue();
576 valid = true;
577 }
578 if (requests.Count == 0)
579 queueEvent.Reset();
580 }
581 if (!valid)
582 continue;
541 583
542 // end gracefully 584 // end gracefully
543 if (st.agentID == STOP_UUID) 585 if (st.agentID == STOP_UUID)
@@ -555,13 +597,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
555 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 597 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
556 { 598 {
557 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 599 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
558 Thread.Sleep(80); 600 Thread.Sleep(100);
559 601
560 RequestMapItemsDelegate d = RequestMapItemsAsync;
561 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
562 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
563 //RequestMapItemsCompleted(response);
564 Interlocked.Increment(ref nAsyncRequests); 602 Interlocked.Increment(ref nAsyncRequests);
603 Util.FireAndForget(x =>
604 {
605 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
606 });
565 } 607 }
566 } 608 }
567 609
@@ -577,147 +619,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
577 Watchdog.RemoveThread(); 619 Watchdog.RemoveThread();
578 } 620 }
579 621
580 const int MAX_ASYNC_REQUESTS = 20;
581
582 /// <summary> 622 /// <summary>
583 /// Enqueues the map item request into the services throttle processing thread 623 /// Enqueues the map item request into the processing thread
584 /// </summary> 624 /// </summary>
585 /// <param name="state"></param> 625 /// <param name="state"></param>
586 public void EnqueueMapItemRequest(MapRequestState st) 626 public void EnqueueMapItemRequest(MapRequestState state)
587 {
588
589 m_ServiceThrottle.Enqueue("map-item", st.regionhandle.ToString() + st.agentID.ToString(), delegate
590 {
591 if (st.agentID != UUID.Zero)
592 {
593 bool dorequest = true;
594 lock (m_rootAgents)
595 {
596 if (!m_rootAgents.Contains(st.agentID))
597 dorequest = false;
598 }
599
600 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
601 {
602 if (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
603 {
604 // AH!!! Recursive !
605 // Put this request back in the queue and return
606 EnqueueMapItemRequest(st);
607 return;
608 }
609
610 RequestMapItemsDelegate d = RequestMapItemsAsync;
611 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
612 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
613 //RequestMapItemsCompleted(response);
614 Interlocked.Increment(ref nAsyncRequests);
615 }
616 }
617 });
618 }
619
620 /// <summary>
621 /// Sends the mapitem response to the IClientAPI
622 /// </summary>
623 /// <param name="response">The OSDMap Response for the mapitem</param>
624 private void RequestMapItemsCompleted(IAsyncResult iar)
625 { 627 {
626 AsyncResult result = (AsyncResult)iar; 628 lock (requests)
627 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
628
629 OSDMap response = (OSDMap)icon.EndInvoke(iar);
630
631 Interlocked.Decrement(ref nAsyncRequests);
632
633 if (!response.ContainsKey("requestID"))
634 return;
635
636 UUID requestID = response["requestID"].AsUUID();
637
638 if (requestID != UUID.Zero)
639 { 629 {
640 MapRequestState mrs = new MapRequestState(); 630 queueEvent.Set();
641 mrs.agentID = UUID.Zero; 631 requests.Enqueue(state);
642 lock (m_openRequests)
643 {
644 if (m_openRequests.ContainsKey(requestID))
645 {
646 mrs = m_openRequests[requestID];
647 m_openRequests.Remove(requestID);
648 }
649 }
650
651 if (mrs.agentID != UUID.Zero)
652 {
653 ScenePresence av = null;
654 m_scene.TryGetScenePresence(mrs.agentID, out av);
655 if (av != null)
656 {
657 if (response.ContainsKey(mrs.itemtype.ToString()))
658 {
659 List<mapItemReply> returnitems = new List<mapItemReply>();
660 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
661 for (int i = 0; i < itemarray.Count; i++)
662 {
663 OSDMap mapitem = (OSDMap)itemarray[i];
664 mapItemReply mi = new mapItemReply();
665 mi.x = (uint)mapitem["X"].AsInteger();
666 mi.y = (uint)mapitem["Y"].AsInteger();
667 mi.id = mapitem["ID"].AsUUID();
668 mi.Extra = mapitem["Extra"].AsInteger();
669 mi.Extra2 = mapitem["Extra2"].AsInteger();
670 mi.name = mapitem["Name"].AsString();
671 returnitems.Add(mi);
672 }
673 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
674 }
675
676 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
677 uint itemtype = 7;
678
679 if (response.ContainsKey(itemtype.ToString()))
680 {
681 List<mapItemReply> returnitems = new List<mapItemReply>();
682 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
683 for (int i = 0; i < itemarray.Count; i++)
684 {
685 OSDMap mapitem = (OSDMap)itemarray[i];
686 mapItemReply mi = new mapItemReply();
687 mi.x = (uint)mapitem["X"].AsInteger();
688 mi.y = (uint)mapitem["Y"].AsInteger();
689 mi.id = mapitem["ID"].AsUUID();
690 mi.Extra = mapitem["Extra"].AsInteger();
691 mi.Extra2 = mapitem["Extra2"].AsInteger();
692 mi.name = mapitem["Name"].AsString();
693 returnitems.Add(mi);
694 }
695 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
696 }
697
698 // Service 1 (MAP_ITEM_TELEHUB)
699 itemtype = 1;
700
701 if (response.ContainsKey(itemtype.ToString()))
702 {
703 List<mapItemReply> returnitems = new List<mapItemReply>();
704 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
705 for (int i = 0; i < itemarray.Count; i++)
706 {
707 OSDMap mapitem = (OSDMap)itemarray[i];
708 mapItemReply mi = new mapItemReply();
709 mi.x = (uint)mapitem["X"].AsInteger();
710 mi.y = (uint)mapitem["Y"].AsInteger();
711 mi.id = mapitem["ID"].AsUUID();
712 mi.Extra = mapitem["Extra"].AsInteger();
713 mi.Extra2 = mapitem["Extra2"].AsInteger();
714 mi.name = mapitem["Name"].AsString();
715 returnitems.Add(mi);
716 }
717 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
718 }
719 }
720 }
721 } 632 }
722 } 633 }
723 634
@@ -744,8 +655,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
744 EnqueueMapItemRequest(st); 655 EnqueueMapItemRequest(st);
745 } 656 }
746 657
747 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
748 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
749 /// <summary> 658 /// <summary>
750 /// Does the actual remote mapitem request 659 /// Does the actual remote mapitem request
751 /// This should be called from an asynchronous thread 660 /// This should be called from an asynchronous thread
@@ -760,7 +669,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
760 /// <param name="itemtype">passed in from packet</param> 669 /// <param name="itemtype">passed in from packet</param>
761 /// <param name="regionhandle">Region we're looking up</param> 670 /// <param name="regionhandle">Region we're looking up</param>
762 /// <returns></returns> 671 /// <returns></returns>
763 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 672 private void RequestMapItemsAsync(UUID id, uint flags,
764 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 673 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
765 { 674 {
766// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 675// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -783,7 +692,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
783 } 692 }
784 693
785 if (blacklisted) 694 if (blacklisted)
786 return new OSDMap(); 695 {
696 Interlocked.Decrement(ref nAsyncRequests);
697 return;
698 }
787 699
788 UUID requestID = UUID.Random(); 700 UUID requestID = UUID.Random();
789 lock (m_cachedRegionMapItemsAddress) 701 lock (m_cachedRegionMapItemsAddress)
@@ -791,6 +703,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
791 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 703 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
792 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 704 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
793 } 705 }
706
794 if (httpserver.Length == 0) 707 if (httpserver.Length == 0)
795 { 708 {
796 uint x = 0, y = 0; 709 uint x = 0, y = 0;
@@ -835,18 +748,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
835 748
836 // Can't find the http server 749 // Can't find the http server
837 if (httpserver.Length == 0 || blacklisted) 750 if (httpserver.Length == 0 || blacklisted)
838 return new OSDMap(); 751 {
839 752 Interlocked.Decrement(ref nAsyncRequests);
840 MapRequestState mrs = new MapRequestState(); 753 return;
841 mrs.agentID = id; 754 }
842 mrs.EstateID = EstateID;
843 mrs.flags = flags;
844 mrs.godlike = godlike;
845 mrs.itemtype=itemtype;
846 mrs.regionhandle = regionhandle;
847
848 lock (m_openRequests)
849 m_openRequests.Add(requestID, mrs);
850 755
851 WebRequest mapitemsrequest = null; 756 WebRequest mapitemsrequest = null;
852 try 757 try
@@ -856,7 +761,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
856 catch (Exception e) 761 catch (Exception e)
857 { 762 {
858 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 763 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
859 return new OSDMap(); 764 Interlocked.Decrement(ref nAsyncRequests);
765 return;
860 } 766 }
861 767
862 mapitemsrequest.Method = "POST"; 768 mapitemsrequest.Method = "POST";
@@ -881,7 +787,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
881 catch (WebException ex) 787 catch (WebException ex)
882 { 788 {
883 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 789 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
884 responseMap["connect"] = OSD.FromBoolean(false);
885 lock (m_blacklistedurls) 790 lock (m_blacklistedurls)
886 { 791 {
887 if (!m_blacklistedurls.ContainsKey(httpserver)) 792 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -890,13 +795,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
890 795
891 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 796 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
892 797
893 return responseMap; 798 Interlocked.Decrement(ref nAsyncRequests);
799 return;
894 } 800 }
895 catch 801 catch
896 { 802 {
897 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 803 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
898 responseMap["connect"] = OSD.FromBoolean(false); 804 Interlocked.Decrement(ref nAsyncRequests);
899 return responseMap; 805 return;
900 } 806 }
901 finally 807 finally
902 { 808 {
@@ -905,26 +811,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
905 } 811 }
906 812
907 string response_mapItems_reply = null; 813 string response_mapItems_reply = null;
908 { 814 { // get the response
815 StreamReader sr = null;
909 try 816 try
910 { 817 {
911 using (WebResponse webResponse = mapitemsrequest.GetResponse()) 818 WebResponse webResponse = mapitemsrequest.GetResponse();
819 if (webResponse != null)
912 { 820 {
913 if (webResponse != null) 821 sr = new StreamReader(webResponse.GetResponseStream());
914 { 822 response_mapItems_reply = sr.ReadToEnd().Trim();
915 using (Stream s = webResponse.GetResponseStream()) 823 }
916 using (StreamReader sr = new StreamReader(s)) 824 else
917 response_mapItems_reply = sr.ReadToEnd().Trim(); 825 {
918 } 826 Interlocked.Decrement(ref nAsyncRequests);
919 else 827 return;
920 { 828 }
921 return new OSDMap();
922 }
923 }
924 } 829 }
925 catch (WebException) 830 catch (WebException)
926 { 831 {
927 responseMap["connect"] = OSD.FromBoolean(false);
928 lock (m_blacklistedurls) 832 lock (m_blacklistedurls)
929 { 833 {
930 if (!m_blacklistedurls.ContainsKey(httpserver)) 834 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -933,19 +837,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
933 837
934 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 838 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
935 839
936 return responseMap; 840 Interlocked.Decrement(ref nAsyncRequests);
841 return;
937 } 842 }
938 catch 843 catch
939 { 844 {
940 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 845 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
941 responseMap["connect"] = OSD.FromBoolean(false);
942 lock (m_blacklistedregions) 846 lock (m_blacklistedregions)
943 { 847 {
944 if (!m_blacklistedregions.ContainsKey(regionhandle)) 848 if (!m_blacklistedregions.ContainsKey(regionhandle))
945 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 849 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
946 } 850 }
947 851
948 return responseMap; 852 Interlocked.Decrement(ref nAsyncRequests);
853 return;
854 }
855 finally
856 {
857 if (sr != null)
858 sr.Close();
949 } 859 }
950 860
951 OSD rezResponse = null; 861 OSD rezResponse = null;
@@ -959,15 +869,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
959 catch (Exception ex) 869 catch (Exception ex)
960 { 870 {
961 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 871 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
962 responseMap["connect"] = OSD.FromBoolean(false);
963
964 lock (m_blacklistedregions) 872 lock (m_blacklistedregions)
965 { 873 {
966 if (!m_blacklistedregions.ContainsKey(regionhandle)) 874 if (!m_blacklistedregions.ContainsKey(regionhandle))
967 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 875 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
968 } 876 }
969 877
970 return responseMap; 878 Interlocked.Decrement(ref nAsyncRequests);
879 return;
971 } 880 }
972 } 881 }
973 882
@@ -981,7 +890,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
981 } 890 }
982 } 891 }
983 892
984 return responseMap; 893 Interlocked.Decrement(ref nAsyncRequests);
894
895 if (id != UUID.Zero)
896 {
897 ScenePresence av = null;
898 m_scene.TryGetScenePresence(id, out av);
899 if (av != null)
900 {
901 if (responseMap.ContainsKey(itemtype.ToString()))
902 {
903 List<mapItemReply> returnitems = new List<mapItemReply>();
904 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
905 for (int i = 0; i < itemarray.Count; i++)
906 {
907 OSDMap mapitem = (OSDMap)itemarray[i];
908 mapItemReply mi = new mapItemReply();
909 mi.x = (uint)mapitem["X"].AsInteger();
910 mi.y = (uint)mapitem["Y"].AsInteger();
911 mi.id = mapitem["ID"].AsUUID();
912 mi.Extra = mapitem["Extra"].AsInteger();
913 mi.Extra2 = mapitem["Extra2"].AsInteger();
914 mi.name = mapitem["Name"].AsString();
915 returnitems.Add(mi);
916 }
917 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
918 }
919
920 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
921 itemtype = 7;
922
923 if (responseMap.ContainsKey(itemtype.ToString()))
924 {
925 List<mapItemReply> returnitems = new List<mapItemReply>();
926 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
927 for (int i = 0; i < itemarray.Count; i++)
928 {
929 OSDMap mapitem = (OSDMap)itemarray[i];
930 mapItemReply mi = new mapItemReply();
931 mi.x = (uint)mapitem["X"].AsInteger();
932 mi.y = (uint)mapitem["Y"].AsInteger();
933 mi.id = mapitem["ID"].AsUUID();
934 mi.Extra = mapitem["Extra"].AsInteger();
935 mi.Extra2 = mapitem["Extra2"].AsInteger();
936 mi.name = mapitem["Name"].AsString();
937 returnitems.Add(mi);
938 }
939 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
940 }
941
942 // Service 1 (MAP_ITEM_TELEHUB)
943 itemtype = 1;
944
945 if (responseMap.ContainsKey(itemtype.ToString()))
946 {
947 List<mapItemReply> returnitems = new List<mapItemReply>();
948 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
949 for (int i = 0; i < itemarray.Count; i++)
950 {
951 OSDMap mapitem = (OSDMap)itemarray[i];
952 mapItemReply mi = new mapItemReply();
953 mi.x = (uint)mapitem["X"].AsInteger();
954 mi.y = (uint)mapitem["Y"].AsInteger();
955 mi.id = mapitem["ID"].AsUUID();
956 mi.Extra = mapitem["Extra"].AsInteger();
957 mi.Extra2 = mapitem["Extra2"].AsInteger();
958 mi.name = mapitem["Name"].AsString();
959 returnitems.Add(mi);
960 }
961 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
962 }
963 }
964 }
985 } 965 }
986 966
987 /// <summary> 967 /// <summary>
@@ -991,7 +971,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
991 /// <param name="minY"></param> 971 /// <param name="minY"></param>
992 /// <param name="maxX"></param> 972 /// <param name="maxX"></param>
993 /// <param name="maxY"></param> 973 /// <param name="maxY"></param>
994 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 974 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
995 { 975 {
996 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 976 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
997 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 977 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1044,21 +1024,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1044 1024
1045 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1025 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1046 { 1026 {
1027 MapBlockRequestData req = new MapBlockRequestData();
1028
1029 req.client = remoteClient;
1030 req.minX = minX;
1031 req.maxX = maxX;
1032 req.minY = minY;
1033 req.maxY = maxY;
1034 req.flags = flag;
1035
1036 lock (m_mapBlockRequestEvent)
1037 {
1038 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1039 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1040 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1041 m_mapBlockRequestEvent.Set();
1042 }
1043
1044 return new List<MapBlockData>();
1045 }
1046
1047 protected void MapBlockSendThread()
1048 {
1049 while (true)
1050 {
1051 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1052
1053 m_mapBlockRequestEvent.WaitOne();
1054 lock (m_mapBlockRequestEvent)
1055 {
1056 int total = 0;
1057 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1058 {
1059 if (q.Count > 0)
1060 thisRunData.Add(q.Dequeue());
1061
1062 total += q.Count;
1063 }
1064
1065 if (total == 0)
1066 m_mapBlockRequestEvent.Reset();
1067 }
1068
1069 foreach (MapBlockRequestData req in thisRunData)
1070 {
1071 // Null client stops thread
1072 if (req.client == null)
1073 return;
1074
1075 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1076 }
1077
1078 Thread.Sleep(50);
1079 }
1080 }
1081
1082 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1083 {
1084 List<MapBlockData> allBlocks = new List<MapBlockData>();
1047 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1085 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1048 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1086 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1049 (minX - 4) * (int)Constants.RegionSize, 1087 minX * (int)Constants.RegionSize,
1050 (maxX + 4) * (int)Constants.RegionSize, 1088 maxX * (int)Constants.RegionSize,
1051 (minY - 4) * (int)Constants.RegionSize, 1089 minY * (int)Constants.RegionSize,
1052 (maxY + 4) * (int)Constants.RegionSize); 1090 maxY * (int)Constants.RegionSize);
1091// (minX - 4) * (int)Constants.RegionSize,
1092// (maxX + 4) * (int)Constants.RegionSize,
1093// (minY - 4) * (int)Constants.RegionSize,
1094// (maxY + 4) * (int)Constants.RegionSize);
1053 foreach (GridRegion r in regions) 1095 foreach (GridRegion r in regions)
1054 { 1096 {
1055 MapBlockData block = new MapBlockData(); 1097 MapBlockData block = new MapBlockData();
1056 MapBlockFromGridRegion(block, r, flag); 1098 MapBlockFromGridRegion(block, r, flag);
1057 mapBlocks.Add(block); 1099 mapBlocks.Add(block);
1100 allBlocks.Add(block);
1101 if (mapBlocks.Count >= 10)
1102 {
1103 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1104 mapBlocks.Clear();
1105 Thread.Sleep(50);
1106 }
1058 } 1107 }
1059 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1108 if (mapBlocks.Count > 0)
1109 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1060 1110
1061 return mapBlocks; 1111 return allBlocks;
1062 } 1112 }
1063 1113
1064 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1114 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1282,7 +1332,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1282 } 1332 }
1283 else 1333 else
1284 { 1334 {
1285 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1335 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1286 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1336 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1287 { 1337 {
1288 OSDMap responsemapdata = new OSDMap(); 1338 OSDMap responsemapdata = new OSDMap();
@@ -1458,6 +1508,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1458 { 1508 {
1459 m_rootAgents.Remove(avatar.UUID); 1509 m_rootAgents.Remove(avatar.UUID);
1460 } 1510 }
1511
1512 lock (m_mapBlockRequestEvent)
1513 {
1514 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1515 m_mapBlockRequests.Remove(avatar.UUID);
1516 }
1461 } 1517 }
1462 1518
1463 public void OnRegionUp(GridRegion otherRegion) 1519 public void OnRegionUp(GridRegion otherRegion)
@@ -1502,9 +1558,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1502 Color background = Color.FromArgb(0, 0, 0, 0); 1558 Color background = Color.FromArgb(0, 0, 0, 0);
1503 SolidBrush transparent = new SolidBrush(background); 1559 SolidBrush transparent = new SolidBrush(background);
1504 Graphics g = Graphics.FromImage(overlay); 1560 Graphics g = Graphics.FromImage(overlay);
1505 g.FillRectangle(transparent, 0, 0, 256, 256); 1561 g.FillRectangle(transparent, 0, 0, 255, 255);
1506 1562
1507 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1563 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1564 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1508 1565
1509 foreach (ILandObject land in parcels) 1566 foreach (ILandObject land in parcels)
1510 { 1567 {
@@ -1512,8 +1569,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1512 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1569 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1513 { 1570 {
1514 landForSale = true; 1571 landForSale = true;
1572
1573 bool[,] landBitmap = land.GetLandBitmap();
1574
1575 for (int x = 0 ; x < 64 ; x++)
1576 {
1577 for (int y = 0 ; y < 64 ; y++)
1578 {
1579 if (landBitmap[x, y])
1580 {
1581 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1582
1583 if (x > 0)
1584 {
1585 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1586 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1587 }
1588 if (y > 0)
1589 {
1590 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1591 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1592 }
1593 if (x < 63)
1594 {
1595 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1596 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1597 }
1598 if (y < 63)
1599 {
1600 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1601 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1602 }
1603 }
1604 }
1605 }
1515 1606
1516 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1607 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1517 } 1608 }
1518 } 1609 }
1519 1610
@@ -1525,15 +1616,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1525 1616
1526 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1617 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1527 1618
1528 for (int x = 0 ; x < 64 ; x++)
1529 {
1530 for (int y = 0 ; y < 64 ; y++)
1531 {
1532 if (saleBitmap[x, y])
1533 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1534 }
1535 }
1536
1537 try 1619 try
1538 { 1620 {
1539 return OpenJPEG.EncodeFromImage(overlay, true); 1621 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1555,4 +1637,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1555 public uint itemtype; 1637 public uint itemtype;
1556 public ulong regionhandle; 1638 public ulong regionhandle;
1557 } 1639 }
1640
1641 public struct MapBlockRequestData
1642 {
1643 public IClientAPI client;
1644 public int minX;
1645 public int minY;
1646 public int maxX;
1647 public int maxY;
1648 public uint flags;
1649 }
1558} 1650}