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.cs185
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs150
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs463
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs208
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs211
-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.cs56
-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.cs32
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs44
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs433
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs190
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs94
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs421
-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.cs6
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs15
-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.cs79
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs433
-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.cs115
-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.cs577
54 files changed, 3316 insertions, 1722 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 3cba9b4..08e7cb7 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 { 276 {
281 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
282 }
283
284#else
285 if (m_CurrentlyWriting.Contains(filename))
286 {
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>
@@ -345,8 +369,7 @@ namespace OpenSim.Region.CoreModules.Asset
345 AssetBase asset = null; 369 AssetBase asset = null;
346 370
347 string filename = GetFileName(id); 371 string filename = GetFileName(id);
348 372 while (File.Exists(filename))
349 if (File.Exists(filename))
350 { 373 {
351 FileStream stream = null; 374 FileStream stream = null;
352 try 375 try
@@ -357,6 +380,8 @@ namespace OpenSim.Region.CoreModules.Asset
357 asset = (AssetBase)bformatter.Deserialize(stream); 380 asset = (AssetBase)bformatter.Deserialize(stream);
358 381
359 m_DiskHits++; 382 m_DiskHits++;
383
384 break;
360 } 385 }
361 catch (System.Runtime.Serialization.SerializationException e) 386 catch (System.Runtime.Serialization.SerializationException e)
362 { 387 {
@@ -369,12 +394,24 @@ namespace OpenSim.Region.CoreModules.Asset
369 // {different version of AssetBase} -- we should attempt to 394 // {different version of AssetBase} -- we should attempt to
370 // delete it and re-cache 395 // delete it and re-cache
371 File.Delete(filename); 396 File.Delete(filename);
397
398 break;
399 }
400 catch (IOException e)
401 {
402 // This is a sharing violation: File exists but can't be opened because it's
403 // being written
404 Thread.Sleep(100);
405
406 continue;
372 } 407 }
373 catch (Exception e) 408 catch (Exception e)
374 { 409 {
375 m_log.WarnFormat( 410 m_log.WarnFormat(
376 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", 411 "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
377 filename, id, e.Message, e.StackTrace); 412 filename, id, e.Message, e.StackTrace);
413
414 break;
378 } 415 }
379 finally 416 finally
380 { 417 {
@@ -408,6 +445,50 @@ namespace OpenSim.Region.CoreModules.Asset
408 return asset; 445 return asset;
409 } 446 }
410 447
448 private bool CheckFromFileCache(string id)
449 {
450 bool found = false;
451
452 string filename = GetFileName(id);
453 if (File.Exists(filename))
454 {
455 // actually check if we can open it, and so update expire
456 FileStream stream = null;
457 try
458 {
459 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
460 if (stream != null)
461 {
462 found = true;
463 stream.Close();
464 }
465
466 }
467 catch (System.Runtime.Serialization.SerializationException e)
468 {
469 found = false;
470 m_log.ErrorFormat(
471 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
472 filename, id, e.Message, e.StackTrace);
473
474 // If there was a problem deserializing the asset, the asset may
475 // either be corrupted OR was serialized under an old format
476 // {different version of AssetBase} -- we should attempt to
477 // delete it and re-cache
478 File.Delete(filename);
479 }
480 catch (Exception e)
481 {
482 found = false;
483 m_log.ErrorFormat(
484 "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
485 filename, id, e.Message, e.StackTrace);
486 }
487 }
488
489 return found;
490 }
491
411 public AssetBase Get(string id) 492 public AssetBase Get(string id)
412 { 493 {
413 m_Requests++; 494 m_Requests++;
@@ -444,11 +525,26 @@ namespace OpenSim.Region.CoreModules.Asset
444 return asset; 525 return asset;
445 } 526 }
446 527
528 public bool Check(string id)
529 {
530 if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
531 return true;
532
533 if (m_FileCacheEnabled && CheckFromFileCache(id))
534 return true;
535 return false;
536 }
537
447 public AssetBase GetCached(string id) 538 public AssetBase GetCached(string id)
448 { 539 {
449 return Get(id); 540 return Get(id);
450 } 541 }
451 542
543 public AssetBase CheckCached(string id)
544 {
545 return Get(id);
546 }
547
452 public void Expire(string id) 548 public void Expire(string id)
453 { 549 {
454 if (m_LogLevel >= 2) 550 if (m_LogLevel >= 2)
@@ -964,6 +1060,11 @@ namespace OpenSim.Region.CoreModules.Asset
964 return asset.Data; 1060 return asset.Data;
965 } 1061 }
966 1062
1063 public bool CheckData(string id)
1064 {
1065 return Check(id); ;
1066 }
1067
967 public bool Get(string id, object sender, AssetRetrieved handler) 1068 public bool Get(string id, object sender, AssetRetrieved handler)
968 { 1069 {
969 AssetBase asset = Get(id); 1070 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 ad17aa9..f62512e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Services.Interfaces;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.Attachments 45namespace OpenSim.Region.CoreModules.Avatar.Attachments
45{ 46{
@@ -75,40 +76,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
75 m_scene.RegisterModuleInterface<IAttachmentsModule>(this); 76 m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
76 77
77 if (Enabled) 78 if (Enabled)
78 {
79 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 79 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
80 m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true);
81 m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false);
82 }
83 80
84 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 81 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
85 } 82 }
86
87 /// <summary>
88 /// Listen for client triggered running state changes so that we can persist the script's object if necessary.
89 /// </summary>
90 /// <param name='localID'></param>
91 /// <param name='itemID'></param>
92 private void HandleScriptStateChange(uint localID, bool started)
93 {
94 SceneObjectGroup sog = m_scene.GetGroupByPrim(localID);
95 if (sog != null && sog.IsAttachment)
96 {
97 if (!started)
98 {
99 // FIXME: This is a convoluted way for working out whether the script state has changed to stop
100 // because it has been manually stopped or because the stop was called in UpdateDetachedObject() below
101 // This needs to be handled in a less tangled way.
102 ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar);
103 if (sp.ControllingClient.IsActive)
104 sog.HasGroupChanged = true;
105 }
106 else
107 {
108 sog.HasGroupChanged = true;
109 }
110 }
111 }
112 83
113 public void RemoveRegion(Scene scene) 84 public void RemoveRegion(Scene scene)
114 { 85 {
@@ -199,6 +170,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
199 170
200// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); 171// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name);
201 172
173 XmlDocument doc = new XmlDocument();
174 string stateData = String.Empty;
175
176 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
177 if (attServ != null)
178 {
179 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
180 stateData = attServ.Get(sp.UUID.ToString());
181 if (stateData != String.Empty)
182 {
183 try
184 {
185 doc.LoadXml(stateData);
186 }
187 catch { }
188 }
189 }
190
191 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
192
193 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
194 if (nodes.Count > 0)
195 {
196 foreach (XmlNode n in nodes)
197 {
198 XmlElement elem = (XmlElement)n;
199 string itemID = elem.GetAttribute("ItemID");
200 string xml = elem.InnerXml;
201
202 itemData[new UUID(itemID)] = xml;
203 }
204 }
205
206
202 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 207 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
203 foreach (AvatarAttachment attach in attachments) 208 foreach (AvatarAttachment attach in attachments)
204 { 209 {
@@ -218,12 +223,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
218 223
219 try 224 try
220 { 225 {
226 string xmlData;
227 XmlDocument d = null;
228 UUID asset;
229 if (itemData.TryGetValue(attach.ItemID, out xmlData))
230 {
231 d = new XmlDocument();
232 d.LoadXml(xmlData);
233 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID);
234 }
235
221 // If we're an NPC then skip all the item checks and manipulations since we don't have an 236 // If we're an NPC then skip all the item checks and manipulations since we don't have an
222 // inventory right now. 237 // inventory right now.
223 if (sp.PresenceType == PresenceType.Npc) 238 if (sp.PresenceType == PresenceType.Npc)
224 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true); 239 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true);
225 else 240 else
226 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80); 241 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d);
227 } 242 }
228 catch (Exception e) 243 catch (Exception e)
229 { 244 {
@@ -284,12 +299,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
284 sp.ClearAttachments(); 299 sp.ClearAttachments();
285 } 300 }
286 301
287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append) 302 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool append)
288 { 303 {
289 if (!Enabled) 304 if (!Enabled)
290 return false; 305 return false;
291 306
292 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, true, append); 307 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp, false, append);
293 } 308 }
294 309
295 /// <summary> 310 /// <summary>
@@ -302,9 +317,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
302 /// <param name='silent'></param> 317 /// <param name='silent'></param>
303 /// <param name='temp'></param> 318 /// <param name='temp'></param>
304 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> 319 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
305 private bool AttachObjectInternal( 320 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp, bool resumeScripts, bool append)
306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts, bool append)
307 { 321 {
322// m_log.DebugFormat(
323// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
324// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
325
326 if (sp.GetAttachments().Contains(group))
327 {
328// m_log.WarnFormat(
329// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
330// group.Name, group.LocalId, sp.Name, AttachmentPt);
331
332 return false;
333 }
334
308 if (group.GetSittingAvatarsCount() != 0) 335 if (group.GetSittingAvatarsCount() != 0)
309 { 336 {
310// m_log.WarnFormat( 337// m_log.WarnFormat(
@@ -315,6 +342,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
315 } 342 }
316 343
317 Vector3 attachPos = group.AbsolutePosition; 344 Vector3 attachPos = group.AbsolutePosition;
345
346 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
347 // be removed when that functionality is implemented in opensim
348 attachmentPt &= 0x7f;
349
318 // If the attachment point isn't the same as the one previously used 350 // If the attachment point isn't the same as the one previously used
319 // set it's offset position = 0 so that it appears on the attachment point 351 // set it's offset position = 0 so that it appears on the attachment point
320 // and not in a weird location somewhere unknown. 352 // and not in a weird location somewhere unknown.
@@ -323,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
323 attachPos = Vector3.Zero; 355 attachPos = Vector3.Zero;
324 } 356 }
325 357
326 // AttachmentPt 0 means the client chose to 'wear' the attachment. 358 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment.
327 if (attachmentPt == (uint)AttachmentPoint.Default) 359 if (attachmentPt == (uint)AttachmentPoint.Default)
328 { 360 {
329 // Check object for stored attachment point 361 // Check object for stored attachment point
@@ -338,20 +370,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
338 attachPos = Vector3.Zero; 370 attachPos = Vector3.Zero;
339 } 371 }
340 372
341 group.AttachmentPoint = attachmentPt;
342 group.AbsolutePosition = attachPos;
343
344 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 373 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
345 374
346 if (attachments.Contains(group))
347 {
348// m_log.WarnFormat(
349// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
350// group.Name, group.LocalId, sp.Name, AttachmentPt);
351
352 return false;
353 }
354
355 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones 375 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
356 while (attachments.Count >= 5) 376 while (attachments.Count >= 5)
357 { 377 {
@@ -372,6 +392,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
372 392
373 lock (sp.AttachmentsSyncLock) 393 lock (sp.AttachmentsSyncLock)
374 { 394 {
395 group.AttachmentPoint = attachmentPt;
396 group.AbsolutePosition = attachPos;
397
375 if (sp.PresenceType != PresenceType.Npc) 398 if (sp.PresenceType != PresenceType.Npc)
376 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); 399 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
377 400
@@ -394,8 +417,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
394 417
395 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append) 418 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
396 { 419 {
397 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
398
399 // Add the new attachment to inventory if we don't already have it. 420 // Add the new attachment to inventory if we don't already have it.
400 if (!temp) 421 if (!temp)
401 { 422 {
@@ -407,7 +428,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
407 } 428 }
408 } 429 }
409 430
410 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 431 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
432 {
433 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
434 }
435
436 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
411 { 437 {
412 if (!Enabled) 438 if (!Enabled)
413 return null; 439 return null;
@@ -445,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
445 return null; 471 return null;
446 } 472 }
447 473
448 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); 474 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append);
449 } 475 }
450 476
451 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 477 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -517,7 +543,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
517 so.AttachedAvatar = UUID.Zero; 543 so.AttachedAvatar = UUID.Zero;
518 rootPart.SetParentLocalId(0); 544 rootPart.SetParentLocalId(0);
519 so.ClearPartAttachmentData(); 545 so.ClearPartAttachmentData();
520 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 546 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
521 so.HasGroupChanged = true; 547 so.HasGroupChanged = true;
522 rootPart.Rezzed = DateTime.Now; 548 rootPart.Rezzed = DateTime.Now;
523 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 549 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -846,7 +872,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
846 } 872 }
847 873
848 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 874 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
849 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) 875 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append)
850 { 876 {
851 if (m_invAccessModule == null) 877 if (m_invAccessModule == null)
852 return null; 878 return null;
@@ -871,10 +897,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
871 return null; 897 return null;
872 } 898 }
873 899
874// m_log.DebugFormat(
875// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
876// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
877
878 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 900 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
879 objatt.HasGroupChanged = false; 901 objatt.HasGroupChanged = false;
880 bool tainted = false; 902 bool tainted = false;
@@ -889,7 +911,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
889 // This will throw if the attachment fails 911 // This will throw if the attachment fails
890 try 912 try
891 { 913 {
892 AttachObjectInternal(sp, objatt, attachmentPt, false, false, true, append); 914 if (doc != null)
915 {
916 objatt.LoadScriptState(doc);
917 objatt.ResetOwnerChangeFlag();
918 }
919
920 AttachObjectInternal(sp, objatt, attachmentPt, false, true, false, true, append);
893 } 921 }
894 catch (Exception e) 922 catch (Exception e)
895 { 923 {
@@ -1028,7 +1056,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1028 AttachmentPt &= 0x7f; 1056 AttachmentPt &= 0x7f;
1029 1057
1030 // Calls attach with a Zero position 1058 // Calls attach with a Zero position
1031 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append)) 1059 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false, append))
1032 { 1060 {
1033// m_log.Debug( 1061// m_log.Debug(
1034// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 1062// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index c8c594d..a8fe045 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -197,7 +197,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
198 198
199 m_numberOfAttachEventsFired = 0; 199 m_numberOfAttachEventsFired = 0;
200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); 200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false);
201 201
202 // Check status on scene presence 202 // Check status on scene presence
203 Assert.That(sp.HasAttachments(), Is.True); 203 Assert.That(sp.HasAttachments(), Is.True);
@@ -244,7 +244,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
244 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); 244 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
245 245
246 m_numberOfAttachEventsFired = 0; 246 m_numberOfAttachEventsFired = 0;
247 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false); 247 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false, false, false);
248 248
249 // Check status on scene presence 249 // Check status on scene presence
250 Assert.That(sp.HasAttachments(), Is.True); 250 Assert.That(sp.HasAttachments(), Is.True);
@@ -277,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
277 277
278 // Test wearing a different attachment from the ground. 278 // Test wearing a different attachment from the ground.
279 { 279 {
280 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); 280 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false);
281 281
282 // Check status on scene presence 282 // Check status on scene presence
283 Assert.That(sp.HasAttachments(), Is.True); 283 Assert.That(sp.HasAttachments(), Is.True);
@@ -310,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
310 310
311 // Test rewearing an already worn attachment from ground. Nothing should happen. 311 // Test rewearing an already worn attachment from ground. Nothing should happen.
312 { 312 {
313 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false); 313 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false, false, false);
314 314
315 // Check status on scene presence 315 // Check status on scene presence
316 Assert.That(sp.HasAttachments(), Is.True); 316 Assert.That(sp.HasAttachments(), Is.True);
@@ -368,7 +368,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
368 sp2.AbsolutePosition = new Vector3(0, 0, 0); 368 sp2.AbsolutePosition = new Vector3(0, 0, 0);
369 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 369 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
370 370
371 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); 371 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false, false);
372 372
373 Assert.That(sp.HasAttachments(), Is.False); 373 Assert.That(sp.HasAttachments(), Is.False);
374 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 374 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -663,7 +663,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
663 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 663 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
664 664
665 SceneObjectGroup rezzedSo 665 SceneObjectGroup rezzedSo
666 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 666 = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
667 667
668 // Wait for chat to signal rezzed script has been started. 668 // Wait for chat to signal rezzed script has been started.
669 m_chatEvent.WaitOne(60000); 669 m_chatEvent.WaitOne(60000);
@@ -682,7 +682,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
682 Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); 682 Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
683 683
684 // Re-rez the attachment to check script running state 684 // Re-rez the attachment to check script running state
685 SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 685 SceneObjectGroup reRezzedSo = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
686 686
687 // Wait for chat to signal rezzed script has been started. 687 // Wait for chat to signal rezzed script has been started.
688 m_chatEvent.WaitOne(60000); 688 m_chatEvent.WaitOne(60000);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index c7ac7c4..bc79944 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -141,9 +141,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
141 /// <param name="sp"></param> 141 /// <param name="sp"></param>
142 /// <param name="texture"></param> 142 /// <param name="texture"></param>
143 /// <param name="visualParam"></param> 143 /// <param name="visualParam"></param>
144 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) 144 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
145 { 145 {
146 SetAppearance(sp, appearance.Texture, appearance.VisualParams); 146 SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
147 }
148
149
150 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
151 {
152 float oldoff = sp.Appearance.AvatarFeetOffset;
153 Vector3 oldbox = sp.Appearance.AvatarBoxSize;
154
155 SetAppearance(sp, textureEntry, visualParams, cacheItems);
156 sp.Appearance.SetSize(avSize);
157
158 float off = sp.Appearance.AvatarFeetOffset;
159 Vector3 box = sp.Appearance.AvatarBoxSize;
160 if (oldoff != off || oldbox != box)
161 ((ScenePresence)sp).SetSize(box, off);
147 } 162 }
148 163
149 /// <summary> 164 /// <summary>
@@ -152,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
152 /// <param name="sp"></param> 167 /// <param name="sp"></param>
153 /// <param name="texture"></param> 168 /// <param name="texture"></param>
154 /// <param name="visualParam"></param> 169 /// <param name="visualParam"></param>
155 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) 170 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
156 { 171 {
157// m_log.DebugFormat( 172// m_log.DebugFormat(
158// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 173// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
@@ -175,18 +190,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
175 // m_log.DebugFormat( 190 // m_log.DebugFormat(
176 // "[AVFACTORY]: Setting visual params for {0} to {1}", 191 // "[AVFACTORY]: Setting visual params for {0} to {1}",
177 // client.Name, string.Join(", ", visualParamsStrings)); 192 // client.Name, string.Join(", ", visualParamsStrings));
178 193/*
179 float oldHeight = sp.Appearance.AvatarHeight; 194 float oldHeight = sp.Appearance.AvatarHeight;
180 changed = sp.Appearance.SetVisualParams(visualParams); 195 changed = sp.Appearance.SetVisualParams(visualParams);
181 196
182 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) 197 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
183 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); 198 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
184 } 199 */
200// float oldoff = sp.Appearance.AvatarFeetOffset;
201// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
202 changed = sp.Appearance.SetVisualParams(visualParams);
203// float off = sp.Appearance.AvatarFeetOffset;
204// Vector3 box = sp.Appearance.AvatarBoxSize;
205// if(oldoff != off || oldbox != box)
206// ((ScenePresence)sp).SetSize(box,off);
185 207
208 }
209
186 // Process the baked texture array 210 // Process the baked texture array
187 if (textureEntry != null) 211 if (textureEntry != null)
188 { 212 {
189// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 213 m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
190 214
191// WriteBakedTexturesReport(sp, m_log.DebugFormat); 215// WriteBakedTexturesReport(sp, m_log.DebugFormat);
192 216
@@ -255,6 +279,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
255 return GetBakedTextureFaces(sp); 279 return GetBakedTextureFaces(sp);
256 } 280 }
257 281
282 public WearableCacheItem[] GetCachedItems(UUID agentId)
283 {
284 ScenePresence sp = m_scene.GetScenePresence(agentId);
285 WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
286 //foreach (WearableCacheItem item in items)
287 //{
288
289 //}
290 return items;
291 }
292
258 public bool SaveBakedTextures(UUID agentId) 293 public bool SaveBakedTextures(UUID agentId)
259 { 294 {
260 ScenePresence sp = m_scene.GetScenePresence(agentId); 295 ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -341,6 +376,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
341 public bool ValidateBakedTextureCache(IScenePresence sp) 376 public bool ValidateBakedTextureCache(IScenePresence sp)
342 { 377 {
343 bool defonly = true; // are we only using default textures 378 bool defonly = true; // are we only using default textures
379 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
380 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
381 WearableCacheItem[] wearableCache = null;
382
383 // Cache wearable data for teleport.
384 // Only makes sense if there's a bake module and a cache module
385 if (bakedModule != null && cache != null)
386 {
387 try
388 {
389 wearableCache = bakedModule.Get(sp.UUID);
390 }
391 catch (Exception)
392 {
393
394 }
395 if (wearableCache != null)
396 {
397 for (int i = 0; i < wearableCache.Length; i++)
398 {
399 cache.Cache(wearableCache[i].TextureAsset);
400 }
401 }
402 }
403 /*
404 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
405 if (invService.GetRootFolder(userID) != null)
406 {
407 WearableCacheItem[] wearableCache = null;
408 if (bakedModule != null)
409 {
410 try
411 {
412 wearableCache = bakedModule.Get(userID);
413 appearance.WearableCacheItems = wearableCache;
414 appearance.WearableCacheItemsDirty = false;
415 foreach (WearableCacheItem item in wearableCache)
416 {
417 appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID;
418 }
419 }
420 catch (Exception)
421 {
422
423 }
424 }
425 */
344 426
345 // Process the texture entry 427 // Process the texture entry
346 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 428 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@@ -348,9 +430,32 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
348 int idx = AvatarAppearance.BAKE_INDICES[i]; 430 int idx = AvatarAppearance.BAKE_INDICES[i];
349 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 431 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
350 432
351 // if there is no texture entry, skip it 433 // No face, so lets check our baked service cache, teleport or login.
352 if (face == null) 434 if (face == null)
353 continue; 435 {
436 if (wearableCache != null)
437 {
438 // If we find the an appearance item, set it as the textureentry and the face
439 WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache);
440 if (searchitem != null)
441 {
442 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx);
443 sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID;
444 face = sp.Appearance.Texture.FaceTextures[idx];
445 }
446 else
447 {
448 // if there is no texture entry and no baked cache, skip it
449 continue;
450 }
451 }
452 else
453 {
454 //No texture entry face and no cache. Skip this face.
455 continue;
456 }
457 }
458
354 459
355// m_log.DebugFormat( 460// m_log.DebugFormat(
356// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 461// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
@@ -365,8 +470,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
365 470
366 defonly = false; // found a non-default texture reference 471 defonly = false; // found a non-default texture reference
367 472
368 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 473 if (cache != null)
369 return false; 474 {
475 if (!cache.Check(face.TextureID.ToString()))
476 return false;
477 }
478 else
479 {
480 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
481 return false;
482 }
370 } 483 }
371 484
372// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 485// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
@@ -378,6 +491,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
378 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) 491 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
379 { 492 {
380 int texturesRebaked = 0; 493 int texturesRebaked = 0;
494 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
381 495
382 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 496 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
383 { 497 {
@@ -401,21 +515,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
401 515
402 if (missingTexturesOnly) 516 if (missingTexturesOnly)
403 { 517 {
404 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 518 if (cache != null)
405 { 519 {
406 continue; 520 if (cache.Check(face.TextureID.ToString()))
521 continue;
522 else
523 {
524 m_log.DebugFormat(
525 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
526 face.TextureID, idx, sp.Name);
527 }
407 } 528 }
408 else 529 else
409 { 530 {
410 // On inter-simulator teleports, this occurs if baked textures are not being stored by the 531 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
411 // grid asset service (which means that they are not available to the new region and so have 532 {
412 // to be re-requested from the client). 533 continue;
413 // 534 }
414 // The only available core OpenSimulator behaviour right now 535
415 // is not to store these textures, temporarily or otherwise. 536 else
416 m_log.DebugFormat( 537 {
417 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 538 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
418 face.TextureID, idx, sp.Name); 539 // grid asset service (which means that they are not available to the new region and so have
540 // to be re-requested from the client).
541 //
542 // The only available core OpenSimulator behaviour right now
543 // is not to store these textures, temporarily or otherwise.
544 m_log.DebugFormat(
545 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
546 face.TextureID, idx, sp.Name);
547 }
419 } 548 }
420 } 549 }
421 else 550 else
@@ -557,26 +686,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
557 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 686 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
558 { 687 {
559 IInventoryService invService = m_scene.InventoryService; 688 IInventoryService invService = m_scene.InventoryService;
560 689 bool resetwearable = false;
561 if (invService.GetRootFolder(userID) != null) 690 if (invService.GetRootFolder(userID) != null)
562 { 691 {
563 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
564 { 693 {
565 for (int j = 0; j < appearance.Wearables[i].Count; j++) 694 for (int j = 0; j < appearance.Wearables[i].Count; j++)
566 { 695 {
696 // Check if the default wearables are not set
567 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 697 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
698 {
699 switch ((WearableType) i)
700 {
701 case WearableType.Eyes:
702 case WearableType.Hair:
703 case WearableType.Shape:
704 case WearableType.Skin:
705 //case WearableType.Underpants:
706 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
707 resetwearable = true;
708 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
709 resetwearable = true;
710 break;
711
712 }
568 continue; 713 continue;
714 }
569 715
570 // Ignore ruth's assets 716 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
571 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 717 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
718 {
719 switch ((WearableType)i)
720 {
721 case WearableType.Eyes:
722 case WearableType.Hair:
723 case WearableType.Shape:
724 case WearableType.Skin:
725 //case WearableType.Underpants:
726 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
727
728 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
729 resetwearable = true;
730 break;
731
732 }
572 continue; 733 continue;
573 734 }
735
574 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 736 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
575 baseItem = invService.GetItem(baseItem); 737 baseItem = invService.GetItem(baseItem);
576 738
577 if (baseItem != null) 739 if (baseItem != null)
578 { 740 {
579 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 741 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
742 int unmodifiedWearableIndexForClosure = i;
743 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
744 delegate(string x, object y, AssetBase z)
745 {
746 if (z == null)
747 {
748 TryAndRepairBrokenWearable(
749 (WearableType)unmodifiedWearableIndexForClosure, invService,
750 userID, appearance);
751 }
752 });
580 } 753 }
581 else 754 else
582 { 755 {
@@ -584,17 +757,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
584 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 757 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
585 appearance.Wearables[i][j].ItemID, (WearableType)i); 758 appearance.Wearables[i][j].ItemID, (WearableType)i);
586 759
587 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 760 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
761 resetwearable = true;
762
588 } 763 }
589 } 764 }
590 } 765 }
766
767 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
768 if (appearance.Wearables[(int) WearableType.Eyes] == null)
769 {
770 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
771
772 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
773 resetwearable = true;
774 }
775 else
776 {
777 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
778 {
779 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
780 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
781 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
782 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
783 resetwearable = true;
784
785 }
786
787 }
788 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
789 if (appearance.Wearables[(int)WearableType.Shape] == null)
790 {
791 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
792
793 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
794 resetwearable = true;
795 }
796 else
797 {
798 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
799 {
800 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
801 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
802 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
803 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
804 resetwearable = true;
805
806 }
807
808 }
809 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
810 if (appearance.Wearables[(int)WearableType.Hair] == null)
811 {
812 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
813
814 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
815 resetwearable = true;
816 }
817 else
818 {
819 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
820 {
821 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
822 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
823 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
824 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
825 resetwearable = true;
826
827 }
828
829 }
830 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
831 if (appearance.Wearables[(int)WearableType.Skin] == null)
832 {
833 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
834
835 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
836 resetwearable = true;
837 }
838 else
839 {
840 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
841 {
842 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
843 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
844 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
845 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
846 resetwearable = true;
847
848 }
849
850 }
851 if (resetwearable)
852 {
853 ScenePresence presence = null;
854 if (m_scene.TryGetScenePresence(userID, out presence))
855 {
856 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
857 presence.Appearance.Serial++);
858 }
859 }
860
591 } 861 }
592 else 862 else
593 { 863 {
594 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 864 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
595 } 865 }
596 } 866 }
867 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
868 {
869 UUID defaultwearable = GetDefaultItem(type);
870 if (defaultwearable != UUID.Zero)
871 {
872 UUID newInvItem = UUID.Random();
873 InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
874 {
875 AssetID =
876 defaultwearable,
877 AssetType
878 =
879 (int)
880 AssetType
881 .Bodypart,
882 CreatorId
883 =
884 userID
885 .ToString
886 (),
887 //InvType = (int)InventoryType.Wearable,
888
889 Description
890 =
891 "Failed Wearable Replacement",
892 Folder =
893 invService
894 .GetFolderForType
895 (userID,
896 AssetType
897 .Bodypart)
898 .ID,
899 Flags = (uint) type,
900 Name = Enum.GetName(typeof (WearableType), type),
901 BasePermissions = (uint) PermissionMask.Copy,
902 CurrentPermissions = (uint) PermissionMask.Copy,
903 EveryOnePermissions = (uint) PermissionMask.Copy,
904 GroupPermissions = (uint) PermissionMask.Copy,
905 NextPermissions = (uint) PermissionMask.Copy
906 };
907 invService.AddItem(itembase);
908 UUID LinkInvItem = UUID.Random();
909 itembase = new InventoryItemBase(LinkInvItem, userID)
910 {
911 AssetID =
912 newInvItem,
913 AssetType
914 =
915 (int)
916 AssetType
917 .Link,
918 CreatorId
919 =
920 userID
921 .ToString
922 (),
923 InvType = (int) InventoryType.Wearable,
924
925 Description
926 =
927 "Failed Wearable Replacement",
928 Folder =
929 invService
930 .GetFolderForType
931 (userID,
932 AssetType
933 .CurrentOutfitFolder)
934 .ID,
935 Flags = (uint) type,
936 Name = Enum.GetName(typeof (WearableType), type),
937 BasePermissions = (uint) PermissionMask.Copy,
938 CurrentPermissions = (uint) PermissionMask.Copy,
939 EveryOnePermissions = (uint) PermissionMask.Copy,
940 GroupPermissions = (uint) PermissionMask.Copy,
941 NextPermissions = (uint) PermissionMask.Copy
942 };
943 invService.AddItem(itembase);
944 appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
945 ScenePresence presence = null;
946 if (m_scene.TryGetScenePresence(userID, out presence))
947 {
948 m_scene.SendInventoryUpdate(presence.ControllingClient,
949 invService.GetFolderForType(userID,
950 AssetType
951 .CurrentOutfitFolder),
952 false, true);
953 }
954 }
955 }
956 private UUID GetDefaultItem(WearableType wearable)
957 {
958 // These are ruth
959 UUID ret = UUID.Zero;
960 switch (wearable)
961 {
962 case WearableType.Eyes:
963 ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
964 break;
965 case WearableType.Hair:
966 ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
967 break;
968 case WearableType.Pants:
969 ret = new UUID("00000000-38f9-1111-024e-222222111120");
970 break;
971 case WearableType.Shape:
972 ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
973 break;
974 case WearableType.Shirt:
975 ret = new UUID("00000000-38f9-1111-024e-222222111110");
976 break;
977 case WearableType.Skin:
978 ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
979 break;
980 case WearableType.Undershirt:
981 ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
982 break;
983 case WearableType.Underpants:
984 ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
985 break;
986 }
597 987
988 return ret;
989 }
598 #endregion 990 #endregion
599 991
600 #region Client Event Handlers 992 #region Client Event Handlers
@@ -604,12 +996,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
604 /// <param name="client"></param> 996 /// <param name="client"></param>
605 private void Client_OnRequestWearables(IClientAPI client) 997 private void Client_OnRequestWearables(IClientAPI client)
606 { 998 {
607 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 999 Util.FireAndForget(delegate(object x)
608 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1000 {
609 if (sp != null) 1001 Thread.Sleep(4000);
610 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1002
611 else 1003 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
612 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1004 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
1005 if (sp != null)
1006 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1007 else
1008 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1009 });
613 } 1010 }
614 1011
615 /// <summary> 1012 /// <summary>
@@ -618,12 +1015,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
618 /// <param name="client"></param> 1015 /// <param name="client"></param>
619 /// <param name="texture"></param> 1016 /// <param name="texture"></param>
620 /// <param name="visualParam"></param> 1017 /// <param name="visualParam"></param>
621 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 1018 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
622 { 1019 {
623 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 1020 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
624 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1021 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
625 if (sp != null) 1022 if (sp != null)
626 SetAppearance(sp, textureEntry, visualParams); 1023 SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
627 else 1024 else
628 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 1025 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
629 } 1026 }
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 58f747b..174642d 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>
@@ -326,21 +372,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
326 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, 372 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
327 string message, ChatSourceType src, bool ignoreDistance) 373 string message, ChatSourceType src, bool ignoreDistance)
328 { 374 {
375 // don't send chat to child agents
376 if (presence.IsChildAgent) return false;
377
329 Vector3 fromRegionPos = fromPos + regionPos; 378 Vector3 fromRegionPos = fromPos + regionPos;
330 Vector3 toRegionPos = presence.AbsolutePosition + 379 Vector3 toRegionPos = presence.AbsolutePosition +
331 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, 380 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize,
332 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 381 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
333 382
334 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 383 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
335 384
336 if (!ignoreDistance) 385 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
386 type == ChatTypeEnum.Say && dis > m_saydistance ||
387 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
337 { 388 {
338 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 389 return false;
339 type == ChatTypeEnum.Say && dis > m_saydistance ||
340 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
341 {
342 return false;
343 }
344 } 390 }
345 391
346 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 392 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
@@ -350,5 +396,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
350 396
351 return true; 397 return true;
352 } 398 }
399
400 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
401 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
402 {
403 System.Threading.Timer Timer;
404 if (flags == 0)
405 {
406 FreezeCache.Add(target.ToString());
407 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
408 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
409 Timers.Add(target, Timer);
410 }
411 else
412 {
413 FreezeCache.Remove(target.ToString());
414 Timers.TryGetValue(target, out Timer);
415 Timers.Remove(target);
416 Timer.Dispose();
417 }
418 }
419
420 private void OnEndParcelFrozen(object avatar)
421 {
422 UUID target = (UUID)avatar;
423 FreezeCache.Remove(target.ToString());
424 System.Threading.Timer Timer;
425 Timers.TryGetValue(target, out Timer);
426 Timers.Remove(target);
427 Timer.Dispose();
428 }
353 } 429 }
354} \ No newline at end of file 430}
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 5a7446f..9fa9be1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -32,6 +32,24 @@ using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using System;
36using System.Reflection;
37using System.Collections;
38using System.Collections.Specialized;
39using System.Reflection;
40using System.IO;
41using System.Web;
42using System.Xml;
43using log4net;
44using Mono.Addins;
45using OpenMetaverse.Messages.Linden;
46using OpenMetaverse.StructuredData;
47using OpenSim.Framework.Capabilities;
48using OpenSim.Framework.Servers;
49using OpenSim.Framework.Servers.HttpServer;
50using Caps = OpenSim.Framework.Capabilities.Caps;
51using OSDArray = OpenMetaverse.StructuredData.OSDArray;
52using OSDMap = OpenMetaverse.StructuredData.OSDMap;
35 53
36using Mono.Addins; 54using Mono.Addins;
37 55
@@ -40,11 +58,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")] 58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
41 public class GodsModule : INonSharedRegionModule, IGodsModule 59 public class GodsModule : INonSharedRegionModule, IGodsModule
42 { 60 {
61 private static readonly ILog m_log =
62 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
63
43 /// <summary>Special UUID for actions that apply to all agents</summary> 64 /// <summary>Special UUID for actions that apply to all agents</summary>
44 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); 65 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
45 66
46 protected Scene m_scene; 67 protected Scene m_scene;
47 protected IDialogModule m_dialogModule; 68 protected IDialogModule m_dialogModule;
69
70 protected Dictionary<UUID, string> m_capsDict =
71 new Dictionary<UUID, string>();
72
48 protected IDialogModule DialogModule 73 protected IDialogModule DialogModule
49 { 74 {
50 get 75 get
@@ -65,6 +90,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
65 m_scene = scene; 90 m_scene = scene;
66 m_scene.RegisterModuleInterface<IGodsModule>(this); 91 m_scene.RegisterModuleInterface<IGodsModule>(this);
67 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 92 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
93 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
94 m_scene.EventManager.OnClientClosed += OnClientClosed;
95 scene.EventManager.OnIncomingInstantMessage +=
96 OnIncomingInstantMessage;
68 } 97 }
69 98
70 public void RemoveRegion(Scene scene) 99 public void RemoveRegion(Scene scene)
@@ -98,6 +127,54 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
98 client.OnRequestGodlikePowers -= RequestGodlikePowers; 127 client.OnRequestGodlikePowers -= RequestGodlikePowers;
99 } 128 }
100 129
130 private void OnClientClosed(UUID agentID, Scene scene)
131 {
132 m_capsDict.Remove(agentID);
133 }
134
135 private void OnRegisterCaps(UUID agentID, Caps caps)
136 {
137 string uri = "/CAPS/" + UUID.Random();
138 m_capsDict[agentID] = uri;
139
140 caps.RegisterHandler("UntrustedSimulatorMessage",
141 new RestStreamHandler("POST", uri,
142 HandleUntrustedSimulatorMessage));
143 }
144
145 private string HandleUntrustedSimulatorMessage(string request,
146 string path, string param, IOSHttpRequest httpRequest,
147 IOSHttpResponse httpResponse)
148 {
149 OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
150
151 string message = osd["message"].AsString();
152
153 if (message == "GodKickUser")
154 {
155 OSDMap body = (OSDMap)osd["body"];
156 OSDArray userInfo = (OSDArray)body["UserInfo"];
157 OSDMap userData = (OSDMap)userInfo[0];
158
159 UUID agentID = userData["AgentID"].AsUUID();
160 UUID godID = userData["GodID"].AsUUID();
161 UUID godSessionID = userData["GodSessionID"].AsUUID();
162 uint kickFlags = userData["KickFlags"].AsUInteger();
163 string reason = userData["Reason"].AsString();
164
165 ScenePresence god = m_scene.GetScenePresence(godID);
166 if (god == null || god.ControllingClient.SessionId != godSessionID)
167 return String.Empty;
168
169 KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
170 }
171 else
172 {
173 m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
174 }
175 return String.Empty;
176 }
177
101 public void RequestGodlikePowers( 178 public void RequestGodlikePowers(
102 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) 179 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
103 { 180 {
@@ -146,76 +223,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
146 /// <param name="reason">The message to send to the user after it's been turned into a field</param> 223 /// <param name="reason">The message to send to the user after it's been turned into a field</param>
147 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) 224 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
148 { 225 {
149 UUID kickUserID = ALL_AGENTS; 226 if (!m_scene.Permissions.IsGod(godID))
150 227 return;
228
151 ScenePresence sp = m_scene.GetScenePresence(agentID); 229 ScenePresence sp = m_scene.GetScenePresence(agentID);
152 230
153 if (sp != null || agentID == kickUserID) 231 if (sp == null && agentID != ALL_AGENTS)
154 { 232 {
155 if (m_scene.Permissions.IsGod(godID)) 233 IMessageTransferModule transferModule =
234 m_scene.RequestModuleInterface<IMessageTransferModule>();
235 if (transferModule != null)
156 { 236 {
157 if (kickflags == 0) 237 m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
158 { 238 transferModule.SendInstantMessage(new GridInstantMessage(
159 if (agentID == kickUserID) 239 m_scene, godID, "God", agentID, (byte)250, false,
160 { 240 Utils.BytesToString(reason), UUID.Zero, true,
161 string reasonStr = Utils.BytesToString(reason); 241 new Vector3(), new byte[] {(byte)kickflags}, true),
162 242 delegate(bool success) {} );
163 m_scene.ForEachClient( 243 }
164 delegate(IClientAPI controller) 244 return;
165 { 245 }
166 if (controller.AgentId != godID)
167 controller.Kick(reasonStr);
168 }
169 );
170
171 // This is a bit crude. It seems the client will be null before it actually stops the thread
172 // The thread will kill itself eventually :/
173 // Is there another way to make sure *all* clients get this 'inter region' message?
174 m_scene.ForEachRootClient(
175 delegate(IClientAPI client)
176 {
177 if (client.AgentId != godID)
178 {
179 client.Close();
180 }
181 }
182 );
183 }
184 else
185 {
186 m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
187 246
188 sp.ControllingClient.Kick(Utils.BytesToString(reason)); 247 switch (kickflags)
189 sp.ControllingClient.Close(); 248 {
190 } 249 case 0:
191 } 250 if (sp != null)
192 251 {
193 if (kickflags == 1) 252 KickPresence(sp, Utils.BytesToString(reason));
194 {
195 sp.AllowMovement = false;
196 if (DialogModule != null)
197 {
198 DialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
199 DialogModule.SendAlertToUser(godID, "User Frozen");
200 }
201 }
202
203 if (kickflags == 2)
204 {
205 sp.AllowMovement = true;
206 if (DialogModule != null)
207 {
208 DialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
209 DialogModule.SendAlertToUser(godID, "User Unfrozen");
210 }
211 }
212 } 253 }
213 else 254 else if (agentID == ALL_AGENTS)
214 { 255 {
215 if (DialogModule != null) 256 m_scene.ForEachRootScenePresence(
216 DialogModule.SendAlertToUser(godID, "Kick request denied"); 257 delegate(ScenePresence p)
258 {
259 if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
260 KickPresence(p, Utils.BytesToString(reason));
261 }
262 );
263 }
264 break;
265 case 1:
266 if (sp != null)
267 {
268 sp.AllowMovement = false;
269 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
270 m_dialogModule.SendAlertToUser(godID, "User Frozen");
217 } 271 }
272 break;
273 case 2:
274 if (sp != null)
275 {
276 sp.AllowMovement = true;
277 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
278 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
279 }
280 break;
281 default:
282 break;
283 }
284 }
285
286 private void KickPresence(ScenePresence sp, string reason)
287 {
288 if (sp.IsChildAgent)
289 return;
290 sp.ControllingClient.Kick(reason);
291 sp.MakeChildAgent();
292 sp.ControllingClient.Close();
293 }
294
295 private void OnIncomingInstantMessage(GridInstantMessage msg)
296 {
297 if (msg.dialog == (uint)250) // Nonlocal kick
298 {
299 UUID agentID = new UUID(msg.toAgentID);
300 string reason = msg.message;
301 UUID godID = new UUID(msg.fromAgentID);
302 uint kickMode = (uint)msg.binaryBucket[0];
303
304 KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
218 } 305 }
219 } 306 }
220 } 307 }
221} \ No newline at end of file 308}
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 fa935cd..1627f6c 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"] = msg.RegionID.ToString(); 731 gim["region_id"] = 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 7d763fa..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,25 +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 m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
186
187 foreach (GridInstantMessage im in msglist)
188 { 189 {
189 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) 190 foreach (GridInstantMessage im in msglist)
190 // send it directly or else the item will be given twice
191 client.SendInstantMessage(im);
192 else
193 { 191 {
194 // Send through scene event manager so all modules get a chance 192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
195 // to look at this message before it gets delivered. 193 // send it directly or else the item will be given twice
196 // 194 client.SendInstantMessage(im);
197 // Needed for proper state management for stored group 195 else
198 // invitations 196 {
199 // 197 // Send through scene event manager so all modules get a chance
200 Scene s = FindScene(client.AgentId); 198 // to look at this message before it gets delivered.
201 if (s != null) 199 //
202 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 }
203 } 210 }
204 } 211 }
205 } 212 }
@@ -211,24 +218,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
211 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 218 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
212 im.dialog != (byte)InstantMessageDialog.GroupNotice && 219 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
213 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 220 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
214 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 221 im.dialog != (byte)InstantMessageDialog.InventoryOffered &&
222 im.dialog != (byte)InstantMessageDialog.TaskInventoryOffered)
215 { 223 {
216 return; 224 return;
217 } 225 }
218 226
219 if (!m_ForwardOfflineGroupMessages)
220 {
221 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
222 im.dialog == (byte)InstantMessageDialog.GroupInvitation)
223 return;
224 }
225
226 Scene scene = FindScene(new UUID(im.fromAgentID)); 227 Scene scene = FindScene(new UUID(im.fromAgentID));
227 if (scene == null) 228 if (scene == null)
228 scene = m_SceneList[0]; 229 scene = m_SceneList[0];
229 230
230 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 231 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
231 "POST", m_RestURL+"/SaveMessage/", im); 232 "POST", m_RestURL+"/SaveMessage/?scope=" +
233 scene.RegionInfo.ScopeID.ToString(), im);
232 234
233 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 235 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
234 { 236 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 98285e9..659b178 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -652,4 +652,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
652 m_assetsLoaded = true; 652 m_assetsLoaded = true;
653 } 653 }
654 } 654 }
655} \ No newline at end of file 655}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 849449b..f4f9e2d 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.Message); 541 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message);
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 bcb7f42..ae58dfd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -177,8 +177,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
177 if (im.binaryBucket.Length < 17) // Invalid 177 if (im.binaryBucket.Length < 17) // Invalid
178 return; 178 return;
179 179
180 UUID receipientID = new UUID(im.toAgentID); 180 UUID recipientID = new UUID(im.toAgentID);
181 ScenePresence user = scene.GetScenePresence(receipientID); 181 ScenePresence user = scene.GetScenePresence(recipientID);
182 UUID copyID; 182 UUID copyID;
183 183
184 // First byte is the asset type 184 // First byte is the asset type
@@ -193,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
193 folderID, new UUID(im.toAgentID)); 193 folderID, new UUID(im.toAgentID));
194 194
195 InventoryFolderBase folderCopy 195 InventoryFolderBase folderCopy
196 = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); 196 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
197 197
198 if (folderCopy == null) 198 if (folderCopy == null)
199 { 199 {
@@ -246,6 +246,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
246 im.imSessionID = itemID.Guid; 246 im.imSessionID = itemID.Guid;
247 } 247 }
248 248
249 im.offline = 0;
250
249 // Send the IM to the recipient. The item is already 251 // Send the IM to the recipient. The item is already
250 // in their inventory, so it will not be lost if 252 // in their inventory, so it will not be lost if
251 // they are offline. 253 // they are offline.
@@ -265,8 +267,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
265 }); 267 });
266 } 268 }
267 } 269 }
268 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) 270 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
271 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
269 { 272 {
273 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
274 IInventoryService invService = scene.InventoryService;
275
276 // Special case: folder redirect.
277 // RLV uses this
278 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
279 {
280 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, client.AgentId);
281 folder = invService.GetFolder(folder);
282
283 if (folder != null)
284 {
285 if (im.binaryBucket.Length >= 16)
286 {
287 UUID destFolderID = new UUID(im.binaryBucket, 0);
288 if (destFolderID != UUID.Zero)
289 {
290 InventoryFolderBase destFolder = new InventoryFolderBase(destFolderID, client.AgentId);
291 destFolder = invService.GetFolder(destFolder);
292 if (destFolder != null)
293 {
294 if (folder.ParentID != destFolder.ID)
295 {
296 folder.ParentID = destFolder.ID;
297 invService.MoveFolder(folder);
298 client.SendBulkUpdateInventory(folder);
299 }
300 }
301 }
302 }
303 }
304 }
305
270 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 306 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
271 307
272 if (user != null) // Local 308 if (user != null) // Local
@@ -276,27 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
276 else 312 else
277 { 313 {
278 if (m_TransferModule != null) 314 if (m_TransferModule != null)
279 m_TransferModule.SendInstantMessage(im, delegate(bool success) { 315 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
280
281 // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
282 // and is apparently supposed to fix bulk inventory updates after accepting items. But
283 // instead it appears to cause two copies of an accepted folder for the receiving user in
284 // at least some cases. Folder/item update is already done when the offer is made (see code above)
285
286// // Send BulkUpdateInventory
287// IInventoryService invService = scene.InventoryService;
288// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
289//
290// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
291// folder = invService.GetFolder(folder);
292//
293// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
294//
295// // If the user has left the scene by the time the message comes back then we can't send
296// // them the update.
297// if (fromUser != null)
298// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
299 });
300 } 316 }
301 } 317 }
302 318
@@ -409,6 +425,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
409 previousParentFolderID = folder.ParentID; 425 previousParentFolderID = folder.ParentID;
410 folder.ParentID = trashFolder.ID; 426 folder.ParentID = trashFolder.ID;
411 invService.MoveFolder(folder); 427 invService.MoveFolder(folder);
428 client.SendBulkUpdateInventory(folder);
412 } 429 }
413 } 430 }
414 431
@@ -522,22 +539,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
522 /// 539 ///
523 /// </summary> 540 /// </summary>
524 /// <param name="msg"></param> 541 /// <param name="msg"></param>
525 private void OnGridInstantMessage(GridInstantMessage msg) 542 private void OnGridInstantMessage(GridInstantMessage im)
526 { 543 {
527 // Check if this is ours to handle 544 // Check if this is ours to handle
528 // 545 //
529 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 546 Scene scene = FindClientScene(new UUID(im.toAgentID));
530 547
531 if (scene == null) 548 if (scene == null)
532 return; 549 return;
533 550
534 // Find agent to deliver to 551 // Find agent to deliver to
535 // 552 //
536 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 553 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
554 if (user == null)
555 return;
556
557 // This requires a little bit of processing because we have to make the
558 // new item visible in the recipient's inventory here
559 //
560 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
561 {
562 if (im.binaryBucket.Length < 17) // Invalid
563 return;
564
565 UUID recipientID = new UUID(im.toAgentID);
566
567 // First byte is the asset type
568 AssetType assetType = (AssetType)im.binaryBucket[0];
569
570 if (AssetType.Folder == assetType)
571 {
572 UUID folderID = new UUID(im.binaryBucket, 1);
537 573
538 // Just forward to local handling 574 InventoryFolderBase given =
539 OnInstantMessage(user.ControllingClient, msg); 575 new InventoryFolderBase(folderID, recipientID);
576 InventoryFolderBase folder =
577 scene.InventoryService.GetFolder(given);
540 578
579 if (folder != null)
580 user.ControllingClient.SendBulkUpdateInventory(folder);
581 }
582 else
583 {
584 UUID itemID = new UUID(im.binaryBucket, 1);
585
586 InventoryItemBase given =
587 new InventoryItemBase(itemID, recipientID);
588 InventoryItemBase item =
589 scene.InventoryService.GetItem(given);
590
591 if (item != null)
592 {
593 user.ControllingClient.SendBulkUpdateInventory(item);
594 }
595 }
596 user.ControllingClient.SendInstantMessage(im);
597 }
598 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
599 {
600 if (im.binaryBucket.Length < 1) // Invalid
601 return;
602
603 UUID recipientID = new UUID(im.toAgentID);
604
605 // Bucket is the asset type
606 AssetType assetType = (AssetType)im.binaryBucket[0];
607
608 if (AssetType.Folder == assetType)
609 {
610 UUID folderID = new UUID(im.imSessionID);
611
612 InventoryFolderBase given =
613 new InventoryFolderBase(folderID, recipientID);
614 InventoryFolderBase folder =
615 scene.InventoryService.GetFolder(given);
616
617 if (folder != null)
618 user.ControllingClient.SendBulkUpdateInventory(folder);
619 }
620 else
621 {
622 UUID itemID = new UUID(im.imSessionID);
623
624 InventoryItemBase given =
625 new InventoryItemBase(itemID, recipientID);
626 InventoryItemBase item =
627 scene.InventoryService.GetItem(given);
628
629 if (item != null)
630 {
631 user.ControllingClient.SendBulkUpdateInventory(item);
632 }
633 }
634
635 // Fix up binary bucket since this may be 17 chars long here
636 Byte[] bucket = new Byte[1];
637 bucket[0] = im.binaryBucket[0];
638 im.binaryBucket = bucket;
639
640 user.ControllingClient.SendInstantMessage(im);
641 }
642 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
643 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
644 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
645 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
646 {
647 user.ControllingClient.SendInstantMessage(im);
648 }
541 } 649 }
542 } 650 }
543} 651}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index e4b0cfa..f3adb95 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}", message); 168 m_log.DebugFormat("[LURE]: TP invite with message {0}", message);
169
170 GridInstantMessage m;
171
172 if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
173 {
174 m = new GridInstantMessage(scene, client.AgentId,
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 }
169 188
170 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
171 client.FirstName+" "+client.LastName, targetid,
172 (byte)InstantMessageDialog.RequestTeleport, false,
173 message, dest, false, presence.AbsolutePosition,
174 new Byte[0], true);
175
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 8329af0..2eb9bfb 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework
55 /// <summary> 55 /// <summary>
56 /// Each agent has its own capabilities handler. 56 /// Each agent has its own capabilities handler.
57 /// </summary> 57 /// </summary>
58 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 58 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
59 59
60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); 60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds 61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
@@ -100,16 +100,17 @@ namespace OpenSim.Region.CoreModules.Framework
100 get { return null; } 100 get { return null; }
101 } 101 }
102 102
103 public void CreateCaps(UUID agentId) 103 public void CreateCaps(UUID agentId, uint circuitCode)
104 { 104 {
105 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) 105 int flags = m_scene.GetUserFlags(agentId);
106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
106 return; 107 return;
107 108
108 String capsObjectPath = GetCapsPath(agentId); 109 String capsObjectPath = GetCapsPath(agentId);
109 110
110 if (m_capsObjects.ContainsKey(agentId)) 111 if (m_capsObjects.ContainsKey(circuitCode))
111 { 112 {
112 Caps oldCaps = m_capsObjects[agentId]; 113 Caps oldCaps = m_capsObjects[circuitCode];
113 114
114 m_log.DebugFormat( 115 m_log.DebugFormat(
115 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", 116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
@@ -124,12 +125,12 @@ namespace OpenSim.Region.CoreModules.Framework
124 (MainServer.Instance == null) ? 0: MainServer.Instance.Port, 125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
125 capsObjectPath, agentId, m_scene.RegionInfo.RegionName); 126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
126 127
127 m_capsObjects[agentId] = caps; 128 m_capsObjects[circuitCode] = caps;
128 129
129 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
130 } 131 }
131 132
132 public void RemoveCaps(UUID agentId) 133 public void RemoveCaps(UUID agentId, uint circuitCode)
133 { 134 {
134 if (childrenSeeds.ContainsKey(agentId)) 135 if (childrenSeeds.ContainsKey(agentId))
135 { 136 {
@@ -138,11 +139,11 @@ namespace OpenSim.Region.CoreModules.Framework
138 139
139 lock (m_capsObjects) 140 lock (m_capsObjects)
140 { 141 {
141 if (m_capsObjects.ContainsKey(agentId)) 142 if (m_capsObjects.ContainsKey(circuitCode))
142 { 143 {
143 m_capsObjects[agentId].DeregisterHandlers(); 144 m_capsObjects[circuitCode].DeregisterHandlers();
144 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); 145 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
145 m_capsObjects.Remove(agentId); 146 m_capsObjects.Remove(circuitCode);
146 } 147 }
147 else 148 else
148 { 149 {
@@ -153,19 +154,30 @@ namespace OpenSim.Region.CoreModules.Framework
153 } 154 }
154 } 155 }
155 156
156 public Caps GetCapsForUser(UUID agentId) 157 public Caps GetCapsForUser(uint circuitCode)
157 { 158 {
158 lock (m_capsObjects) 159 lock (m_capsObjects)
159 { 160 {
160 if (m_capsObjects.ContainsKey(agentId)) 161 if (m_capsObjects.ContainsKey(circuitCode))
161 { 162 {
162 return m_capsObjects[agentId]; 163 return m_capsObjects[circuitCode];
163 } 164 }
164 } 165 }
165 166
166 return null; 167 return null;
167 } 168 }
168 169
170 public void ActivateCaps(uint circuitCode)
171 {
172 lock (m_capsObjects)
173 {
174 if (m_capsObjects.ContainsKey(circuitCode))
175 {
176 m_capsObjects[circuitCode].Activate();
177 }
178 }
179 }
180
169 public void SetAgentCapsSeeds(AgentCircuitData agent) 181 public void SetAgentCapsSeeds(AgentCircuitData agent)
170 { 182 {
171 capsPaths[agent.AgentID] = agent.CapsPath; 183 capsPaths[agent.AgentID] = agent.CapsPath;
@@ -236,9 +248,9 @@ namespace OpenSim.Region.CoreModules.Framework
236 StringBuilder caps = new StringBuilder(); 248 StringBuilder caps = new StringBuilder();
237 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 249 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
238 250
239 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects) 251 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
240 { 252 {
241 caps.AppendFormat("** User {0}:\n", kvp.Key); 253 caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
242 254
243 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); ) 255 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
244 { 256 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 4cf7645..974fd57 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -242,7 +242,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
242 242
243 protected virtual void OnNewClient(IClientAPI client) 243 protected virtual void OnNewClient(IClientAPI client)
244 { 244 {
245 client.OnTeleportHomeRequest += TeleportHome; 245 client.OnTeleportHomeRequest += TriggerTeleportHome;
246 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 246 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
247 247
248 if (!DisableInterRegionTeleportCancellation) 248 if (!DisableInterRegionTeleportCancellation)
@@ -364,7 +364,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
364 /// <param name="sp"></param> 364 /// <param name="sp"></param>
365 /// <param name="position"></param> 365 /// <param name="position"></param>
366 /// <param name="lookAt"></param> 366 /// <param name="lookAt"></param>
367 /// <param name="teleportFlags"></param 367 /// <param name="teleportFlags"></param>
368 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 368 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
369 { 369 {
370 m_log.DebugFormat( 370 m_log.DebugFormat(
@@ -399,11 +399,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
399 position.Z = newPosZ; 399 position.Z = newPosZ;
400 } 400 }
401 401
402 if (sp.Flying)
403 teleportFlags |= (uint)TeleportFlags.IsFlying;
404
402 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 405 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
403 406
404 sp.ControllingClient.SendTeleportStart(teleportFlags); 407 sp.ControllingClient.SendTeleportStart(teleportFlags);
405 408
406 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 409 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
410 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
407 sp.Velocity = Vector3.Zero; 411 sp.Velocity = Vector3.Zero;
408 sp.Teleport(position); 412 sp.Teleport(position);
409 413
@@ -604,8 +608,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
604 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 608 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
605 // it's actually doing a lot of work. 609 // it's actually doing a lot of work.
606 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 610 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
607 611 if (endPoint == null || endPoint.Address == null)
608 if (endPoint.Address == null)
609 { 612 {
610 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 613 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
611 614
@@ -642,6 +645,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
642 // both regions 645 // both regions
643 if (sp.ParentID != (uint)0) 646 if (sp.ParentID != (uint)0)
644 sp.StandUp(); 647 sp.StandUp();
648 else if (sp.Flying)
649 teleportFlags |= (uint)TeleportFlags.IsFlying;
645 650
646 if (DisableInterRegionTeleportCancellation) 651 if (DisableInterRegionTeleportCancellation)
647 teleportFlags |= (uint)TeleportFlags.DisableCancel; 652 teleportFlags |= (uint)TeleportFlags.DisableCancel;
@@ -900,7 +905,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
900 // 905 //
901 // This sleep can be increased if necessary. However, whilst it's active, 906 // This sleep can be increased if necessary. However, whilst it's active,
902 // an agent cannot teleport back to this region if it has teleported away. 907 // an agent cannot teleport back to this region if it has teleported away.
903 Thread.Sleep(2000); 908 Thread.Sleep(3000);
904 909
905 sp.Scene.IncomingCloseAgent(sp.UUID, false); 910 sp.Scene.IncomingCloseAgent(sp.UUID, false);
906 } 911 }
@@ -1050,7 +1055,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1050 1055
1051 #region Teleport Home 1056 #region Teleport Home
1052 1057
1053 public virtual void TeleportHome(UUID id, IClientAPI client) 1058 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
1059 {
1060 TeleportHome(id, client);
1061 }
1062
1063 public virtual bool TeleportHome(UUID id, IClientAPI client)
1054 { 1064 {
1055 m_log.DebugFormat( 1065 m_log.DebugFormat(
1056 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 1066 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -1060,12 +1070,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1060 1070
1061 if (uinfo != null) 1071 if (uinfo != null)
1062 { 1072 {
1073 if (uinfo.HomeRegionID == UUID.Zero)
1074 {
1075 // can't find the Home region: Tell viewer and abort
1076 client.SendTeleportFailed("You don't have a home position set.");
1077 return false;
1078 }
1063 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 1079 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
1064 if (regionInfo == null) 1080 if (regionInfo == null)
1065 { 1081 {
1066 // can't find the Home region: Tell viewer and abort 1082 // can't find the Home region: Tell viewer and abort
1067 client.SendTeleportFailed("Your home region could not be found."); 1083 client.SendTeleportFailed("Your home region could not be found.");
1068 return; 1084 return false;
1069 } 1085 }
1070 1086
1071 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 1087 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
@@ -1078,10 +1094,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1078 } 1094 }
1079 else 1095 else
1080 { 1096 {
1081 m_log.ErrorFormat( 1097 // can't find the Home region: Tell viewer and abort
1082 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 1098 client.SendTeleportFailed("Your home region could not be found.");
1083 client.Name, client.AgentId); 1099 return false;
1084 } 1100 }
1101 return true;
1085 } 1102 }
1086 1103
1087 #endregion 1104 #endregion
@@ -1089,15 +1106,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1089 1106
1090 #region Agent Crossings 1107 #region Agent Crossings
1091 1108
1092 public bool Cross(ScenePresence agent, bool isFlying) 1109 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1093 { 1110 {
1094 Scene scene = agent.Scene; 1111 version = String.Empty;
1095 Vector3 pos = agent.AbsolutePosition; 1112 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1096 1113
1097// m_log.DebugFormat( 1114// m_log.DebugFormat(
1098// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1115// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1099 1116
1100 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1101 uint neighbourx = scene.RegionInfo.RegionLocX; 1117 uint neighbourx = scene.RegionInfo.RegionLocX;
1102 uint neighboury = scene.RegionInfo.RegionLocY; 1118 uint neighboury = scene.RegionInfo.RegionLocY;
1103 const float boundaryDistance = 1.7f; 1119 const float boundaryDistance = 1.7f;
@@ -1118,52 +1134,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1118 } 1134 }
1119 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1135 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1120 { 1136 {
1121 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1137 neighboury--;
1122 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1138 newpos.Y = Constants.RegionSize - enterDistance;
1123 {
1124 neighboury--;
1125 newpos.Y = Constants.RegionSize - enterDistance;
1126 }
1127 else
1128 {
1129 agent.IsInTransit = true;
1130
1131 neighboury = b.TriggerRegionY;
1132 neighbourx = b.TriggerRegionX;
1133
1134 Vector3 newposition = pos;
1135 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1136 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1137 agent.ControllingClient.SendAgentAlertMessage(
1138 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1139 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1140 return true;
1141 }
1142 }
1143
1144 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
1145 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
1146 {
1147 neighbourx--;
1148 newpos.X = Constants.RegionSize - enterDistance;
1149 }
1150 else
1151 {
1152 agent.IsInTransit = true;
1153
1154 neighboury = ba.TriggerRegionY;
1155 neighbourx = ba.TriggerRegionX;
1156
1157 Vector3 newposition = pos;
1158 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1159 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1160 agent.ControllingClient.SendAgentAlertMessage(
1161 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1162 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1163
1164 return true;
1165 } 1139 }
1166 1140
1141 neighbourx--;
1142 newpos.X = Constants.RegionSize - enterDistance;
1167 } 1143 }
1168 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 1144 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1169 { 1145 {
@@ -1173,26 +1149,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1173 1149
1174 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1150 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1175 { 1151 {
1176 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1152 neighboury--;
1177 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 1153 newpos.Y = Constants.RegionSize - enterDistance;
1178 {
1179 neighboury--;
1180 newpos.Y = Constants.RegionSize - enterDistance;
1181 }
1182 else
1183 {
1184 agent.IsInTransit = true;
1185
1186 neighboury = ba.TriggerRegionY;
1187 neighbourx = ba.TriggerRegionX;
1188 Vector3 newposition = pos;
1189 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1190 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1191 agent.ControllingClient.SendAgentAlertMessage(
1192 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1193 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1194 return true;
1195 }
1196 } 1154 }
1197 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1155 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1198 { 1156 {
@@ -1204,25 +1162,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1204 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 1162 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1205 { 1163 {
1206 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 1164 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
1207 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 1165 neighboury--;
1208 { 1166 newpos.Y = Constants.RegionSize - enterDistance;
1209 neighboury--;
1210 newpos.Y = Constants.RegionSize - enterDistance;
1211 }
1212 else
1213 {
1214 agent.IsInTransit = true;
1215
1216 neighboury = b.TriggerRegionY;
1217 neighbourx = b.TriggerRegionX;
1218 Vector3 newposition = pos;
1219 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
1220 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
1221 agent.ControllingClient.SendAgentAlertMessage(
1222 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
1223 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
1224 return true;
1225 }
1226 } 1167 }
1227 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 1168 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1228 { 1169 {
@@ -1256,19 +1197,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1256 } 1197 }
1257 */ 1198 */
1258 1199
1259 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1200 xDest = neighbourx;
1201 yDest = neighboury;
1260 1202
1261 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1203 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1262 1204
1205 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1206
1263 ExpiringCache<ulong, DateTime> r; 1207 ExpiringCache<ulong, DateTime> r;
1264 DateTime banUntil; 1208 DateTime banUntil;
1265 1209
1266 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 1210 if (m_bannedRegions.TryGetValue(agentID, out r))
1267 { 1211 {
1268 if (r.TryGetValue(neighbourHandle, out banUntil)) 1212 if (r.TryGetValue(neighbourHandle, out banUntil))
1269 { 1213 {
1270 if (DateTime.Now < banUntil) 1214 if (DateTime.Now < banUntil)
1271 return false; 1215 return null;
1272 r.Remove(neighbourHandle); 1216 r.Remove(neighbourHandle);
1273 } 1217 }
1274 } 1218 }
@@ -1280,28 +1224,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1280 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1224 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1281 1225
1282 string reason; 1226 string reason;
1283 string version; 1227 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1284 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1285 { 1228 {
1286 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1287 if (r == null) 1229 if (r == null)
1288 { 1230 {
1289 r = new ExpiringCache<ulong, DateTime>(); 1231 r = new ExpiringCache<ulong, DateTime>();
1290 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1232 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1291 1233
1292 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 1234 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1293 } 1235 }
1294 else 1236 else
1295 { 1237 {
1296 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 1238 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1297 } 1239 }
1240 return null;
1241 }
1242
1243 return neighbourRegion;
1244 }
1245
1246 public bool Cross(ScenePresence agent, bool isFlying)
1247 {
1248 uint x;
1249 uint y;
1250 Vector3 newpos;
1251 string version;
1252
1253 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1254 if (neighbourRegion == null)
1255 {
1256 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1298 return false; 1257 return false;
1299 } 1258 }
1300 1259
1301 agent.IsInTransit = true; 1260 agent.IsInTransit = true;
1302 1261
1303 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1262 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1304 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1263 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1305 1264
1306 return true; 1265 return true;
1307 } 1266 }
@@ -1370,52 +1329,49 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1370 icon.EndInvoke(iar); 1329 icon.EndInvoke(iar);
1371 } 1330 }
1372 1331
1373 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1332 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1333 {
1334 if (neighbourRegion == null)
1335 return false;
1336
1337 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1338
1339 agent.RemoveFromPhysicalScene();
1340
1341 return true;
1342 }
1374 1343
1375 /// <summary> 1344 /// <summary>
1376 /// This Closes child agents on neighbouring regions 1345 /// This Closes child agents on neighbouring regions
1377 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1346 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1378 /// </summary> 1347 /// </summary>
1379 protected ScenePresence CrossAgentToNewRegionAsync( 1348 public ScenePresence CrossAgentToNewRegionAsync(
1380 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1349 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1381 bool isFlying, string version) 1350 bool isFlying, string version)
1382 { 1351 {
1383 if (neighbourRegion == null) 1352 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1353 {
1354 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1384 return agent; 1355 return agent;
1356 }
1385 1357
1386 if (!m_entityTransferStateMachine.SetInTransit(agent.UUID)) 1358 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1387 { 1359 {
1388 m_log.ErrorFormat( 1360 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1389 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2} - agent is already in transit",
1390 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName);
1391 return agent; 1361 return agent;
1392 } 1362 }
1393 1363
1394 bool transitWasReset = false; 1364 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1365 return agent;
1366 }
1395 1367
1368 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1369 {
1396 try 1370 try
1397 { 1371 {
1398 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 1372 AgentData cAgent = new AgentData();
1399
1400 m_log.DebugFormat(
1401 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1402 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1403
1404 Scene m_scene = agent.Scene;
1405
1406 if (!agent.ValidateAttachments())
1407 m_log.DebugFormat(
1408 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1409 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1410
1411 pos = pos + agent.Velocity;
1412 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1413
1414 agent.RemoveFromPhysicalScene();
1415
1416 AgentData cAgent = new AgentData();
1417 agent.CopyTo(cAgent); 1373 agent.CopyTo(cAgent);
1418 cAgent.Position = pos; 1374 cAgent.Position = pos + agent.Velocity;
1419 if (isFlying) 1375 if (isFlying)
1420 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1376 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1421 1377
@@ -1425,7 +1381,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1425 // Beyond this point, extra cleanup is needed beyond removing transit state 1381 // Beyond this point, extra cleanup is needed beyond removing transit state
1426 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1382 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1427 1383
1428 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1384 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1429 { 1385 {
1430 // region doesn't take it 1386 // region doesn't take it
1431 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1387 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1437,100 +1393,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1437 ReInstantiateScripts(agent); 1393 ReInstantiateScripts(agent);
1438 agent.AddToPhysicalScene(isFlying); 1394 agent.AddToPhysicalScene(isFlying);
1439 1395
1440 return agent; 1396 return false;
1441 } 1397 }
1442 1398
1443 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1399 }
1444 agent.ControllingClient.RequestClientInfo(); 1400 catch (Exception e)
1401 {
1402 m_log.ErrorFormat(
1403 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1404 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1445 1405
1446 //m_log.Debug("BEFORE CROSS"); 1406 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1447 //Scene.DumpChildrenSeeds(UUID); 1407 return false;
1448 //DumpKnownRegions(); 1408 }
1449 string agentcaps;
1450 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1451 {
1452 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1453 neighbourRegion.RegionHandle);
1454 return agent;
1455 }
1456 1409
1457 // No turning back 1410 return true;
1458 agent.IsChildAgent = true; 1411 }
1459 1412
1460 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1413 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1414 bool isFlying, string version)
1415 {
1416 agent.ControllingClient.RequestClientInfo();
1461 1417
1462 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1418 string agentcaps;
1419 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1420 {
1421 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1422 neighbourRegion.RegionHandle);
1423 return;
1424 }
1463 1425
1464 if (m_eqModule != null) 1426 // No turning back
1465 { 1427 agent.IsChildAgent = true;
1466 m_eqModule.CrossRegion(
1467 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1468 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1469 }
1470 else
1471 {
1472 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1473 capsPath);
1474 }
1475 1428
1476 // SUCCESS! 1429 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1477 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1478 1430
1479 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1431 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1480 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1481 1432
1482 agent.MakeChildAgent(); 1433 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1483 1434
1484 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1435 if (m_eqModule != null)
1485 // but not sure yet what the side effects would be. 1436 {
1486 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1437 m_eqModule.CrossRegion(
1487 transitWasReset = true; 1438 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1439 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1440 }
1441 else
1442 {
1443 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1444 capsPath);
1445 }
1488 1446
1489 // now we have a child agent in this region. Request all interesting data about other (root) agents 1447 // SUCCESS!
1490 agent.SendOtherAgentsAvatarDataToMe(); 1448 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1491 agent.SendOtherAgentsAppearanceToMe();
1492 1449
1493 // Backwards compatibility. Best effort 1450 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1494 if (version == "Unknown" || version == string.Empty) 1451 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1495 {
1496 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1497 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1498 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1499 }
1500 1452
1501 // Next, let's close the child agent connections that are too far away. 1453 agent.MakeChildAgent();
1502 agent.CloseChildAgents(neighbourx, neighboury);
1503 1454
1504 AgentHasMovedAway(agent, false); 1455 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1456 // but not sure yet what the side effects would be.
1457 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1505 1458
1506// // the user may change their profile information in other region, 1459 // now we have a child agent in this region. Request all interesting data about other (root) agents
1507// // so the userinfo in UserProfileCache is not reliable any more, delete it 1460 agent.SendOtherAgentsAvatarDataToMe();
1508// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1461 agent.SendOtherAgentsAppearanceToMe();
1509// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1510// {
1511// m_log.DebugFormat(
1512// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1513// }
1514
1515 //m_log.Debug("AFTER CROSS");
1516 //Scene.DumpChildrenSeeds(UUID);
1517 //DumpKnownRegions();
1518 }
1519 catch (Exception e)
1520 {
1521 m_log.ErrorFormat(
1522 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1523 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1524 1462
1525 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1463 // Backwards compatibility. Best effort
1526 } 1464 if (version == "Unknown" || version == string.Empty)
1527 finally
1528 { 1465 {
1529 if (!transitWasReset) 1466 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1530 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1467 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1468 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1531 } 1469 }
1532 1470
1533 return agent; 1471 // Next, let's close the child agent connections that are too far away.
1472 uint neighbourx;
1473 uint neighboury;
1474
1475 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1476
1477 neighbourx /= Constants.RegionSize;
1478 neighboury /= Constants.RegionSize;
1479
1480 agent.CloseChildAgents(neighbourx, neighboury);
1481
1482 AgentHasMovedAway(agent, false);
1483
1484 // the user may change their profile information in other region,
1485 // so the userinfo in UserProfileCache is not reliable any more, delete it
1486 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1487// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1488// {
1489// m_log.DebugFormat(
1490// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1491// }
1492
1493 //m_log.Debug("AFTER CROSS");
1494 //Scene.DumpChildrenSeeds(UUID);
1495 //DumpKnownRegions();
1496
1497 return;
1534 } 1498 }
1535 1499
1536 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1500 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1601,10 +1565,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1601 agent.Id0 = currentAgentCircuit.Id0; 1565 agent.Id0 = currentAgentCircuit.Id0;
1602 } 1566 }
1603 1567
1604 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1568 IPEndPoint external = region.ExternalEndPoint;
1605 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1569 if (external != null)
1570 {
1571 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1572 d.BeginInvoke(sp, agent, region, external, true,
1606 InformClientOfNeighbourCompleted, 1573 InformClientOfNeighbourCompleted,
1607 d); 1574 d);
1575 }
1608 } 1576 }
1609 #endregion 1577 #endregion
1610 1578
@@ -2185,27 +2153,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2185 Utils.LongToUInts(newRegionHandle, out x, out y); 2153 Utils.LongToUInts(newRegionHandle, out x, out y);
2186 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 2154 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2187 2155
2188 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2156 if (destination != null)
2189 { 2157 {
2190 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 2158 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
2159 return; // we did it
2160 }
2191 2161
2192 // We are going to move the object back to the old position so long as the old position 2162 // no one or failed lets go back and tell physics to go on
2193 // is in the region 2163 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2194 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 2164 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2195 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 2165 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
2196 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
2197 2166
2198 grp.RootPart.GroupPosition = oldGroupPosition; 2167 grp.AbsolutePosition = oldGroupPosition;
2168 grp.Velocity = Vector3.Zero;
2199 2169
2200 // Need to turn off the physics flags, otherwise the object will continue to attempt to 2170 if (grp.RootPart.PhysActor != null)
2201 // move out of the region creating an infinite loop of failed attempts to cross 2171 grp.RootPart.PhysActor.CrossingFailure();
2202 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2203 2172
2204 grp.ScheduleGroupForFullUpdate(); 2173 if (grp.RootPart.KeyframeMotion != null)
2205 } 2174 grp.RootPart.KeyframeMotion.CrossingFailure();
2175
2176 grp.ScheduleGroupForFullUpdate();
2206 } 2177 }
2207 2178
2208 2179
2180
2209 /// <summary> 2181 /// <summary>
2210 /// Move the given scene object into a new region 2182 /// Move the given scene object into a new region
2211 /// </summary> 2183 /// </summary>
@@ -2256,17 +2228,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2256 grp, e); 2228 grp, e);
2257 } 2229 }
2258 } 2230 }
2231/*
2232 * done on caller ( not in attachments crossing for now)
2259 else 2233 else
2260 { 2234 {
2235
2261 if (!grp.IsDeleted) 2236 if (!grp.IsDeleted)
2262 { 2237 {
2263 PhysicsActor pa = grp.RootPart.PhysActor; 2238 PhysicsActor pa = grp.RootPart.PhysActor;
2264 if (pa != null) 2239 if (pa != null)
2240 {
2265 pa.CrossingFailure(); 2241 pa.CrossingFailure();
2242 if (grp.RootPart.KeyframeMotion != null)
2243 {
2244 // moved to KeyframeMotion.CrossingFailure
2245// grp.RootPart.Velocity = Vector3.Zero;
2246 grp.RootPart.KeyframeMotion.CrossingFailure();
2247// grp.SendGroupRootTerseUpdate();
2248 }
2249 }
2266 } 2250 }
2267 2251
2268 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 2252 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2269 } 2253 }
2254 */
2270 } 2255 }
2271 else 2256 else
2272 { 2257 {
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 b188741..9b78b3b 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
184 184
185 protected override void OnNewClient(IClientAPI client) 185 protected override void OnNewClient(IClientAPI client)
186 { 186 {
187 client.OnTeleportHomeRequest += TeleportHome; 187 client.OnTeleportHomeRequest += TriggerTeleportHome;
188 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 188 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
189 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 189 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
190 } 190 }
@@ -291,6 +291,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
291 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 291 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
292 } 292 }
293 293
294 public void TriggerTeleportHome(UUID id, IClientAPI client)
295 {
296 TeleportHome(id, client);
297 }
298
294 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) 299 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
295 { 300 {
296 reason = "Please wear your grid's allowed appearance before teleporting to another grid"; 301 reason = "Please wear your grid's allowed appearance before teleporting to another grid";
@@ -409,7 +414,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
409 // return base.UpdateAgent(reg, finalDestination, agentData, sp); 414 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
410 //} 415 //}
411 416
412 public override void TeleportHome(UUID id, IClientAPI client) 417 public override bool TeleportHome(UUID id, IClientAPI client)
413 { 418 {
414 m_log.DebugFormat( 419 m_log.DebugFormat(
415 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 420 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -420,8 +425,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
420 { 425 {
421 // local grid user 426 // local grid user
422 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); 427 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
423 base.TeleportHome(id, client); 428 return base.TeleportHome(id, client);
424 return;
425 } 429 }
426 430
427 // Foreign user wants to go home 431 // Foreign user wants to go home
@@ -431,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
431 { 435 {
432 client.SendTeleportFailed("Your information has been lost"); 436 client.SendTeleportFailed("Your information has been lost");
433 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); 437 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information");
434 return; 438 return false;
435 } 439 }
436 440
437 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); 441 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString());
@@ -441,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
441 { 445 {
442 client.SendTeleportFailed("Your home region could not be found"); 446 client.SendTeleportFailed("Your home region could not be found");
443 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); 447 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found");
444 return; 448 return false;
445 } 449 }
446 450
447 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); 451 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId);
@@ -449,7 +453,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
449 { 453 {
450 client.SendTeleportFailed("Internal error"); 454 client.SendTeleportFailed("Internal error");
451 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); 455 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be");
452 return; 456 return false;
453 } 457 }
454 458
455 GridRegion homeGatekeeper = MakeRegion(aCircuit); 459 GridRegion homeGatekeeper = MakeRegion(aCircuit);
@@ -457,9 +461,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
457 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 461 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
458 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 462 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
459 463
460 DoTeleport( 464 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
461 sp, homeGatekeeper, finalDestination, 465 return true;
462 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
463 } 466 }
464 467
465 /// <summary> 468 /// <summary>
@@ -586,4 +589,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
586 return region; 589 return region;
587 } 590 }
588 } 591 }
589} \ No newline at end of file 592}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index eaf4ce2..5aad7f0 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
@@ -357,6 +362,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
357 362
358 foreach (SceneObjectGroup objectGroup in objlist) 363 foreach (SceneObjectGroup objectGroup in objlist)
359 { 364 {
365 if (objectGroup.RootPart.KeyframeMotion != null)
366 objectGroup.RootPart.KeyframeMotion.Stop();
367 objectGroup.RootPart.SetForce(Vector3.Zero);
368 objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
369 objectGroup.RootPart.KeyframeMotion = null;
370
360 Vector3 inventoryStoredPosition = new Vector3 371 Vector3 inventoryStoredPosition = new Vector3
361 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 372 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
362 ? 250 373 ? 250
@@ -367,9 +378,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
367 : objectGroup.AbsolutePosition.Y, 378 : objectGroup.AbsolutePosition.Y,
368 objectGroup.AbsolutePosition.Z); 379 objectGroup.AbsolutePosition.Z);
369 380
381 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
370 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 382 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
371 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 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
391
372 objectGroup.AbsolutePosition = inventoryStoredPosition; 392 objectGroup.AbsolutePosition = inventoryStoredPosition;
393 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
373 394
374 // Make sure all bits but the ones we want are clear 395 // Make sure all bits but the ones we want are clear
375 // on take. 396 // on take.
@@ -488,8 +509,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
488 IClientAPI remoteClient) 509 IClientAPI remoteClient)
489 { 510 {
490 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; 511 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
512 // For the porposes of inventory, an object is modify if the prims
513 // are modify. This allows renaming an object that contains no
514 // mod items.
491 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 515 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
492 effectivePerms &= grp.GetEffectivePermissions(); 516 {
517 uint groupPerms = grp.GetEffectivePermissions(true);
518 if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0)
519 groupPerms |= (uint)PermissionMask.Modify;
520
521 effectivePerms &= groupPerms;
522 }
493 effectivePerms |= (uint)PermissionMask.Move; 523 effectivePerms |= (uint)PermissionMask.Move;
494 524
495 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 525 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
@@ -669,7 +699,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
669 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) 699 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
670 { 700 {
671 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 701 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
672 folder = m_Scene.InventoryService.GetFolder(f); 702 if (f != null)
703 folder = m_Scene.InventoryService.GetFolder(f);
673 } 704 }
674 } 705 }
675 706
@@ -699,16 +730,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
699 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 730 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
700 { 731 {
701// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 732// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
702
703 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 733 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
704 item = m_Scene.InventoryService.GetItem(item); 734 item = m_Scene.InventoryService.GetItem(item);
705 735
706 if (item == null) 736 if (item == null)
707 { 737 {
708 m_log.WarnFormat(
709 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
710 itemID, remoteClient.Name);
711
712 return null; 738 return null;
713 } 739 }
714 740
@@ -759,6 +785,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
759 if (e == null || attachment) // Single 785 if (e == null || attachment) // Single
760 { 786 {
761 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 787 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
788 if (!attachment)
789 {
790 g.RootPart.AttachPoint = g.RootPart.Shape.State;
791 g.RootPart.AttachOffset = g.AbsolutePosition;
792 g.RootPart.AttachRotation = g.GroupRotation;
793 g.RootPart.Shape.State = 0;
794 }
762 795
763 objlist.Add(g); 796 objlist.Add(g);
764 veclist.Add(new Vector3(0, 0, 0)); 797 veclist.Add(new Vector3(0, 0, 0));
@@ -788,6 +821,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
788 foreach (XmlNode n in groups) 821 foreach (XmlNode n in groups)
789 { 822 {
790 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); 823 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
824 g.RootPart.AttachPoint = g.RootPart.Shape.State;
825 g.RootPart.AttachOffset = g.AbsolutePosition;
826 g.RootPart.AttachRotation = g.GroupRotation;
827 g.RootPart.Shape.State = 0;
791 828
792 objlist.Add(g); 829 objlist.Add(g);
793 XmlElement el = (XmlElement)n; 830 XmlElement el = (XmlElement)n;
@@ -807,12 +844,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
807 } 844 }
808 } 845 }
809 846
847 int primcount = 0;
848 foreach (SceneObjectGroup g in objlist)
849 primcount += g.PrimCount;
850
851 if (!m_Scene.Permissions.CanRezObject(
852 primcount, remoteClient.AgentId, pos)
853 && !attachment)
854 {
855 // The client operates in no fail mode. It will
856 // have already removed the item from the folder
857 // if it's no copy.
858 // Put it back if it's not an attachment
859 //
860 if (item != null)
861 {
862 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
863 remoteClient.SendBulkUpdateInventory(item);
864 }
865
866 return null;
867 }
868
810 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) 869 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
811 return null; 870 return null;
812 871
813 for (int i = 0; i < objlist.Count; i++) 872 for (int i = 0; i < objlist.Count; i++)
814 { 873 {
815 group = objlist[i]; 874 group = objlist[i];
875 SceneObjectPart rootPart = group.RootPart;
816 876
817// m_log.DebugFormat( 877// m_log.DebugFormat(
818// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 878// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -873,8 +933,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
873 933
874 if (!attachment) 934 if (!attachment)
875 { 935 {
876 SceneObjectPart rootPart = group.RootPart;
877
878 if (rootPart.Shape.PCode == (byte)PCode.Prim) 936 if (rootPart.Shape.PCode == (byte)PCode.Prim)
879 group.ClearPartAttachmentData(); 937 group.ClearPartAttachmentData();
880 938
@@ -892,6 +950,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
892// remoteClient.Name); 950// remoteClient.Name);
893 } 951 }
894 952
953 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
954
895 if (item != null) 955 if (item != null)
896 DoPostRezWhenFromItem(item, attachment); 956 DoPostRezWhenFromItem(item, attachment);
897 957
@@ -970,8 +1030,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
970 { 1030 {
971 rootPart.Name = item.Name; 1031 rootPart.Name = item.Name;
972 rootPart.Description = item.Description; 1032 rootPart.Description = item.Description;
973 rootPart.ObjectSaleType = item.SaleType; 1033 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
974 rootPart.SalePrice = item.SalePrice; 1034 {
1035 rootPart.ObjectSaleType = item.SaleType;
1036 rootPart.SalePrice = item.SalePrice;
1037 }
975 } 1038 }
976 1039
977 so.FromFolderID = item.Folder; 1040 so.FromFolderID = item.Folder;
@@ -981,7 +1044,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
981// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1044// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
982 1045
983 if ((rootPart.OwnerID != item.Owner) || 1046 if ((rootPart.OwnerID != item.Owner) ||
984 (item.CurrentPermissions & 16) != 0) 1047 (item.CurrentPermissions & 16) != 0 ||
1048 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
985 { 1049 {
986 //Need to kill the for sale here 1050 //Need to kill the for sale here
987 rootPart.ObjectSaleType = 0; 1051 rootPart.ObjectSaleType = 0;
@@ -991,31 +1055,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
991 { 1055 {
992 foreach (SceneObjectPart part in so.Parts) 1056 foreach (SceneObjectPart part in so.Parts)
993 { 1057 {
994 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
995 {
996 part.EveryoneMask = item.EveryOnePermissions;
997 part.NextOwnerMask = item.NextPermissions;
998 }
999 part.GroupMask = 0; // DO NOT propagate here 1058 part.GroupMask = 0; // DO NOT propagate here
1059
1060 part.LastOwnerID = part.OwnerID;
1061 part.OwnerID = item.Owner;
1062 part.Inventory.ChangeInventoryOwner(item.Owner);
1000 } 1063 }
1001 1064
1002 so.ApplyNextOwnerPermissions(); 1065 so.ApplyNextOwnerPermissions();
1066
1067 // In case the user has changed flags on a received item
1068 // we have to apply those changes after the slam. Else we
1069 // get a net loss of permissions
1070 foreach (SceneObjectPart part in so.Parts)
1071 {
1072 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1073 {
1074 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1075 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1076 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1077 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1078 }
1079 }
1003 } 1080 }
1004 } 1081 }
1005 1082 else
1006 foreach (SceneObjectPart part in so.Parts)
1007 { 1083 {
1008 part.FromUserInventoryItemID = fromUserInventoryItemId; 1084 foreach (SceneObjectPart part in so.Parts)
1009
1010 if ((part.OwnerID != item.Owner) ||
1011 (item.CurrentPermissions & 16) != 0)
1012 { 1085 {
1013 part.Inventory.ChangeInventoryOwner(item.Owner); 1086 part.FromUserInventoryItemID = fromUserInventoryItemId;
1014 part.GroupMask = 0; // DO NOT propagate here 1087
1088 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1089 part.EveryoneMask = item.EveryOnePermissions;
1090 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1091 part.NextOwnerMask = item.NextPermissions;
1092 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1093 part.GroupMask = item.GroupPermissions;
1015 } 1094 }
1016
1017 part.EveryoneMask = item.EveryOnePermissions;
1018 part.NextOwnerMask = item.NextPermissions;
1019 } 1095 }
1020 1096
1021 rootPart.TrimPermissions(); 1097 rootPart.TrimPermissions();
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index c4255b9..7b11658 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -92,9 +92,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid
92 } 92 }
93 } 93 }
94 94
95 protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 95 protected override List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
96 { 96 {
97 List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); 97 List<MapBlockData> mapBlocks = base.GetAndSendBlocksInternal(remoteClient, minX, minY, maxX, maxY, flag);
98 lock (m_SeenMapBlocks) 98 lock (m_SeenMapBlocks)
99 { 99 {
100 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) 100 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 a676971..0276267 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -42,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using Mono.Addins; 44using Mono.Addins;
45using Amib.Threading;
45 46
46/***************************************************** 47/*****************************************************
47 * 48 *
@@ -102,6 +103,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
102 private Dictionary<UUID, HttpRequestClass> m_pendingRequests; 103 private Dictionary<UUID, HttpRequestClass> m_pendingRequests;
103 private Scene m_scene; 104 private Scene m_scene;
104 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>(); 105 // private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
106 public static SmartThreadPool ThreadPool = null;
105 107
106 public HttpRequestModule() 108 public HttpRequestModule()
107 { 109 {
@@ -279,7 +281,30 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
279 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 281 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
280 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 282 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
281 283
284 int maxThreads = 50;
285
286 IConfig httpConfig = config.Configs["HttpRequestModule"];
287 if (httpConfig != null)
288 {
289 maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads);
290 }
291
282 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 292 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
293
294 // First instance sets this up for all sims
295 if (ThreadPool == null)
296 {
297 STPStartInfo startInfo = new STPStartInfo();
298 startInfo.IdleTimeout = 20000;
299 startInfo.MaxWorkerThreads = maxThreads;
300 startInfo.MinWorkerThreads = 5;
301 startInfo.ThreadPriority = ThreadPriority.BelowNormal;
302 startInfo.StartSuspended = true;
303
304 ThreadPool = new SmartThreadPool(startInfo);
305
306 ThreadPool.Start();
307 }
283 } 308 }
284 309
285 public void AddRegion(Scene scene) 310 public void AddRegion(Scene scene)
@@ -340,7 +365,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
340 public string HttpMIMEType = "text/plain;charset=utf-8"; 365 public string HttpMIMEType = "text/plain;charset=utf-8";
341 public int HttpTimeout; 366 public int HttpTimeout;
342 public bool HttpVerifyCert = true; 367 public bool HttpVerifyCert = true;
343 private Thread httpThread; 368 public IWorkItemResult WorkItem = null;
344 369
345 // Request info 370 // Request info
346 private UUID _itemID; 371 private UUID _itemID;
@@ -374,12 +399,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
374 399
375 public void Process() 400 public void Process()
376 { 401 {
377 httpThread = new Thread(SendRequest);
378 httpThread.Name = "HttpRequestThread";
379 httpThread.Priority = ThreadPriority.BelowNormal;
380 httpThread.IsBackground = true;
381 _finished = false; 402 _finished = false;
382 httpThread.Start(); 403
404 lock (HttpRequestModule.ThreadPool)
405 WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null);
406 }
407
408 private object StpSendWrapper(object o)
409 {
410 SendRequest();
411 return null;
383 } 412 }
384 413
385 /* 414 /*
@@ -398,6 +427,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
398 try 427 try
399 { 428 {
400 Request = (HttpWebRequest) WebRequest.Create(Url); 429 Request = (HttpWebRequest) WebRequest.Create(Url);
430
431 //This works around some buggy HTTP Servers like Lighttpd
432 Request.ServicePoint.Expect100Continue = false;
433
401 Request.Method = HttpMethod; 434 Request.Method = HttpMethod;
402 Request.ContentType = HttpMIMEType; 435 Request.ContentType = HttpMIMEType;
403 436
@@ -405,13 +438,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
405 { 438 {
406 // We could hijack Connection Group Name to identify 439 // We could hijack Connection Group Name to identify
407 // a desired security exception. But at the moment we'll use a dummy header instead. 440 // a desired security exception. But at the moment we'll use a dummy header instead.
408// Request.ConnectionGroupName = "NoVerify";
409 Request.Headers.Add("NoVerifyCert", "true"); 441 Request.Headers.Add("NoVerifyCert", "true");
410 } 442 }
411// else
412// {
413// Request.ConnectionGroupName="Verify";
414// }
415 if (proxyurl != null && proxyurl.Length > 0) 443 if (proxyurl != null && proxyurl.Length > 0)
416 { 444 {
417 if (proxyexcepts != null && proxyexcepts.Length > 0) 445 if (proxyexcepts != null && proxyexcepts.Length > 0)
@@ -474,25 +502,56 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
474 502
475 // continue building the string 503 // continue building the string
476 sb.Append(tempString); 504 sb.Append(tempString);
505 if (sb.Length > 2048)
506 break;
477 } 507 }
478 } while (count > 0); // any more data to read? 508 } while (count > 0); // any more data to read?
479 509
480 ResponseBody = sb.ToString(); 510 ResponseBody = sb.ToString().Replace("\r", "");
481 } 511 }
482 catch (Exception e) 512 catch (WebException e)
483 { 513 {
484 Status = (int)OSHttpStatusCode.ClientErrorJoker; 514 if (e.Status == WebExceptionStatus.ProtocolError)
485 ResponseBody = e.Message; 515 {
516 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
517 Status = (int)webRsp.StatusCode;
518 try
519 {
520 using (Stream responseStream = webRsp.GetResponseStream())
521 {
522 ResponseBody = responseStream.GetStreamString();
523 }
524 }
525 catch
526 {
527 ResponseBody = webRsp.StatusDescription;
528 }
529 }
530 else
531 {
532 Status = (int)OSHttpStatusCode.ClientErrorJoker;
533 ResponseBody = e.Message;
534 }
535
536 if (ResponseBody == null)
537 ResponseBody = String.Empty;
486 538
487 _finished = true; 539 _finished = true;
488 return; 540 return;
489 } 541 }
542 catch (Exception e)
543 {
544 // Don't crash on anything else
545 }
490 finally 546 finally
491 { 547 {
492 if (response != null) 548 if (response != null)
493 response.Close(); 549 response.Close();
494 } 550 }
495 551
552 if (ResponseBody == null)
553 ResponseBody = String.Empty;
554
496 _finished = true; 555 _finished = true;
497 } 556 }
498 557
@@ -500,7 +559,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
500 { 559 {
501 try 560 try
502 { 561 {
503 httpThread.Abort(); 562 if (!WorkItem.Cancel())
563 {
564 WorkItem.Abort();
565 }
504 } 566 }
505 catch (Exception) 567 catch (Exception)
506 { 568 {
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index c9cd412..f2922d6 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -42,40 +42,15 @@ 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;
79 } 54 }
80 55
81 public class RequestData 56 public class RequestData
@@ -89,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 64 //public ManualResetEvent ev;
90 public bool requestDone; 65 public bool requestDone;
91 public int startTime; 66 public int startTime;
67 public bool responseSent;
92 public string uri; 68 public string uri;
93 } 69 }
94 70
@@ -102,20 +78,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 78 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 79 MethodBase.GetCurrentMethod().DeclaringType);
104 80
105 /// <summary> 81 private Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 82 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 83
115 /// <summary> 84 private Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 85 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 86
120 private uint m_HttpsPort = 0; 87 private uint m_HttpsPort = 0;
121 private IHttpServer m_HttpServer = null; 88 private IHttpServer m_HttpServer = null;
@@ -126,7 +93,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
126 /// <summary> 93 /// <summary>
127 /// The default maximum number of urls 94 /// The default maximum number of urls
128 /// </summary> 95 /// </summary>
129 public const int DefaultTotalUrls = 100; 96 public const int DefaultTotalUrls = 15000;
130 97
131 /// <summary> 98 /// <summary>
132 /// Maximum number of external urls that can be set up by this module. 99 /// Maximum number of external urls that can be set up by this module.
@@ -221,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 188 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
222 return urlcode; 189 return urlcode;
223 } 190 }
224 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 191 string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
225 192
226 UrlData urlData = new UrlData(); 193 UrlData urlData = new UrlData();
227 urlData.hostID = host.UUID; 194 urlData.hostID = host.UUID;
@@ -229,19 +196,20 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
229 urlData.engine = engine; 196 urlData.engine = engine;
230 urlData.url = url; 197 urlData.url = url;
231 urlData.urlcode = urlcode; 198 urlData.urlcode = urlcode;
199 urlData.isSsl = false;
232 urlData.requests = new Dictionary<UUID, RequestData>(); 200 urlData.requests = new Dictionary<UUID, RequestData>();
233 201
234 m_UrlMap[url] = urlData; 202 m_UrlMap[url] = urlData;
235 203
236 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 204 string uri = "/lslhttp/" + urlcode.ToString();
237 205
238 m_HttpServer.AddPollServiceHTTPHandler( 206 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
239 uri, 207 args.Type = PollServiceEventArgs.EventType.LslHttp;
240 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 208 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
241 209
242 m_log.DebugFormat( 210// m_log.DebugFormat(
243 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 211// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
244 uri, itemID, host.Name, host.LocalId); 212// uri, itemID, host.Name, host.LocalId);
245 213
246 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 214 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
247 } 215 }
@@ -266,7 +234,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
266 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 234 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
267 return urlcode; 235 return urlcode;
268 } 236 }
269 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 237 string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
270 238
271 UrlData urlData = new UrlData(); 239 UrlData urlData = new UrlData();
272 urlData.hostID = host.UUID; 240 urlData.hostID = host.UUID;
@@ -274,19 +242,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
274 urlData.engine = engine; 242 urlData.engine = engine;
275 urlData.url = url; 243 urlData.url = url;
276 urlData.urlcode = urlcode; 244 urlData.urlcode = urlcode;
245 urlData.isSsl = true;
277 urlData.requests = new Dictionary<UUID, RequestData>(); 246 urlData.requests = new Dictionary<UUID, RequestData>();
278 247
248
279 m_UrlMap[url] = urlData; 249 m_UrlMap[url] = urlData;
280 250
281 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 251 string uri = "/lslhttps/" + urlcode.ToString();
282 252
283 m_HttpsServer.AddPollServiceHTTPHandler( 253 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
284 uri, 254 args.Type = PollServiceEventArgs.EventType.LslHttp;
285 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 255 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
286 256
287 m_log.DebugFormat( 257// m_log.DebugFormat(
288 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 258// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
289 uri, itemID, host.Name, host.LocalId); 259// uri, itemID, host.Name, host.LocalId);
290 260
291 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 261 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
292 } 262 }
@@ -305,12 +275,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
305 return; 275 return;
306 } 276 }
307 277
308 foreach (UUID req in data.requests.Keys) 278 lock (m_RequestMap)
309 m_RequestMap.Remove(req); 279 {
310 280 foreach (UUID req in data.requests.Keys)
311 m_log.DebugFormat( 281 m_RequestMap.Remove(req);
312 "[URL MODULE]: Releasing url {0} for {1} in {2}", 282 }
313 url, data.itemID, data.hostID); 283
284// m_log.DebugFormat(
285// "[URL MODULE]: Releasing url {0} for {1} in {2}",
286// url, data.itemID, data.hostID);
314 287
315 RemoveUrl(data); 288 RemoveUrl(data);
316 m_UrlMap.Remove(url); 289 m_UrlMap.Remove(url);
@@ -335,29 +308,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
335 308
336 public void HttpResponse(UUID request, int status, string body) 309 public void HttpResponse(UUID request, int status, string body)
337 { 310 {
338 lock (m_UrlMap) 311 lock (m_RequestMap)
339 { 312 {
340 if (m_RequestMap.ContainsKey(request)) 313 if (m_RequestMap.ContainsKey(request))
341 { 314 {
342 UrlData urlData = m_RequestMap[request]; 315 UrlData urlData = m_RequestMap[request];
343 string responseBody = body; 316 if (!urlData.requests[request].responseSent)
344 if (urlData.requests[request].responseType.Equals("text/plain"))
345 { 317 {
346 string value; 318 string responseBody = body;
347 if (urlData.requests[request].headers.TryGetValue("user-agent", out value)) 319 if (urlData.requests[request].responseType.Equals("text/plain"))
348 { 320 {
349 if (value != null && value.IndexOf("MSIE") >= 0) 321 string value;
322 if (urlData.requests[request].headers.TryGetValue("user-agent", out value))
350 { 323 {
351 // wrap the html escaped response if the target client is IE 324 if (value != null && value.IndexOf("MSIE") >= 0)
352 // It ignores "text/plain" if the body is html 325 {
353 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>"; 326 // wrap the html escaped response if the target client is IE
327 // It ignores "text/plain" if the body is html
328 responseBody = "<html>" + System.Web.HttpUtility.HtmlEncode(body) + "</html>";
329 }
354 } 330 }
355 } 331 }
332
333 urlData.requests[request].responseCode = status;
334 urlData.requests[request].responseBody = body;
335 //urlData.requests[request].ev.Set();
336 urlData.requests[request].requestDone = true;
337 urlData.requests[request].responseSent = true;
356 } 338 }
357 urlData.requests[request].responseCode = status;
358 urlData.requests[request].responseBody = responseBody;
359 //urlData.requests[request].ev.Set();
360 urlData.requests[request].requestDone =true;
361 } 339 }
362 else 340 else
363 { 341 {
@@ -368,7 +346,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
368 346
369 public string GetHttpHeader(UUID requestId, string header) 347 public string GetHttpHeader(UUID requestId, string header)
370 { 348 {
371 lock (m_UrlMap) 349 lock (m_RequestMap)
372 { 350 {
373 if (m_RequestMap.ContainsKey(requestId)) 351 if (m_RequestMap.ContainsKey(requestId))
374 { 352 {
@@ -382,7 +360,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
382 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 360 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
383 } 361 }
384 } 362 }
385
386 return String.Empty; 363 return String.Empty;
387 } 364 }
388 365
@@ -406,8 +383,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
406 { 383 {
407 RemoveUrl(url.Value); 384 RemoveUrl(url.Value);
408 removeURLs.Add(url.Key); 385 removeURLs.Add(url.Key);
409 foreach (UUID req in url.Value.requests.Keys) 386 lock (m_RequestMap)
410 m_RequestMap.Remove(req); 387 {
388 foreach (UUID req in url.Value.requests.Keys)
389 m_RequestMap.Remove(req);
390 }
411 } 391 }
412 } 392 }
413 393
@@ -428,9 +408,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
428 { 408 {
429 RemoveUrl(url.Value); 409 RemoveUrl(url.Value);
430 removeURLs.Add(url.Key); 410 removeURLs.Add(url.Key);
431 411 lock (m_RequestMap)
432 foreach (UUID req in url.Value.requests.Keys) 412 {
433 m_RequestMap.Remove(req); 413 foreach (UUID req in url.Value.requests.Keys)
414 m_RequestMap.Remove(req);
415 }
434 } 416 }
435 } 417 }
436 418
@@ -439,123 +421,128 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
439 } 421 }
440 } 422 }
441 423
424
442 private void RemoveUrl(UrlData data) 425 private void RemoveUrl(UrlData data)
443 { 426 {
444 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 427 if (data.isSsl)
428 m_HttpsServer.RemoveHTTPHandler("", "/lslhttps/"+data.urlcode.ToString()+"/");
429 else
430 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
445 } 431 }
446 432
447 private Hashtable NoEvents(UUID requestID, UUID sessionID) 433 private Hashtable NoEvents(UUID requestID, UUID sessionID)
448 { 434 {
449 Hashtable response = new Hashtable(); 435 Hashtable response = new Hashtable();
450 UrlData urlData; 436 UrlData url;
451 437 int startTime = 0;
452 lock (m_UrlMap) 438 lock (m_RequestMap)
453 { 439 {
454 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
455 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
456 // for the request ID.
457 if (!m_RequestMap.ContainsKey(requestID)) 440 if (!m_RequestMap.ContainsKey(requestID))
458 {
459 response["int_response_code"] = 404;
460 response["str_response_string"] = "";
461 response["keepalive"] = false;
462 response["reusecontext"] = false;
463
464 return response; 441 return response;
465 } 442 url = m_RequestMap[requestID];
443 startTime = url.requests[requestID].startTime;
444 }
466 445
467 urlData = m_RequestMap[requestID]; 446 if (System.Environment.TickCount - startTime > 25000)
447 {
448 response["int_response_code"] = 500;
449 response["str_response_string"] = "Script timeout";
450 response["content_type"] = "text/plain";
451 response["keepalive"] = false;
452 response["reusecontext"] = false;
468 453
469 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 454 //remove from map
455 lock (url.requests)
456 {
457 url.requests.Remove(requestID);
458 }
459 lock (m_RequestMap)
470 { 460 {
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;
476
477 //remove from map
478 urlData.requests.Remove(requestID);
479 m_RequestMap.Remove(requestID); 461 m_RequestMap.Remove(requestID);
480
481 return response;
482 } 462 }
463
464 return response;
483 } 465 }
484 466
467
485 return response; 468 return response;
486 } 469 }
487 470
488 private bool HasEvents(UUID requestID, UUID sessionID) 471 private bool HasEvents(UUID requestID, UUID sessionID)
489 { 472 {
490 lock (m_UrlMap) 473 UrlData url=null;
474
475 lock (m_RequestMap)
491 { 476 {
492 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
493 // can still make it through to HttpRequestHandler(). That will return without setting up a request
494 // when it detects that the URL has been removed. The poller, however, will continue to ask for
495 // events for that request, so here we will signal that there are events and in GetEvents we will
496 // return a 404.
497 if (!m_RequestMap.ContainsKey(requestID)) 477 if (!m_RequestMap.ContainsKey(requestID))
498 { 478 {
499 return true; 479 return false;
500 } 480 }
501 481 url = m_RequestMap[requestID];
502 UrlData urlData = m_RequestMap[requestID]; 482 }
503 483 lock (url.requests)
504 if (!urlData.requests.ContainsKey(requestID)) 484 {
485 if (!url.requests.ContainsKey(requestID))
505 { 486 {
506 return true; 487 return false;
507 } 488 }
508 489 else
509 // Trigger return of timeout response.
510 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
511 { 490 {
512 return true; 491 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
492 {
493 return true;
494 }
495 if (url.requests[requestID].requestDone)
496 return true;
497 else
498 return false;
513 } 499 }
514
515 return urlData.requests[requestID].requestDone;
516 } 500 }
517 } 501 }
518 502 private Hashtable GetEvents(UUID requestID, UUID sessionID)
519 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
520 { 503 {
521 Hashtable response; 504 UrlData url = null;
505 RequestData requestData = null;
522 506
523 lock (m_UrlMap) 507 lock (m_RequestMap)
524 { 508 {
525 UrlData url = null;
526 RequestData requestData = null;
527
528 if (!m_RequestMap.ContainsKey(requestID)) 509 if (!m_RequestMap.ContainsKey(requestID))
529 return NoEvents(requestID, sessionID); 510 return NoEvents(requestID,sessionID);
530
531 url = m_RequestMap[requestID]; 511 url = m_RequestMap[requestID];
512 }
513 lock (url.requests)
514 {
532 requestData = url.requests[requestID]; 515 requestData = url.requests[requestID];
516 }
517
518 if (!requestData.requestDone)
519 return NoEvents(requestID,sessionID);
520
521 Hashtable response = new Hashtable();
533 522
534 if (!requestData.requestDone) 523 if (System.Environment.TickCount - requestData.startTime > 25000)
535 return NoEvents(requestID, sessionID); 524 {
536 525 response["int_response_code"] = 500;
537 response = new Hashtable(); 526 response["str_response_string"] = "Script timeout";
538 527 response["content_type"] = "text/plain";
539 if (System.Environment.TickCount - requestData.startTime > 25000)
540 {
541 response["int_response_code"] = 500;
542 response["str_response_string"] = "Script timeout";
543 response["content_type"] = "text/plain";
544 response["keepalive"] = false;
545 response["reusecontext"] = false;
546 return response;
547 }
548
549 //put response
550 response["int_response_code"] = requestData.responseCode;
551 response["str_response_string"] = requestData.responseBody;
552 response["content_type"] = requestData.responseType;
553 // response["content_type"] = "text/plain";
554 response["keepalive"] = false; 528 response["keepalive"] = false;
555 response["reusecontext"] = false; 529 response["reusecontext"] = false;
556 530 return response;
557 //remove from map 531 }
532 //put response
533 response["int_response_code"] = requestData.responseCode;
534 response["str_response_string"] = requestData.responseBody;
535 response["content_type"] = "text/plain";
536 response["keepalive"] = false;
537 response["reusecontext"] = false;
538
539 //remove from map
540 lock (url.requests)
541 {
558 url.requests.Remove(requestID); 542 url.requests.Remove(requestID);
543 }
544 lock (m_RequestMap)
545 {
559 m_RequestMap.Remove(requestID); 546 m_RequestMap.Remove(requestID);
560 } 547 }
561 548
@@ -564,41 +551,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
564 551
565 public void HttpRequestHandler(UUID requestID, Hashtable request) 552 public void HttpRequestHandler(UUID requestID, Hashtable request)
566 { 553 {
567 string uri = request["uri"].ToString(); 554 lock (request)
568 bool is_ssl = uri.Contains("lslhttps");
569
570 try
571 { 555 {
572 Hashtable headers = (Hashtable)request["headers"]; 556 string uri = request["uri"].ToString();
573 557 bool is_ssl = uri.Contains("lslhttps");
574// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
575 558
576 int pos1 = uri.IndexOf("/");// /lslhttp 559 try
577 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
578 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
579 string uri_tmp = uri.Substring(0, pos3 + 1);
580 //HTTP server code doesn't provide us with QueryStrings
581 string pathInfo;
582 string queryString;
583 queryString = "";
584
585 pathInfo = uri.Substring(pos3);
586
587 UrlData urlData = null;
588
589 lock (m_UrlMap)
590 { 560 {
591 string url; 561 Hashtable headers = (Hashtable)request["headers"];
592 562
593 if (is_ssl) 563// string uri_full = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
594 url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 564
565 int pos1 = uri.IndexOf("/");// /lslhttp
566 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
567 int pos3 = pos2 + 37; // /lslhttp/urlcode
568 string uri_tmp = uri.Substring(0, pos3);
569 //HTTP server code doesn't provide us with QueryStrings
570 string pathInfo;
571 string queryString;
572 queryString = "";
573
574 pathInfo = uri.Substring(pos3);
575
576 UrlData url = null;
577 string urlkey;
578 if (!is_ssl)
579 urlkey = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
580 //m_UrlMap[];
595 else 581 else
596 url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 582 urlkey = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
597 583
598 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 584 if (m_UrlMap.ContainsKey(urlkey))
599 // request was being processed. 585 {
600 if (!m_UrlMap.TryGetValue(url, out urlData)) 586 url = m_UrlMap[urlkey];
587 }
588 else
589 {
590 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
601 return; 591 return;
592 }
602 593
603 //for llGetHttpHeader support we need to store original URI here 594 //for llGetHttpHeader support we need to store original URI here
604 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 595 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -618,7 +609,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
618 string value = (string)header.Value; 609 string value = (string)header.Value;
619 requestData.headers.Add(key, value); 610 requestData.headers.Add(key, value);
620 } 611 }
621
622 foreach (DictionaryEntry de in request) 612 foreach (DictionaryEntry de in request)
623 { 613 {
624 if (de.Key.ToString() == "querystringkeys") 614 if (de.Key.ToString() == "querystringkeys")
@@ -629,13 +619,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
629 if (request.ContainsKey(key)) 619 if (request.ContainsKey(key))
630 { 620 {
631 string val = (String)request[key]; 621 string val = (String)request[key];
632 queryString = queryString + key + "=" + val + "&"; 622 if (key != "")
623 {
624 queryString = queryString + key + "=" + val + "&";
625 }
626 else
627 {
628 queryString = queryString + val + "&";
629 }
633 } 630 }
634 } 631 }
635
636 if (queryString.Length > 1) 632 if (queryString.Length > 1)
637 queryString = queryString.Substring(0, queryString.Length - 1); 633 queryString = queryString.Substring(0, queryString.Length - 1);
634
638 } 635 }
636
639 } 637 }
640 638
641 //if this machine is behind DNAT/port forwarding, currently this is being 639 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -643,23 +641,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
643 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 641 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
644 requestData.headers["x-path-info"] = pathInfo; 642 requestData.headers["x-path-info"] = pathInfo;
645 requestData.headers["x-query-string"] = queryString; 643 requestData.headers["x-query-string"] = queryString;
646 requestData.headers["x-script-url"] = urlData.url; 644 requestData.headers["x-script-url"] = url.url;
647 645
648 urlData.requests.Add(requestID, requestData); 646 //requestData.ev = new ManualResetEvent(false);
649 m_RequestMap.Add(requestID, urlData); 647 lock (url.requests)
650 } 648 {
649 url.requests.Add(requestID, requestData);
650 }
651 lock (m_RequestMap)
652 {
653 //add to request map
654 m_RequestMap.Add(requestID, url);
655 }
651 656
652 urlData.engine.PostScriptEvent( 657 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
653 urlData.itemID, 658
654 "http_request", 659 //send initial response?
655 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 660// Hashtable response = new Hashtable();
656 } 661
657 catch (Exception we) 662 return;
658 { 663
659 //Hashtable response = new Hashtable(); 664 }
660 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 665 catch (Exception we)
661 m_log.Warn(we.Message); 666 {
662 m_log.Warn(we.StackTrace); 667 //Hashtable response = new Hashtable();
668 m_log.Warn("[HttpRequestHandler]: http-in request failed");
669 m_log.Warn(we.Message);
670 m_log.Warn(we.StackTrace);
671 }
663 } 672 }
664 } 673 }
665 674
@@ -668,4 +677,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
668 ScriptRemoved(itemID); 677 ScriptRemoved(itemID);
669 } 678 }
670 } 679 }
671} \ No newline at end of file 680}
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 6bf50d2..fccf053 100644
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -262,6 +262,8 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
262 return "modInvokeR"; 262 return "modInvokeR";
263 else if (sid.ReturnType == typeof(object[])) 263 else if (sid.ReturnType == typeof(object[]))
264 return "modInvokeL"; 264 return "modInvokeL";
265 else if (sid.ReturnType == typeof(void))
266 return "modInvokeN";
265 267
266 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name); 268 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
267 } 269 }
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 a413546..8b8bb37 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -306,6 +306,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
306 return false; 306 return false;
307 } 307 }
308 308
309 public bool CloseChildAgent(GridRegion destination, UUID id)
310 {
311 return CloseAgent(destination, id);
312 }
313
309 public bool CloseAgent(GridRegion destination, UUID id) 314 public bool CloseAgent(GridRegion destination, UUID id)
310 { 315 {
311 if (destination == null) 316 if (destination == null)
@@ -320,7 +325,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
320 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); 325 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
321 return true; 326 return true;
322 } 327 }
323
324 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 328 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
325 return false; 329 return false;
326 } 330 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index b2a1b23..c8698ca 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -262,6 +262,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
262 return false; 262 return false;
263 } 263 }
264 264
265 public bool CloseChildAgent(GridRegion destination, UUID id)
266 {
267 if (destination == null)
268 return false;
269
270 // Try local first
271 if (m_localBackend.CloseChildAgent(destination, id))
272 return true;
273
274 // else do the remote thing
275 if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
276 return m_remoteConnector.CloseChildAgent(destination, id);
277
278 return false;
279 }
265 280
266 public bool CloseAgent(GridRegion destination, UUID id) 281 public bool CloseAgent(GridRegion destination, UUID id)
267 { 282 {
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 60f6739..a5f5749 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -32,6 +32,7 @@ using System.IO;
32using System.Linq; 32using System.Linq;
33using System.Reflection; 33using System.Reflection;
34using System.Security; 34using System.Security;
35using System.Timers;
35using log4net; 36using log4net;
36using Mono.Addins; 37using Mono.Addins;
37using Nini.Config; 38using Nini.Config;
@@ -48,6 +49,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
48 { 49 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 51
52 private Timer m_regionChangeTimer = new Timer();
51 public Scene Scene { get; private set; } 53 public Scene Scene { get; private set; }
52 public IUserManagement UserManager { get; private set; } 54 public IUserManagement UserManager { get; private set; }
53 55
@@ -65,6 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
65 public event ChangeDelegate OnEstateInfoChange; 67 public event ChangeDelegate OnEstateInfoChange;
66 public event MessageDelegate OnEstateMessage; 68 public event MessageDelegate OnEstateMessage;
67 69
70 private int m_delayCount = 0;
71
68 #region Region Module interface 72 #region Region Module interface
69 73
70 public string Name { get { return "EstateManagementModule"; } } 74 public string Name { get { return "EstateManagementModule"; } }
@@ -114,6 +118,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
114 118
115 #region Packet Data Responders 119 #region Packet Data Responders
116 120
121 private void clientSendDetailedEstateData(IClientAPI remote_client, UUID invoice)
122 {
123 sendDetailedEstateData(remote_client, invoice);
124 sendEstateLists(remote_client, invoice);
125 }
126
117 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) 127 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice)
118 { 128 {
119 uint sun = 0; 129 uint sun = 0;
@@ -136,7 +146,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
136 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime, 146 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime,
137 Scene.RegionInfo.EstateSettings.AbuseEmail, 147 Scene.RegionInfo.EstateSettings.AbuseEmail,
138 estateOwner); 148 estateOwner);
149 }
139 150
151 private void sendEstateLists(IClientAPI remote_client, UUID invoice)
152 {
140 remote_client.SendEstateList(invoice, 153 remote_client.SendEstateList(invoice,
141 (int)Constants.EstateAccessCodex.EstateManagers, 154 (int)Constants.EstateAccessCodex.EstateManagers,
142 Scene.RegionInfo.EstateSettings.EstateManagers, 155 Scene.RegionInfo.EstateSettings.EstateManagers,
@@ -318,6 +331,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
318 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 331 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
319 if (restartModule != null) 332 if (restartModule != null)
320 { 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
321 List<int> times = new List<int>(); 344 List<int> times = new List<int>();
322 while (timeInSeconds > 0) 345 while (timeInSeconds > 0)
323 { 346 {
@@ -330,7 +353,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
330 timeInSeconds -= 15; 353 timeInSeconds -= 15;
331 } 354 }
332 355
333 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); 356 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false);
334 357
335 m_log.InfoFormat( 358 m_log.InfoFormat(
336 "User {0} requested restart of region {1} in {2} seconds", 359 "User {0} requested restart of region {1} in {2} seconds",
@@ -546,7 +569,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
546 { 569 {
547 if (!s.IsChildAgent) 570 if (!s.IsChildAgent)
548 { 571 {
549 Scene.TeleportClientHome(user, s.ControllingClient); 572 if (!Scene.TeleportClientHome(user, s.ControllingClient))
573 {
574 s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out.");
575 s.ControllingClient.Close();
576 }
550 } 577 }
551 } 578 }
552 579
@@ -555,7 +582,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
555 { 582 {
556 remote_client.SendAlertMessage("User is already on the region ban list"); 583 remote_client.SendAlertMessage("User is already on the region ban list");
557 } 584 }
558 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 585 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
559 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 586 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
560 } 587 }
561 else 588 else
@@ -611,7 +638,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
611 remote_client.SendAlertMessage("User is not on the region ban list"); 638 remote_client.SendAlertMessage("User is not on the region ban list");
612 } 639 }
613 640
614 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 641 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
615 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 642 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
616 } 643 }
617 else 644 else
@@ -777,7 +804,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
777 ScenePresence s = Scene.GetScenePresence(prey); 804 ScenePresence s = Scene.GetScenePresence(prey);
778 if (s != null) 805 if (s != null)
779 { 806 {
780 Scene.TeleportClientHome(prey, s.ControllingClient); 807 if (!Scene.TeleportClientHome(prey, s.ControllingClient))
808 {
809 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
810 s.ControllingClient.Close();
811 }
781 } 812 }
782 } 813 }
783 } 814 }
@@ -795,7 +826,13 @@ namespace OpenSim.Region.CoreModules.World.Estate
795 // Also make sure they are actually in the region 826 // Also make sure they are actually in the region
796 ScenePresence p; 827 ScenePresence p;
797 if(Scene.TryGetScenePresence(client.AgentId, out p)) 828 if(Scene.TryGetScenePresence(client.AgentId, out p))
798 Scene.TeleportClientHome(p.UUID, p.ControllingClient); 829 {
830 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
831 {
832 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
833 p.ControllingClient.Close();
834 }
835 }
799 } 836 }
800 }); 837 });
801 } 838 }
@@ -1170,7 +1207,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1170 1207
1171 private void EventManager_OnNewClient(IClientAPI client) 1208 private void EventManager_OnNewClient(IClientAPI client)
1172 { 1209 {
1173 client.OnDetailedEstateDataRequest += sendDetailedEstateData; 1210 client.OnDetailedEstateDataRequest += clientSendDetailedEstateData;
1174 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler; 1211 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler;
1175// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture; 1212// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture;
1176 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture; 1213 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture;
@@ -1222,6 +1259,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1222 flags |= RegionFlags.AllowParcelChanges; 1259 flags |= RegionFlags.AllowParcelChanges;
1223 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1260 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1224 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);
1225 1266
1226 if (Scene.RegionInfo.RegionSettings.FixedSun) 1267 if (Scene.RegionInfo.RegionSettings.FixedSun)
1227 flags |= RegionFlags.SunFixed; 1268 flags |= RegionFlags.SunFixed;
@@ -1229,11 +1270,15 @@ namespace OpenSim.Region.CoreModules.World.Estate
1229 flags |= RegionFlags.Sandbox; 1270 flags |= RegionFlags.Sandbox;
1230 if (Scene.RegionInfo.EstateSettings.AllowVoice) 1271 if (Scene.RegionInfo.EstateSettings.AllowVoice)
1231 flags |= RegionFlags.AllowVoice; 1272 flags |= RegionFlags.AllowVoice;
1273 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1274 flags |= RegionFlags.AllowLandmark;
1275 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1276 flags |= RegionFlags.AllowSetHome;
1277 if (Scene.RegionInfo.EstateSettings.BlockDwell)
1278 flags |= RegionFlags.BlockDwell;
1279 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
1280 flags |= RegionFlags.ResetHomeOnTeleport;
1232 1281
1233 // Fudge these to always on, so the menu options activate
1234 //
1235 flags |= RegionFlags.AllowLandmark;
1236 flags |= RegionFlags.AllowSetHome;
1237 1282
1238 // TODO: SkipUpdateInterestList 1283 // TODO: SkipUpdateInterestList
1239 1284
@@ -1274,6 +1319,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1274 flags |= RegionFlags.ResetHomeOnTeleport; 1319 flags |= RegionFlags.ResetHomeOnTeleport;
1275 if (Scene.RegionInfo.EstateSettings.TaxFree) 1320 if (Scene.RegionInfo.EstateSettings.TaxFree)
1276 flags |= RegionFlags.TaxFree; 1321 flags |= RegionFlags.TaxFree;
1322 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1323 flags |= RegionFlags.AllowLandmark;
1324 if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
1325 flags |= RegionFlags.AllowParcelChanges;
1326 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1327 flags |= RegionFlags.AllowSetHome;
1277 if (Scene.RegionInfo.EstateSettings.DenyMinors) 1328 if (Scene.RegionInfo.EstateSettings.DenyMinors)
1278 flags |= (RegionFlags)(1 << 30); 1329 flags |= (RegionFlags)(1 << 30);
1279 1330
@@ -1294,6 +1345,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1294 1345
1295 public void TriggerRegionInfoChange() 1346 public void TriggerRegionInfoChange()
1296 { 1347 {
1348 m_regionChangeTimer.Stop();
1349 m_regionChangeTimer.Start();
1350 }
1351
1352 protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e)
1353 {
1297 ChangeDelegate change = OnRegionInfoChange; 1354 ChangeDelegate change = OnRegionInfoChange;
1298 1355
1299 if (change != null) 1356 if (change != null)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index dbf5138..b4f7d51 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -88,19 +88,21 @@ namespace OpenSim.Region.CoreModules.World.Land
88 /// <value> 88 /// <value>
89 /// Land objects keyed by local id 89 /// Land objects keyed by local id
90 /// </value> 90 /// </value>
91 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 91// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
92
93 //ubit: removed the readonly so i can move it around
94 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
92 95
93 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 96 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
94 97
95 private bool m_allowedForcefulBans = true; 98 private bool m_allowedForcefulBans = true;
99 private UUID DefaultGodParcelGroup;
100 private string DefaultGodParcelName;
96 101
97 // caches ExtendedLandData 102 // caches ExtendedLandData
98 private Cache parcelInfoCache; 103 private Cache parcelInfoCache;
99 104 private Dictionary<UUID, Vector3> forcedPosition =
100 /// <summary> 105 new Dictionary<UUID, Vector3>();
101 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
102 /// </summary>
103 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
104 106
105 #region INonSharedRegionModule Members 107 #region INonSharedRegionModule Members
106 108
@@ -111,6 +113,12 @@ namespace OpenSim.Region.CoreModules.World.Land
111 113
112 public void Initialise(IConfigSource source) 114 public void Initialise(IConfigSource source)
113 { 115 {
116 IConfig cnf = source.Configs["LandManagement"];
117 if (cnf != null)
118 {
119 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
120 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
121 }
114 } 122 }
115 123
116 public void AddRegion(Scene scene) 124 public void AddRegion(Scene scene)
@@ -163,13 +171,6 @@ namespace OpenSim.Region.CoreModules.World.Land
163 m_scene.UnregisterModuleCommander(m_commander.Name); 171 m_scene.UnregisterModuleCommander(m_commander.Name);
164 } 172 }
165 173
166// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
167// {
168// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
169// reason = "You are not allowed to enter this sim.";
170// return nearestParcel != null;
171// }
172
173 /// <summary> 174 /// <summary>
174 /// Processes commandline input. Do not call directly. 175 /// Processes commandline input. Do not call directly.
175 /// </summary> 176 /// </summary>
@@ -210,6 +211,8 @@ namespace OpenSim.Region.CoreModules.World.Land
210 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 211 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
211 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 212 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
212 client.OnPreAgentUpdate += ClientOnPreAgentUpdate; 213 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
214 client.OnParcelEjectUser += ClientOnParcelEjectUser;
215 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
213 216
214 EntityBase presenceEntity; 217 EntityBase presenceEntity;
215 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 218 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -226,48 +229,6 @@ namespace OpenSim.Region.CoreModules.World.Land
226 229
227 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 230 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
228 { 231 {
229 //If we are forcing a position for them to go
230 if (forcedPosition.ContainsKey(remoteClient.AgentId))
231 {
232 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
233
234 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
235 //When the avatar walks into a ban line on the ground, it prevents getting stuck
236 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
237
238 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
239 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
240 {
241// m_log.DebugFormat(
242// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
243// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
244
245 forcedPosition.Remove(remoteClient.AgentId);
246 }
247 //if we are far away, teleport
248 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
249 {
250 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
251// m_log.DebugFormat(
252// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
253// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
254
255 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
256 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
257
258 forcedPosition.Remove(remoteClient.AgentId);
259 }
260 else
261 {
262// m_log.DebugFormat(
263// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
264// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
265
266 //Forces them toward the forced position we want if they aren't there yet
267 agentData.UseClientAgentPosition = true;
268 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
269 }
270 }
271 } 232 }
272 233
273 public void Close() 234 public void Close()
@@ -292,6 +253,7 @@ namespace OpenSim.Region.CoreModules.World.Land
292 { 253 {
293 LandData newData = data.Copy(); 254 LandData newData = data.Copy();
294 newData.LocalID = local_id; 255 newData.LocalID = local_id;
256 ILandObject landobj = null;
295 257
296 ILandObject land; 258 ILandObject land;
297 lock (m_landList) 259 lock (m_landList)
@@ -331,14 +293,14 @@ namespace OpenSim.Region.CoreModules.World.Land
331 protected ILandObject CreateDefaultParcel() 293 protected ILandObject CreateDefaultParcel()
332 { 294 {
333 m_log.DebugFormat( 295 m_log.DebugFormat(
334 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 296 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
335 297
336 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 298 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
337 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 299 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
338 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 300 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
339 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 301 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
340 302
341 return AddLandObject(fullSimParcel); 303 return AddLandObject(fullSimParcel);
342 } 304 }
343 305
344 public List<ILandObject> AllParcels() 306 public List<ILandObject> AllParcels()
@@ -387,10 +349,16 @@ namespace OpenSim.Region.CoreModules.World.Land
387 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 349 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
388 { 350 {
389 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 351 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
390 if (position.HasValue) 352
391 { 353 if (!position.HasValue)
392 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 354 return;
393 } 355
356 bool isFlying = avatar.PhysicsActor.Flying;
357 avatar.RemoveFromPhysicalScene();
358
359 avatar.AbsolutePosition = (Vector3)position;
360
361 avatar.AddToPhysicalScene(isFlying);
394 } 362 }
395 363
396 public void SendYouAreRestrictedNotice(ScenePresence avatar) 364 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -410,29 +378,7 @@ namespace OpenSim.Region.CoreModules.World.Land
410 } 378 }
411 379
412 if (parcelAvatarIsEntering != null) 380 if (parcelAvatarIsEntering != null)
413 { 381 EnforceBans(parcelAvatarIsEntering, avatar);
414 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
415 {
416 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
417 {
418 SendYouAreBannedNotice(avatar);
419 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
420 }
421 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
422 {
423 SendYouAreRestrictedNotice(avatar);
424 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
425 }
426 else
427 {
428 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
429 }
430 }
431 else
432 {
433 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
434 }
435 }
436 } 382 }
437 } 383 }
438 384
@@ -461,30 +407,51 @@ namespace OpenSim.Region.CoreModules.World.Land
461 407
462 public void SendLandUpdate(ScenePresence avatar, bool force) 408 public void SendLandUpdate(ScenePresence avatar, bool force)
463 { 409 {
410
411 /* stop sendind same data twice
412 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
413 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
414
415 if (over != null)
416 {
417
418 if (force)
419 {
420 if (!avatar.IsChildAgent)
421 {
422 over.SendLandUpdateToClient(avatar.ControllingClient);
423 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
424 m_scene.RegionInfo.RegionID);
425 }
426 }
427
428 if (avatar.currentParcelUUID != over.LandData.GlobalID)
429 {
430 if (!avatar.IsChildAgent)
431 {
432 over.SendLandUpdateToClient(avatar.ControllingClient);
433 avatar.currentParcelUUID = over.LandData.GlobalID;
434 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
435 m_scene.RegionInfo.RegionID);
436 }
437 }
438 */
439 if (avatar.IsChildAgent)
440 return;
441
464 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 442 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
465 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 443 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
466 444
467 if (over != null) 445 if (over != null)
468 { 446 {
469 if (force) 447 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
448 if (force || NotsameID)
470 { 449 {
471 if (!avatar.IsChildAgent) 450 over.SendLandUpdateToClient(avatar.ControllingClient);
472 { 451 if (NotsameID)
473 over.SendLandUpdateToClient(avatar.ControllingClient);
474 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
475 m_scene.RegionInfo.RegionID);
476 }
477 }
478
479 if (avatar.currentParcelUUID != over.LandData.GlobalID)
480 {
481 if (!avatar.IsChildAgent)
482 {
483 over.SendLandUpdateToClient(avatar.ControllingClient);
484 avatar.currentParcelUUID = over.LandData.GlobalID; 452 avatar.currentParcelUUID = over.LandData.GlobalID;
485 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 453 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
486 m_scene.RegionInfo.RegionID); 454 m_scene.RegionInfo.RegionID);
487 }
488 } 455 }
489 } 456 }
490 } 457 }
@@ -536,6 +503,7 @@ namespace OpenSim.Region.CoreModules.World.Land
536 //when we are finally in a safe place, lets release the forced position lock 503 //when we are finally in a safe place, lets release the forced position lock
537 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 504 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
538 } 505 }
506 EnforceBans(parcel, clientAvatar);
539 } 507 }
540 } 508 }
541 509
@@ -686,27 +654,28 @@ namespace OpenSim.Region.CoreModules.World.Land
686 /// </summary> 654 /// </summary>
687 public void Clear(bool setupDefaultParcel) 655 public void Clear(bool setupDefaultParcel)
688 { 656 {
689 List<ILandObject> parcels; 657 Dictionary<int, ILandObject> landworkList;
658 // move to work pointer since we are deleting it all
690 lock (m_landList) 659 lock (m_landList)
691 { 660 {
692 parcels = new List<ILandObject>(m_landList.Values); 661 landworkList = m_landList;
662 m_landList = new Dictionary<int, ILandObject>();
693 } 663 }
694 664
695 foreach (ILandObject lo in parcels) 665 // this 2 methods have locks (now)
666 ResetSimLandObjects();
667
668 if (setupDefaultParcel)
669 CreateDefaultParcel();
670
671 // fire outside events unlocked
672 foreach (ILandObject lo in landworkList.Values)
696 { 673 {
697 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 674 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
698 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); 675 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
699 } 676 }
677 landworkList.Clear();
700 678
701 lock (m_landList)
702 {
703 m_landList.Clear();
704
705 ResetSimLandObjects();
706 }
707
708 if (setupDefaultParcel)
709 CreateDefaultParcel();
710 } 679 }
711 680
712 private void performFinalLandJoin(ILandObject master, ILandObject slave) 681 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -753,7 +722,7 @@ namespace OpenSim.Region.CoreModules.World.Land
753 int x; 722 int x;
754 int y; 723 int y;
755 724
756 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 725 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
757 return null; 726 return null;
758 727
759 try 728 try
@@ -803,14 +772,13 @@ namespace OpenSim.Region.CoreModules.World.Land
803 { 772 {
804 try 773 try
805 { 774 {
806 return m_landList[m_landIDList[x / 4, y / 4]]; 775 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
776 return m_landList[m_landIDList[x / 4, y / 4]];
777 //else
778 // return null;
807 } 779 }
808 catch (IndexOutOfRangeException) 780 catch (IndexOutOfRangeException)
809 { 781 {
810// m_log.WarnFormat(
811// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
812// x, y, m_scene.RegionInfo.RegionName);
813
814 return null; 782 return null;
815 } 783 }
816 } 784 }
@@ -1094,6 +1062,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1094 //Owner Flag 1062 //Owner Flag
1095 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1063 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1096 } 1064 }
1065 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1066 {
1067 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1068 }
1097 else if (currentParcelBlock.LandData.SalePrice > 0 && 1069 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1098 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1070 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1099 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1071 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1174,8 +1146,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1174 { 1146 {
1175 if (!temp.Contains(currentParcel)) 1147 if (!temp.Contains(currentParcel))
1176 { 1148 {
1177 currentParcel.ForceUpdateLandInfo(); 1149 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1178 temp.Add(currentParcel); 1150 {
1151 currentParcel.ForceUpdateLandInfo();
1152 temp.Add(currentParcel);
1153 }
1179 } 1154 }
1180 } 1155 }
1181 } 1156 }
@@ -1394,8 +1369,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1394 1369
1395 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1370 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1396 { 1371 {
1397// m_log.DebugFormat( 1372 Dictionary<int, ILandObject> landworkList;
1398// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); 1373 // move to work pointer since we are deleting it all
1374 lock (m_landList)
1375 {
1376 landworkList = m_landList;
1377 m_landList = new Dictionary<int, ILandObject>();
1378 }
1379
1380 //Remove all the land objects in the sim and then process our new data
1381 foreach (int n in landworkList.Keys)
1382 {
1383 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1384 }
1385 landworkList.Clear();
1386
1387 lock (m_landList)
1388 {
1389 m_landIDList.Initialize();
1390 m_landList.Clear();
1391 }
1399 1392
1400 for (int i = 0; i < data.Count; i++) 1393 for (int i = 0; i < data.Count; i++)
1401 IncomingLandObjectFromStorage(data[i]); 1394 IncomingLandObjectFromStorage(data[i]);
@@ -1403,10 +1396,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1403 1396
1404 public void IncomingLandObjectFromStorage(LandData data) 1397 public void IncomingLandObjectFromStorage(LandData data)
1405 { 1398 {
1399
1406 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1400 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1407 new_land.LandData = data.Copy(); 1401 new_land.LandData = data.Copy();
1408 new_land.SetLandBitmapFromByteArray(); 1402 new_land.SetLandBitmapFromByteArray();
1409 AddLandObject(new_land); 1403 AddLandObject(new_land);
1404 new_land.SendLandUpdateToAvatarsOverMe();
1410 } 1405 }
1411 1406
1412 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1407 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1737,6 +1732,168 @@ namespace OpenSim.Region.CoreModules.World.Land
1737 1732
1738 UpdateLandObject(localID, land.LandData); 1733 UpdateLandObject(localID, land.LandData);
1739 } 1734 }
1735
1736 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1737 {
1738 ILandObject land = null;
1739 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1740 foreach (ILandObject landObject in Land)
1741 {
1742 if (landObject.LandData.LocalID == landID)
1743 {
1744 land = landObject;
1745 }
1746 }
1747 land.DeedToGroup(DefaultGodParcelGroup);
1748 land.LandData.Name = DefaultGodParcelName;
1749 land.SendLandUpdateToAvatarsOverMe();
1750 }
1751
1752 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1753 {
1754 ScenePresence SP;
1755 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1756 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1757 if (SP.UserLevel != 0)
1758 {
1759 if (flags == 0) //All parcels, scripted or not
1760 {
1761 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1762 {
1763 if (e.OwnerID == targetID)
1764 {
1765 returns.Add(e);
1766 }
1767 }
1768 );
1769 }
1770 if (flags == 4) //All parcels, scripted object
1771 {
1772 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1773 {
1774 if (e.OwnerID == targetID)
1775 {
1776 if (e.ContainsScripts())
1777 {
1778 returns.Add(e);
1779 }
1780 }
1781 }
1782 );
1783 }
1784 if (flags == 4) //not target parcel, scripted object
1785 {
1786 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1787 {
1788 if (e.OwnerID == targetID)
1789 {
1790 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1791 if (landobject.LandData.OwnerID != e.OwnerID)
1792 {
1793 if (e.ContainsScripts())
1794 {
1795 returns.Add(e);
1796 }
1797 }
1798 }
1799 }
1800 );
1801 }
1802 foreach (SceneObjectGroup ol in returns)
1803 {
1804 ReturnObject(ol, client);
1805 }
1806 }
1807 }
1808 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1809 {
1810 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1811 objs[0] = obj;
1812 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1813 }
1814
1815 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1816
1817 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1818 {
1819 ScenePresence targetAvatar = null;
1820 ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar);
1821 ScenePresence parcelManager = null;
1822 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1823 System.Threading.Timer Timer;
1824
1825 if (targetAvatar.UserLevel == 0)
1826 {
1827 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1828 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze))
1829 return;
1830 if (flags == 0)
1831 {
1832 targetAvatar.AllowMovement = false;
1833 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
1834 parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen.");
1835 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
1836 Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0);
1837 Timers.Add(targetAvatar.UUID, Timer);
1838 }
1839 else
1840 {
1841 targetAvatar.AllowMovement = true;
1842 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you.");
1843 parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen.");
1844 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1845 Timers.Remove(targetAvatar.UUID);
1846 Timer.Dispose();
1847 }
1848 }
1849 }
1850 private void OnEndParcelFrozen(object avatar)
1851 {
1852 ScenePresence targetAvatar = (ScenePresence)avatar;
1853 targetAvatar.AllowMovement = true;
1854 System.Threading.Timer Timer;
1855 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1856 Timers.Remove(targetAvatar.UUID);
1857 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1858 }
1859
1860
1861 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1862 {
1863 ScenePresence targetAvatar = null;
1864 ScenePresence parcelManager = null;
1865
1866 // Must have presences
1867 if (!m_scene.TryGetScenePresence(target, out targetAvatar) ||
1868 !m_scene.TryGetScenePresence(client.AgentId, out parcelManager))
1869 return;
1870
1871 // Cannot eject estate managers or gods
1872 if (m_scene.Permissions.IsAdministrator(target))
1873 return;
1874
1875 // Check if you even have permission to do this
1876 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1877 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1878 !m_scene.Permissions.IsAdministrator(client.AgentId))
1879 return;
1880
1881 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1882
1883 targetAvatar.TeleportWithMomentum(pos, null);
1884 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1885 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1886
1887 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1888 {
1889 LandAccessEntry entry = new LandAccessEntry();
1890 entry.AgentID = targetAvatar.UUID;
1891 entry.Flags = AccessList.Ban;
1892 entry.Expires = 0; // Perm
1893
1894 land.LandData.ParcelAccessList.Add(entry);
1895 }
1896 }
1740 1897
1741 protected void InstallInterfaces() 1898 protected void InstallInterfaces()
1742 { 1899 {
@@ -1799,5 +1956,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1799 1956
1800 MainConsole.Instance.Output(report.ToString()); 1957 MainConsole.Instance.Output(report.ToString());
1801 } 1958 }
1959
1960 public void EnforceBans(ILandObject land, ScenePresence avatar)
1961 {
1962 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
1963 return;
1964
1965 if (land.IsEitherBannedOrRestricted(avatar.UUID))
1966 {
1967 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
1968 {
1969 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
1970 if (pos == null)
1971 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
1972 else
1973 ForceAvatarToPosition(avatar, (Vector3)pos);
1974 }
1975 else
1976 {
1977 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
1978 }
1979 }
1980 }
1802 } 1981 }
1803} 1982}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 5969d45..07d00c0 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 }
@@ -249,7 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Land
249 remote_client.SendLandProperties(seq_id, 270 remote_client.SendLandProperties(seq_id,
250 snap_selection, request_result, this, 271 snap_selection, request_result, this,
251 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 272 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
252 GetParcelMaxPrimCount(), 273 GetParcelBasePrimCount(),
253 GetSimulatorMaxPrimCount(), regionFlags); 274 GetSimulatorMaxPrimCount(), regionFlags);
254 } 275 }
255 276
@@ -309,7 +330,7 @@ namespace OpenSim.Region.CoreModules.World.Land
309 330
310 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 331 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
311 ParcelFlags.AllowPublish | 332 ParcelFlags.AllowPublish |
312 ParcelFlags.MaturePublish); 333 ParcelFlags.MaturePublish) | (uint)(1 << 23);
313 } 334 }
314 335
315 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 336 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity))
@@ -421,6 +442,19 @@ namespace OpenSim.Region.CoreModules.World.Land
421 return false; 442 return false;
422 } 443 }
423 444
445 public bool CanBeOnThisLand(UUID avatar, float posHeight)
446 {
447 if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
448 {
449 return false;
450 }
451 else if (IsRestrictedFromLand(avatar))
452 {
453 return false;
454 }
455 return true;
456 }
457
424 public bool HasGroupAccess(UUID avatar) 458 public bool HasGroupAccess(UUID avatar)
425 { 459 {
426 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) 460 if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
@@ -1185,6 +1219,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1185 1219
1186 #endregion 1220 #endregion
1187 1221
1222 private void OnFrame()
1223 {
1224 m_expiryCounter++;
1225
1226 if (m_expiryCounter >= 50)
1227 {
1228 ExpireAccessList();
1229 m_expiryCounter = 0;
1230 }
1231 }
1232
1188 private void ExpireAccessList() 1233 private void ExpireAccessList()
1189 { 1234 {
1190 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1235 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1195,7 +1240,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1195 delete.Add(entry); 1240 delete.Add(entry);
1196 } 1241 }
1197 foreach (LandAccessEntry entry in delete) 1242 foreach (LandAccessEntry entry in delete)
1243 {
1198 LandData.ParcelAccessList.Remove(entry); 1244 LandData.ParcelAccessList.Remove(entry);
1245 ScenePresence presence;
1246
1247 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1248 {
1249 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1250 if (land.LandData.LocalID == LandData.LocalID)
1251 {
1252 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1253 presence.TeleportWithMomentum(pos, null);
1254 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1255 }
1256 }
1257 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1258 }
1199 1259
1200 if (delete.Count > 0) 1260 if (delete.Count > 0)
1201 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1261 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 4e20196..6f92ef6 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 249a40d..9c441ed 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;
@@ -212,7 +232,25 @@ namespace OpenSim.Region.CoreModules.World.Region
212 232
213 private void OnTimer(object source, ElapsedEventArgs e) 233 private void OnTimer(object source, ElapsedEventArgs e)
214 { 234 {
215 int nextInterval = DoOneNotice(); 235 int nextInterval = DoOneNotice(true);
236
237 SetTimer(nextInterval);
238 }
239
240 public void DelayRestart(int seconds, string message)
241 {
242 if (m_CountdownTimer == null)
243 return;
244
245 m_CountdownTimer.Stop();
246 m_CountdownTimer = null;
247
248 m_Alerts = new List<int>(m_CurrentAlerts);
249 m_Alerts.Add(seconds);
250 m_Alerts.Sort();
251 m_Alerts.Reverse();
252
253 int nextInterval = DoOneNotice(false);
216 254
217 SetTimer(nextInterval); 255 SetTimer(nextInterval);
218 } 256 }
@@ -226,6 +264,9 @@ namespace OpenSim.Region.CoreModules.World.Region
226 if (m_DialogModule != null && message != String.Empty) 264 if (m_DialogModule != null && message != String.Empty)
227 m_DialogModule.SendGeneralAlert(message); 265 m_DialogModule.SendGeneralAlert(message);
228 } 266 }
267 if (m_MarkerPath != String.Empty)
268 File.Delete(Path.Combine(m_MarkerPath,
269 m_Scene.RegionInfo.RegionID.ToString()));
229 } 270 }
230 271
231 private void HandleRegionRestart(string module, string[] args) 272 private void HandleRegionRestart(string module, string[] args)
@@ -270,5 +311,25 @@ namespace OpenSim.Region.CoreModules.World.Region
270 311
271 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 312 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
272 } 313 }
314
315 protected void CreateMarkerFile()
316 {
317 if (m_MarkerPath == String.Empty)
318 return;
319
320 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
321 try
322 {
323 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
324 FileStream fs = File.Create(path);
325 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
326 Byte[] buf = enc.GetBytes(pidstring);
327 fs.Write(buf, 0, buf.Length);
328 fs.Close();
329 }
330 catch (Exception)
331 {
332 }
333 }
273 } 334 }
274} \ No newline at end of file 335} \ No newline at end of file
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..4c96a50 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 c50ab64..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,7 +78,6 @@ 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>();
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
91 if (Util.GetConfigVarFromSections<string>( 94 if (Util.GetConfigVarFromSections<string>(
92 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap") 95 config, "WorldMapModule", configSections, "WorldMap") == "WorldMap")
93 m_Enabled = true; 96 m_Enabled = true;
94 97
95 blacklistTimeout 98 blacklistTimeout
96 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000; 99 = Util.GetConfigVarFromSections<int>(config, "BlacklistTimeout", configSections, 10 * 60) * 1000;
97 } 100 }
@@ -234,54 +237,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
234 // 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
235 // 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.
236 239
237 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 240 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
238 { 241 //{
239 ScenePresence avatarPresence = null; 242 // ScenePresence avatarPresence = null;
240 243
241 m_scene.TryGetScenePresence(agentID, out avatarPresence); 244 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
242 245
243 if (avatarPresence != null) 246 // if (avatarPresence != null)
244 { 247 // {
245 bool lookup = false; 248 // bool lookup = false;
246 249
247 lock (cachedMapBlocks) 250 // lock (cachedMapBlocks)
248 { 251 // {
249 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 252 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
250 { 253 // {
251 List<MapBlockData> mapBlocks; 254 // List<MapBlockData> mapBlocks;
252 255
253 mapBlocks = cachedMapBlocks; 256 // mapBlocks = cachedMapBlocks;
254 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 257 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
255 } 258 // }
256 else 259 // else
257 { 260 // {
258 lookup = true; 261 // lookup = true;
259 } 262 // }
260 } 263 // }
261 if (lookup) 264 // if (lookup)
262 { 265 // {
263 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 266 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
264 267
265 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 268 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
266 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 269 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
267 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 270 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
268 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 271 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
269 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 272 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
270 foreach (GridRegion r in regions) 273 // foreach (GridRegion r in regions)
271 { 274 // {
272 MapBlockData block = new MapBlockData(); 275 // MapBlockData block = new MapBlockData();
273 MapBlockFromGridRegion(block, r, 0); 276 // MapBlockFromGridRegion(block, r, 0);
274 mapBlocks.Add(block); 277 // mapBlocks.Add(block);
275 } 278 // }
276 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 279 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
277 280
278 lock (cachedMapBlocks) 281 // lock (cachedMapBlocks)
279 cachedMapBlocks = mapBlocks; 282 // cachedMapBlocks = mapBlocks;
280 283
281 cachedTime = Util.UnixTimeSinceEpoch(); 284 // cachedTime = Util.UnixTimeSinceEpoch();
282 } 285 // }
283 } 286 // }
284 } 287 //}
285 288
286 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 289 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
287 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 290 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -308,8 +311,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
308 protected static OSDMapLayer GetOSDMapLayerResponse() 311 protected static OSDMapLayer GetOSDMapLayerResponse()
309 { 312 {
310 OSDMapLayer mapLayer = new OSDMapLayer(); 313 OSDMapLayer mapLayer = new OSDMapLayer();
311 mapLayer.Right = 5000; 314 mapLayer.Right = 2048;
312 mapLayer.Top = 5000; 315 mapLayer.Top = 2048;
313 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 316 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
314 317
315 return mapLayer; 318 return mapLayer;
@@ -338,6 +341,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
338 { 341 {
339 m_rootAgents.Remove(AgentId); 342 m_rootAgents.Remove(AgentId);
340 } 343 }
344 lock (m_mapBlockRequestEvent)
345 {
346 if (m_mapBlockRequests.ContainsKey(AgentId))
347 m_mapBlockRequests.Remove(AgentId);
348 }
341 } 349 }
342 #endregion 350 #endregion
343 351
@@ -360,6 +368,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
360 ThreadPriority.BelowNormal, 368 ThreadPriority.BelowNormal,
361 true, 369 true,
362 true); 370 true);
371 Watchdog.StartThread(
372 MapBlockSendThread,
373 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
374 ThreadPriority.BelowNormal,
375 true,
376 true);
363 } 377 }
364 378
365 /// <summary> 379 /// <summary>
@@ -375,7 +389,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
375 st.itemtype=0; 389 st.itemtype=0;
376 st.regionhandle=0; 390 st.regionhandle=0;
377 391
378 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 }
379 } 413 }
380 414
381 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 415 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -531,7 +565,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
531 { 565 {
532 while (true) 566 while (true)
533 { 567 {
534 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;
535 583
536 // end gracefully 584 // end gracefully
537 if (st.agentID == STOP_UUID) 585 if (st.agentID == STOP_UUID)
@@ -549,13 +597,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
549 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 597 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
550 { 598 {
551 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 599 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
552 Thread.Sleep(80); 600 Thread.Sleep(100);
553 601
554 RequestMapItemsDelegate d = RequestMapItemsAsync;
555 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
556 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
557 //RequestMapItemsCompleted(response);
558 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 });
559 } 607 }
560 } 608 }
561 609
@@ -577,110 +625,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
577 /// <param name="state"></param> 625 /// <param name="state"></param>
578 public void EnqueueMapItemRequest(MapRequestState state) 626 public void EnqueueMapItemRequest(MapRequestState state)
579 { 627 {
580 requests.Enqueue(state); 628 lock (requests)
581 }
582
583 /// <summary>
584 /// Sends the mapitem response to the IClientAPI
585 /// </summary>
586 /// <param name="response">The OSDMap Response for the mapitem</param>
587 private void RequestMapItemsCompleted(IAsyncResult iar)
588 {
589 AsyncResult result = (AsyncResult)iar;
590 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
591
592 OSDMap response = (OSDMap)icon.EndInvoke(iar);
593
594 Interlocked.Decrement(ref nAsyncRequests);
595
596 if (!response.ContainsKey("requestID"))
597 return;
598
599 UUID requestID = response["requestID"].AsUUID();
600
601 if (requestID != UUID.Zero)
602 { 629 {
603 MapRequestState mrs = new MapRequestState(); 630 queueEvent.Set();
604 mrs.agentID = UUID.Zero; 631 requests.Enqueue(state);
605 lock (m_openRequests)
606 {
607 if (m_openRequests.ContainsKey(requestID))
608 {
609 mrs = m_openRequests[requestID];
610 m_openRequests.Remove(requestID);
611 }
612 }
613
614 if (mrs.agentID != UUID.Zero)
615 {
616 ScenePresence av = null;
617 m_scene.TryGetScenePresence(mrs.agentID, out av);
618 if (av != null)
619 {
620 if (response.ContainsKey(mrs.itemtype.ToString()))
621 {
622 List<mapItemReply> returnitems = new List<mapItemReply>();
623 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
624 for (int i = 0; i < itemarray.Count; i++)
625 {
626 OSDMap mapitem = (OSDMap)itemarray[i];
627 mapItemReply mi = new mapItemReply();
628 mi.x = (uint)mapitem["X"].AsInteger();
629 mi.y = (uint)mapitem["Y"].AsInteger();
630 mi.id = mapitem["ID"].AsUUID();
631 mi.Extra = mapitem["Extra"].AsInteger();
632 mi.Extra2 = mapitem["Extra2"].AsInteger();
633 mi.name = mapitem["Name"].AsString();
634 returnitems.Add(mi);
635 }
636 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
637 }
638
639 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
640 uint itemtype = 7;
641
642 if (response.ContainsKey(itemtype.ToString()))
643 {
644 List<mapItemReply> returnitems = new List<mapItemReply>();
645 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
646 for (int i = 0; i < itemarray.Count; i++)
647 {
648 OSDMap mapitem = (OSDMap)itemarray[i];
649 mapItemReply mi = new mapItemReply();
650 mi.x = (uint)mapitem["X"].AsInteger();
651 mi.y = (uint)mapitem["Y"].AsInteger();
652 mi.id = mapitem["ID"].AsUUID();
653 mi.Extra = mapitem["Extra"].AsInteger();
654 mi.Extra2 = mapitem["Extra2"].AsInteger();
655 mi.name = mapitem["Name"].AsString();
656 returnitems.Add(mi);
657 }
658 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
659 }
660
661 // Service 1 (MAP_ITEM_TELEHUB)
662 itemtype = 1;
663
664 if (response.ContainsKey(itemtype.ToString()))
665 {
666 List<mapItemReply> returnitems = new List<mapItemReply>();
667 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
668 for (int i = 0; i < itemarray.Count; i++)
669 {
670 OSDMap mapitem = (OSDMap)itemarray[i];
671 mapItemReply mi = new mapItemReply();
672 mi.x = (uint)mapitem["X"].AsInteger();
673 mi.y = (uint)mapitem["Y"].AsInteger();
674 mi.id = mapitem["ID"].AsUUID();
675 mi.Extra = mapitem["Extra"].AsInteger();
676 mi.Extra2 = mapitem["Extra2"].AsInteger();
677 mi.name = mapitem["Name"].AsString();
678 returnitems.Add(mi);
679 }
680 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
681 }
682 }
683 }
684 } 632 }
685 } 633 }
686 634
@@ -707,8 +655,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
707 EnqueueMapItemRequest(st); 655 EnqueueMapItemRequest(st);
708 } 656 }
709 657
710 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
711 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
712 /// <summary> 658 /// <summary>
713 /// Does the actual remote mapitem request 659 /// Does the actual remote mapitem request
714 /// This should be called from an asynchronous thread 660 /// This should be called from an asynchronous thread
@@ -723,7 +669,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
723 /// <param name="itemtype">passed in from packet</param> 669 /// <param name="itemtype">passed in from packet</param>
724 /// <param name="regionhandle">Region we're looking up</param> 670 /// <param name="regionhandle">Region we're looking up</param>
725 /// <returns></returns> 671 /// <returns></returns>
726 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 672 private void RequestMapItemsAsync(UUID id, uint flags,
727 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 673 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
728 { 674 {
729// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 675// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -746,7 +692,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
746 } 692 }
747 693
748 if (blacklisted) 694 if (blacklisted)
749 return new OSDMap(); 695 {
696 Interlocked.Decrement(ref nAsyncRequests);
697 return;
698 }
750 699
751 UUID requestID = UUID.Random(); 700 UUID requestID = UUID.Random();
752 lock (m_cachedRegionMapItemsAddress) 701 lock (m_cachedRegionMapItemsAddress)
@@ -754,6 +703,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
754 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 703 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
755 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 704 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
756 } 705 }
706
757 if (httpserver.Length == 0) 707 if (httpserver.Length == 0)
758 { 708 {
759 uint x = 0, y = 0; 709 uint x = 0, y = 0;
@@ -798,18 +748,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
798 748
799 // Can't find the http server 749 // Can't find the http server
800 if (httpserver.Length == 0 || blacklisted) 750 if (httpserver.Length == 0 || blacklisted)
801 return new OSDMap(); 751 {
802 752 Interlocked.Decrement(ref nAsyncRequests);
803 MapRequestState mrs = new MapRequestState(); 753 return;
804 mrs.agentID = id; 754 }
805 mrs.EstateID = EstateID;
806 mrs.flags = flags;
807 mrs.godlike = godlike;
808 mrs.itemtype=itemtype;
809 mrs.regionhandle = regionhandle;
810
811 lock (m_openRequests)
812 m_openRequests.Add(requestID, mrs);
813 755
814 WebRequest mapitemsrequest = null; 756 WebRequest mapitemsrequest = null;
815 try 757 try
@@ -819,7 +761,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
819 catch (Exception e) 761 catch (Exception e)
820 { 762 {
821 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);
822 return new OSDMap(); 764 Interlocked.Decrement(ref nAsyncRequests);
765 return;
823 } 766 }
824 767
825 mapitemsrequest.Method = "POST"; 768 mapitemsrequest.Method = "POST";
@@ -844,7 +787,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
844 catch (WebException ex) 787 catch (WebException ex)
845 { 788 {
846 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);
847 responseMap["connect"] = OSD.FromBoolean(false);
848 lock (m_blacklistedurls) 790 lock (m_blacklistedurls)
849 { 791 {
850 if (!m_blacklistedurls.ContainsKey(httpserver)) 792 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -853,13 +795,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
853 795
854 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 796 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
855 797
856 return responseMap; 798 Interlocked.Decrement(ref nAsyncRequests);
799 return;
857 } 800 }
858 catch 801 catch
859 { 802 {
860 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 803 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
861 responseMap["connect"] = OSD.FromBoolean(false); 804 Interlocked.Decrement(ref nAsyncRequests);
862 return responseMap; 805 return;
863 } 806 }
864 finally 807 finally
865 { 808 {
@@ -868,26 +811,24 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
868 } 811 }
869 812
870 string response_mapItems_reply = null; 813 string response_mapItems_reply = null;
871 { 814 { // get the response
815 StreamReader sr = null;
872 try 816 try
873 { 817 {
874 using (WebResponse webResponse = mapitemsrequest.GetResponse()) 818 WebResponse webResponse = mapitemsrequest.GetResponse();
819 if (webResponse != null)
875 { 820 {
876 if (webResponse != null) 821 sr = new StreamReader(webResponse.GetResponseStream());
877 { 822 response_mapItems_reply = sr.ReadToEnd().Trim();
878 using (Stream s = webResponse.GetResponseStream()) 823 }
879 using (StreamReader sr = new StreamReader(s)) 824 else
880 response_mapItems_reply = sr.ReadToEnd().Trim(); 825 {
881 } 826 Interlocked.Decrement(ref nAsyncRequests);
882 else 827 return;
883 { 828 }
884 return new OSDMap();
885 }
886 }
887 } 829 }
888 catch (WebException) 830 catch (WebException)
889 { 831 {
890 responseMap["connect"] = OSD.FromBoolean(false);
891 lock (m_blacklistedurls) 832 lock (m_blacklistedurls)
892 { 833 {
893 if (!m_blacklistedurls.ContainsKey(httpserver)) 834 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -896,19 +837,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
896 837
897 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 838 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
898 839
899 return responseMap; 840 Interlocked.Decrement(ref nAsyncRequests);
841 return;
900 } 842 }
901 catch 843 catch
902 { 844 {
903 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 845 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
904 responseMap["connect"] = OSD.FromBoolean(false);
905 lock (m_blacklistedregions) 846 lock (m_blacklistedregions)
906 { 847 {
907 if (!m_blacklistedregions.ContainsKey(regionhandle)) 848 if (!m_blacklistedregions.ContainsKey(regionhandle))
908 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 849 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
909 } 850 }
910 851
911 return responseMap; 852 Interlocked.Decrement(ref nAsyncRequests);
853 return;
854 }
855 finally
856 {
857 if (sr != null)
858 sr.Close();
912 } 859 }
913 860
914 OSD rezResponse = null; 861 OSD rezResponse = null;
@@ -922,15 +869,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
922 catch (Exception ex) 869 catch (Exception ex)
923 { 870 {
924 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);
925 responseMap["connect"] = OSD.FromBoolean(false);
926
927 lock (m_blacklistedregions) 872 lock (m_blacklistedregions)
928 { 873 {
929 if (!m_blacklistedregions.ContainsKey(regionhandle)) 874 if (!m_blacklistedregions.ContainsKey(regionhandle))
930 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 875 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
931 } 876 }
932 877
933 return responseMap; 878 Interlocked.Decrement(ref nAsyncRequests);
879 return;
934 } 880 }
935 } 881 }
936 882
@@ -944,7 +890,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
944 } 890 }
945 } 891 }
946 892
947 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 }
948 } 965 }
949 966
950 /// <summary> 967 /// <summary>
@@ -954,7 +971,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
954 /// <param name="minY"></param> 971 /// <param name="minY"></param>
955 /// <param name="maxX"></param> 972 /// <param name="maxX"></param>
956 /// <param name="maxY"></param> 973 /// <param name="maxY"></param>
957 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)
958 { 975 {
959 //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);
960 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
@@ -1007,21 +1024,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1007 1024
1008 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)
1009 { 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>();
1010 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1085 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1011 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1086 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1012 (minX - 4) * (int)Constants.RegionSize, 1087 minX * (int)Constants.RegionSize,
1013 (maxX + 4) * (int)Constants.RegionSize, 1088 maxX * (int)Constants.RegionSize,
1014 (minY - 4) * (int)Constants.RegionSize, 1089 minY * (int)Constants.RegionSize,
1015 (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);
1016 foreach (GridRegion r in regions) 1095 foreach (GridRegion r in regions)
1017 { 1096 {
1018 MapBlockData block = new MapBlockData(); 1097 MapBlockData block = new MapBlockData();
1019 MapBlockFromGridRegion(block, r, flag); 1098 MapBlockFromGridRegion(block, r, flag);
1020 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 }
1021 } 1107 }
1022 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1108 if (mapBlocks.Count > 0)
1109 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1023 1110
1024 return mapBlocks; 1111 return allBlocks;
1025 } 1112 }
1026 1113
1027 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1114 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1245,7 +1332,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1245 } 1332 }
1246 else 1333 else
1247 { 1334 {
1248 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1335 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1249 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1336 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1250 { 1337 {
1251 OSDMap responsemapdata = new OSDMap(); 1338 OSDMap responsemapdata = new OSDMap();
@@ -1421,6 +1508,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1421 { 1508 {
1422 m_rootAgents.Remove(avatar.UUID); 1509 m_rootAgents.Remove(avatar.UUID);
1423 } 1510 }
1511
1512 lock (m_mapBlockRequestEvent)
1513 {
1514 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1515 m_mapBlockRequests.Remove(avatar.UUID);
1516 }
1424 } 1517 }
1425 1518
1426 public void OnRegionUp(GridRegion otherRegion) 1519 public void OnRegionUp(GridRegion otherRegion)
@@ -1465,9 +1558,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1465 Color background = Color.FromArgb(0, 0, 0, 0); 1558 Color background = Color.FromArgb(0, 0, 0, 0);
1466 SolidBrush transparent = new SolidBrush(background); 1559 SolidBrush transparent = new SolidBrush(background);
1467 Graphics g = Graphics.FromImage(overlay); 1560 Graphics g = Graphics.FromImage(overlay);
1468 g.FillRectangle(transparent, 0, 0, 256, 256); 1561 g.FillRectangle(transparent, 0, 0, 255, 255);
1469 1562
1470 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));
1471 1565
1472 foreach (ILandObject land in parcels) 1566 foreach (ILandObject land in parcels)
1473 { 1567 {
@@ -1475,8 +1569,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1475 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1569 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1476 { 1570 {
1477 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 }
1478 1606
1479 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1607 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1480 } 1608 }
1481 } 1609 }
1482 1610
@@ -1488,15 +1616,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1488 1616
1489 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);
1490 1618
1491 for (int x = 0 ; x < 64 ; x++)
1492 {
1493 for (int y = 0 ; y < 64 ; y++)
1494 {
1495 if (saleBitmap[x, y])
1496 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1497 }
1498 }
1499
1500 try 1619 try
1501 { 1620 {
1502 return OpenJPEG.EncodeFromImage(overlay, true); 1621 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1518,4 +1637,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1518 public uint itemtype; 1637 public uint itemtype;
1519 public ulong regionhandle; 1638 public ulong regionhandle;
1520 } 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 }
1521} 1650}