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.cs173
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs93
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs112
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs10
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs169
-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/InstantMessage/InstantMessageModule.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs104
-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.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs426
-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.cs192
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs31
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs402
-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.cs441
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs63
-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.cs547
48 files changed, 2648 insertions, 1318 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 e973652..7332415 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 8add4bb..0aa4693 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;
@@ -38,6 +39,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
38{ 39{
39 public class AssetXferUploader 40 public class AssetXferUploader
40 { 41 {
42 // Viewer's notion of the default texture
43 private List<UUID> defaultIDs = new List<UUID> {
44 new UUID("5748decc-f629-461c-9a36-a35a221fe21f"),
45 new UUID("7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"),
46 new UUID("6522e74d-1660-4e7f-b601-6f48c1659a77"),
47 new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97")
48 };
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 50
43 /// <summary> 51 /// <summary>
@@ -85,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
85 93
86 private sbyte type = 0; 94 private sbyte type = 0;
87 private byte wearableType = 0; 95 private byte wearableType = 0;
96 private byte[] m_oldData = null;
88 public ulong XferID; 97 public ulong XferID;
89 private Scene m_Scene; 98 private Scene m_Scene;
90 99
@@ -127,18 +136,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
127 136
128 if (XferID == xferID) 137 if (XferID == xferID)
129 { 138 {
130 if (m_asset.Data.Length > 1) 139 lock (this)
131 { 140 {
132 byte[] destinationArray = new byte[m_asset.Data.Length + data.Length]; 141 int assetLength = m_asset.Data.Length;
133 Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length); 142 int dataLength = data.Length;
134 Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length); 143
135 m_asset.Data = destinationArray; 144 if (m_asset.Data.Length > 1)
136 } 145 {
137 else 146 byte[] destinationArray = new byte[assetLength + dataLength];
138 { 147 Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
139 byte[] buffer2 = new byte[data.Length - 4]; 148 Array.Copy(data, 0, destinationArray, assetLength, dataLength);
140 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 149 m_asset.Data = destinationArray;
141 m_asset.Data = buffer2; 150 }
151 else
152 {
153 if (dataLength > 4)
154 {
155 byte[] buffer2 = new byte[dataLength - 4];
156 Array.Copy(data, 4, buffer2, 0, dataLength - 4);
157 m_asset.Data = buffer2;
158 }
159 }
142 } 160 }
143 161
144 ourClient.SendConfirmXfer(xferID, packetID); 162 ourClient.SendConfirmXfer(xferID, packetID);
@@ -393,6 +411,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
393 411
394 private void CompleteCreateItem(uint callbackID) 412 private void CompleteCreateItem(uint callbackID)
395 { 413 {
414 ValidateAssets();
396 m_Scene.AssetService.Store(m_asset); 415 m_Scene.AssetService.Store(m_asset);
397 416
398 InventoryItemBase item = new InventoryItemBase(); 417 InventoryItemBase item = new InventoryItemBase();
@@ -413,6 +432,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
413 item.Flags = (uint) wearableType; 432 item.Flags = (uint) wearableType;
414 item.CreationDate = Util.UnixTimeSinceEpoch(); 433 item.CreationDate = Util.UnixTimeSinceEpoch();
415 434
435 m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
436 item.ID, item.AssetID);
437
416 if (m_Scene.AddInventoryItem(item)) 438 if (m_Scene.AddInventoryItem(item))
417 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 439 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
418 else 440 else
@@ -420,5 +442,132 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
420 442
421 m_transactions.RemoveXferUploader(m_transactionID); 443 m_transactions.RemoveXferUploader(m_transactionID);
422 } 444 }
445
446 private void ValidateAssets()
447 {
448 if (m_asset.Type == (sbyte)AssetType.Clothing ||
449 m_asset.Type == (sbyte)AssetType.Bodypart)
450 {
451 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
452 string[] lines = content.Split(new char[] {'\n'});
453
454 List<string> validated = new List<string>();
455
456 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
457
458 int textures = 0;
459
460 foreach (string line in lines)
461 {
462 try
463 {
464 if (line.StartsWith("textures "))
465 {
466 textures = Convert.ToInt32(line.Substring(9));
467 validated.Add(line);
468 }
469 else if (textures > 0)
470 {
471 string[] parts = line.Split(new char[] {' '});
472
473 UUID tx = new UUID(parts[1]);
474 int id = Convert.ToInt32(parts[0]);
475
476 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
477 (allowed.ContainsKey(id) && allowed[id] == tx))
478 {
479 validated.Add(parts[0] + " " + tx.ToString());
480 }
481 else
482 {
483 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
484 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
485
486 if ((perms & full) != full)
487 {
488 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
489 validated.Add(parts[0] + " " + UUID.Zero.ToString());
490 }
491 else
492 {
493 validated.Add(line);
494 }
495 }
496 textures--;
497 }
498 else
499 {
500 validated.Add(line);
501 }
502 }
503 catch
504 {
505 // If it's malformed, skip it
506 }
507 }
508
509 string final = String.Join("\n", validated.ToArray());
510
511 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
512 }
513 }
514
515 /// <summary>
516 /// Get the asset data uploaded in this transfer.
517 /// </summary>
518 /// <returns>null if the asset has not finished uploading</returns>
519 public AssetBase GetAssetData()
520 {
521 if (m_uploadState == UploadState.Complete)
522 {
523 ValidateAssets();
524 return m_asset;
525 }
526
527 return null;
528 }
529
530 public void SetOldData(byte[] d)
531 {
532 m_oldData = d;
533 }
534
535 private Dictionary<int,UUID> ExtractTexturesFromOldData()
536 {
537 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
538 if (m_oldData == null)
539 return result;
540
541 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
542 string[] lines = content.Split(new char[] {'\n'});
543
544 int textures = 0;
545
546 foreach (string line in lines)
547 {
548 try
549 {
550 if (line.StartsWith("textures "))
551 {
552 textures = Convert.ToInt32(line.Substring(9));
553 }
554 else if (textures > 0)
555 {
556 string[] parts = line.Split(new char[] {' '});
557
558 UUID tx = new UUID(parts[1]);
559 int id = Convert.ToInt32(parts[0]);
560 result[id] = tx;
561 textures--;
562 }
563 }
564 catch
565 {
566 // If it's malformed, skip it
567 }
568 }
569
570 return result;
571 }
423 } 572 }
424} \ No newline at end of file 573}
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/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 8e800cb..b1bb56b 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -251,57 +251,70 @@ namespace OpenSim.Region.CoreModules.Asset
251 251
252 private void UpdateFileCache(string key, AssetBase asset) 252 private void UpdateFileCache(string key, AssetBase asset)
253 { 253 {
254 string filename = GetFileName(asset.ID); 254 // TODO: Spawn this off to some seperate thread to do the actual writing
255 255 if (asset != null)
256 try
257 { 256 {
258 // If the file is already cached just update access time. 257 string filename = GetFileName(key);
259 if (File.Exists(filename)) 258
260 { 259 try
261 lock (m_CurrentlyWriting)
262 {
263 if (!m_CurrentlyWriting.Contains(filename))
264 File.SetLastAccessTime(filename, DateTime.Now);
265 }
266 }
267 else
268 { 260 {
269 // Once we start writing, make sure we flag that we're writing 261 // If the file is already cached, don't cache it, just touch it so access time is updated
270 // that object to the cache so that we don't try to write the 262 if (File.Exists(filename))
271 // same file multiple times.
272 lock (m_CurrentlyWriting)
273 { 263 {
274#if WAIT_ON_INPROGRESS_REQUESTS 264 // We don't really want to know about sharing
275 if (m_CurrentlyWriting.ContainsKey(filename)) 265 // violations here. If the file is locked, then
266 // the other thread has updated the time for us.
267 try
276 { 268 {
277 return; 269 lock (m_CurrentlyWriting)
270 {
271 if (!m_CurrentlyWriting.Contains(filename))
272 File.SetLastAccessTime(filename, DateTime.Now);
273 }
278 } 274 }
279 else 275 catch
280 {
281 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
282 }
283
284#else
285 if (m_CurrentlyWriting.Contains(filename))
286 { 276 {
287 return;
288 } 277 }
289 else 278 } else {
279
280 // Once we start writing, make sure we flag that we're writing
281 // that object to the cache so that we don't try to write the
282 // same file multiple times.
283 lock (m_CurrentlyWriting)
290 { 284 {
291 m_CurrentlyWriting.Add(filename); 285#if WAIT_ON_INPROGRESS_REQUESTS
292 } 286 if (m_CurrentlyWriting.ContainsKey(filename))
287 {
288 return;
289 }
290 else
291 {
292 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
293 }
294
295#else
296 if (m_CurrentlyWriting.Contains(filename))
297 {
298 return;
299 }
300 else
301 {
302 m_CurrentlyWriting.Add(filename);
303 }
293#endif 304#endif
294 }
295 305
296 Util.FireAndForget( 306 }
297 delegate { WriteFileCache(filename, asset); }); 307
308 Util.FireAndForget(
309 delegate { WriteFileCache(filename, asset); });
310 }
311 }
312 catch (Exception e)
313 {
314 m_log.ErrorFormat(
315 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
316 asset.ID, e.Message, e.StackTrace);
298 } 317 }
299 }
300 catch (Exception e)
301 {
302 m_log.ErrorFormat(
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
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 24170fc..acd156e 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{
@@ -169,6 +170,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
169 170
170// 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);
171 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
172 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 207 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
173 foreach (AvatarAttachment attach in attachments) 208 foreach (AvatarAttachment attach in attachments)
174 { 209 {
@@ -188,12 +223,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
188 223
189 try 224 try
190 { 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
191 // 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
192 // inventory right now. 237 // inventory right now.
193 if (sp.PresenceType == PresenceType.Npc) 238 if (sp.PresenceType == PresenceType.Npc)
194 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); 239 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
195 else 240 else
196 RezSingleAttachmentFromInventory(sp, attach.ItemID, p); 241 RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d);
197 } 242 }
198 catch (Exception e) 243 catch (Exception e)
199 { 244 {
@@ -238,13 +283,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
238 283
239 sp.ClearAttachments(); 284 sp.ClearAttachments();
240 } 285 }
241 286
242 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
243 { 288 {
244 if (!Enabled) 289 if (!Enabled)
245 return false; 290 return false;
246 291
247 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) 292 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp))
248 { 293 {
249 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); 294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
250 return true; 295 return true;
@@ -253,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
253 return false; 298 return false;
254 } 299 }
255 300
256 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
257 { 302 {
258 lock (sp.AttachmentsSyncLock) 303 lock (sp.AttachmentsSyncLock)
259 { 304 {
@@ -308,6 +353,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
308 attachPos = Vector3.Zero; 353 attachPos = Vector3.Zero;
309 } 354 }
310 355
356 if (useAttachData)
357 {
358 group.RootPart.RotationOffset = group.RootPart.AttachRotation;
359 attachPos = group.RootPart.AttachOffset;
360 if (attachmentPt == 0)
361 {
362 attachmentPt = group.RootPart.AttachPoint;
363 if (attachmentPt == 0)
364 {
365 attachmentPt = (uint)AttachmentPoint.LeftHand;
366 attachPos = Vector3.Zero;
367 }
368 }
369 else if (group.RootPart.AttachPoint != attachmentPt)
370 {
371 attachPos = Vector3.Zero;
372 }
373 }
311 group.AttachmentPoint = attachmentPt; 374 group.AttachmentPoint = attachmentPt;
312 group.AbsolutePosition = attachPos; 375 group.AbsolutePosition = attachPos;
313 376
@@ -348,7 +411,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
348 } 411 }
349 } 412 }
350 413
351 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 414 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
415 {
416 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
417 }
418
419 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
352 { 420 {
353 if (!Enabled) 421 if (!Enabled)
354 return null; 422 return null;
@@ -387,7 +455,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
387 return null; 455 return null;
388 } 456 }
389 457
390 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 458 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
391 } 459 }
392 460
393 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 461 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -461,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
461 so.AttachedAvatar = UUID.Zero; 529 so.AttachedAvatar = UUID.Zero;
462 rootPart.SetParentLocalId(0); 530 rootPart.SetParentLocalId(0);
463 so.ClearPartAttachmentData(); 531 so.ClearPartAttachmentData();
464 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 532 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
465 so.HasGroupChanged = true; 533 so.HasGroupChanged = true;
466 rootPart.Rezzed = DateTime.Now; 534 rootPart.Rezzed = DateTime.Now;
467 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 535 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -778,8 +846,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
778 UpdateDetachedObject(sp, so); 846 UpdateDetachedObject(sp, so);
779 } 847 }
780 848
781 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 849 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
782 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 850 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
783 { 851 {
784 if (m_invAccessModule == null) 852 if (m_invAccessModule == null)
785 return null; 853 return null;
@@ -817,7 +885,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
817 // This will throw if the attachment fails 885 // This will throw if the attachment fails
818 try 886 try
819 { 887 {
820 AttachObjectInternal(sp, objatt, attachmentPt, false, false); 888 AttachObjectInternal(sp, objatt, attachmentPt, false, false, false);
821 } 889 }
822 catch (Exception e) 890 catch (Exception e)
823 { 891 {
@@ -830,10 +898,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
830 m_scene.DeleteSceneObject(objatt, false); 898 m_scene.DeleteSceneObject(objatt, false);
831 return null; 899 return null;
832 } 900 }
833 901
834 if (tainted) 902 if (tainted)
835 objatt.HasGroupChanged = true; 903 objatt.HasGroupChanged = true;
836 904
905 if (doc != null)
906 {
907 objatt.LoadScriptState(doc);
908 objatt.ResetOwnerChangeFlag();
909 }
910
837 // Fire after attach, so we don't get messy perms dialogs 911 // Fire after attach, so we don't get messy perms dialogs
838 // 4 == AttachedRez 912 // 4 == AttachedRez
839 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 913 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
@@ -851,7 +925,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
851 itemID, sp.Name, attachmentPt); 925 itemID, sp.Name, attachmentPt);
852 } 926 }
853 } 927 }
854 928
855 return null; 929 return null;
856 } 930 }
857 931
@@ -974,7 +1048,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
974 AttachmentPt &= 0x7f; 1048 AttachmentPt &= 0x7f;
975 1049
976 // Calls attach with a Zero position 1050 // Calls attach with a Zero position
977 AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); 1051 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false))
1052 {
1053// m_log.Debug(
1054// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1055// + ", AttachmentPoint: " + AttachmentPt);
1056
1057 // Save avatar attachment information
1058 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
1059 }
978 } 1060 }
979 catch (Exception e) 1061 catch (Exception e)
980 { 1062 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 0ee01c7..4e9d3f9 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); 200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, 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);
@@ -254,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
254 sp2.AbsolutePosition = new Vector3(0, 0, 0); 254 sp2.AbsolutePosition = new Vector3(0, 0, 0);
255 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 255 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
256 256
257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); 257 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
258 258
259 Assert.That(sp.HasAttachments(), Is.False); 259 Assert.That(sp.HasAttachments(), Is.False);
260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -438,7 +438,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
438 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 438 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
439 439
440 SceneObjectGroup rezzedSo 440 SceneObjectGroup rezzedSo
441 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 441 = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
442 442
443 // Wait for chat to signal rezzed script has been started. 443 // Wait for chat to signal rezzed script has been started.
444 m_chatEvent.WaitOne(60000); 444 m_chatEvent.WaitOne(60000);
@@ -457,7 +457,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
457 Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); 457 Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
458 458
459 // Re-rez the attachment to check script running state 459 // Re-rez the attachment to check script running state
460 SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 460 SceneObjectGroup reRezzedSo = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
461 461
462 // Wait for chat to signal rezzed script has been started. 462 // Wait for chat to signal rezzed script has been started.
463 m_chatEvent.WaitOne(60000); 463 m_chatEvent.WaitOne(60000);
@@ -663,4 +663,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
663 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); 663 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
664 } 664 }
665 } 665 }
666} \ No newline at end of file 666}
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 0a69979..8496005 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -592,12 +592,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
592 /// <param name="client"></param> 592 /// <param name="client"></param>
593 private void Client_OnRequestWearables(IClientAPI client) 593 private void Client_OnRequestWearables(IClientAPI client)
594 { 594 {
595 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 595 Util.FireAndForget(delegate(object x)
596 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 596 {
597 if (sp != null) 597 Thread.Sleep(4000);
598 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 598
599 else 599 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
600 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 600 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
601 if (sp != null)
602 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
603 else
604 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
605 });
601 } 606 }
602 607
603 /// <summary> 608 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 6d62ff0..4c3f1cc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -51,7 +51,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
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 private List<Scene> m_scenes = new List<Scene>(); 53 private List<Scene> m_scenes = new List<Scene>();
54 54 private List<string> FreezeCache = new List<string>();
55 private string m_adminPrefix = "";
55 internal object m_syncy = new object(); 56 internal object m_syncy = new object();
56 57
57 internal IConfig m_config; 58 internal IConfig m_config;
@@ -78,6 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
78 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 79 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
79 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 80 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
80 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", "");
81 } 83 }
82 84
83 public virtual void AddRegion(Scene scene) 85 public virtual void AddRegion(Scene scene)
@@ -173,7 +175,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
173 return; 175 return;
174 } 176 }
175 177
176 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 }
177 } 187 }
178 188
179 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 189 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -187,11 +197,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
187 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 197 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
188 { 198 {
189 string fromName = c.From; 199 string fromName = c.From;
200 string fromNamePrefix = "";
190 UUID fromID = UUID.Zero; 201 UUID fromID = UUID.Zero;
191 UUID ownerID = UUID.Zero; 202 UUID ownerID = UUID.Zero;
192 UUID targetID = c.TargetUUID;
193 string message = c.Message; 203 string message = c.Message;
194 IScene scene = c.Scene; 204 IScene scene = c.Scene;
205 UUID destination = c.Destination;
195 Vector3 fromPos = c.Position; 206 Vector3 fromPos = c.Position;
196 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 207 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
197 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 208 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -211,6 +222,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
211 fromPos = avatar.AbsolutePosition; 222 fromPos = avatar.AbsolutePosition;
212 fromName = avatar.Name; 223 fromName = avatar.Name;
213 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"
214 ownerID = c.Sender.AgentId; 230 ownerID = c.Sender.AgentId;
215 231
216 break; 232 break;
@@ -229,40 +245,47 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
229 message = message.Substring(0, 1000); 245 message = message.Substring(0, 1000);
230 246
231// m_log.DebugFormat( 247// m_log.DebugFormat(
232// "[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}",
233// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 249// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
234 250
235 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 251 HashSet<UUID> receiverIDs = new HashSet<UUID>();
236 252
237 foreach (Scene s in m_scenes) 253 foreach (Scene s in m_scenes)
238 { 254 {
239 if (targetID == UUID.Zero) 255 // This should use ForEachClient, but clients don't have a position.
240 { 256 // If camera is moved into client, then camera position can be used
241 // This should use ForEachClient, but clients don't have a position. 257 // MT: No, it can't, as chat is heard from the avatar position, not
242 // If camera is moved into client, then camera position can be used 258 // the camera position.
243 s.ForEachRootScenePresence( 259 s.ForEachRootScenePresence(
244 delegate(ScenePresence presence) 260 delegate(ScenePresence presence)
261 {
262 if (destination != UUID.Zero && presence.UUID != destination)
263 return;
264 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
265 if (Presencecheck != null)
245 { 266 {
246 if (TrySendChatMessage( 267 // This will pass all chat from objects. Not
247 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) 268 // perfect, but it will do. For now. Better
248 receiverIDs.Add(presence.UUID); 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 }
249 } 284 }
250 );
251 }
252 else
253 {
254 // This is a send to a specific client eg from llRegionSayTo
255 // no need to check distance etc, jand send is as say
256 ScenePresence presence = s.GetScenePresence(targetID);
257 if (presence != null && !presence.IsChildAgent)
258 {
259 if (TrySendChatMessage(
260 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
261 receiverIDs.Add(presence.UUID);
262 } 285 }
263 } 286 );
264 } 287 }
265 288
266 (scene as Scene).EventManager.TriggerOnChatToClients( 289 (scene as Scene).EventManager.TriggerOnChatToClients(
267 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 290 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
268 } 291 }
@@ -302,28 +325,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
302 } 325 }
303 326
304 // 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);
305
306 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 328 HashSet<UUID> receiverIDs = new HashSet<UUID>();
307 329
308 ((Scene)c.Scene).ForEachRootClient( 330 if (c.Scene != null)
309 delegate(IClientAPI client) 331 {
310 { 332 ((Scene)c.Scene).ForEachRootClient
311 // don't forward SayOwner chat from objects to 333 (
312 // non-owner agents 334 delegate(IClientAPI client)
313 if ((c.Type == ChatTypeEnum.Owner) && 335 {
314 (null != c.SenderObject) && 336 // don't forward SayOwner chat from objects to
315 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 337 // non-owner agents
316 return; 338 if ((c.Type == ChatTypeEnum.Owner) &&
317 339 (null != c.SenderObject) &&
318 client.SendChatMessage( 340 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
319 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 341 return;
320 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 342
321 343 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
322 receiverIDs.Add(client.AgentId); 344 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
323 }); 345 receiverIDs.Add(client.AgentId);
324 346 }
325 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 347 );
326 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 }
327 } 351 }
328 352
329 /// <summary> 353 /// <summary>
@@ -348,7 +372,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
348 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, 372 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
349 string message, ChatSourceType src, bool ignoreDistance) 373 string message, ChatSourceType src, bool ignoreDistance)
350 { 374 {
351 // don't send stuff to child agents 375 // don't send chat to child agents
352 if (presence.IsChildAgent) return false; 376 if (presence.IsChildAgent) return false;
353 377
354 Vector3 fromRegionPos = fromPos + regionPos; 378 Vector3 fromRegionPos = fromPos + regionPos;
@@ -357,15 +381,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
357 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 381 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
358 382
359 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 383 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
360 384
361 if (!ignoreDistance) 385 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
386 type == ChatTypeEnum.Say && dis > m_saydistance ||
387 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
362 { 388 {
363 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 389 return false;
364 type == ChatTypeEnum.Say && dis > m_saydistance ||
365 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
366 {
367 return false;
368 }
369 } 390 }
370 391
371 // 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
@@ -375,5 +396,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
375 396
376 return true; 397 return true;
377 } 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 }
378 } 429 }
379} \ 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/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 3983369..cc266df 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 {
@@ -159,8 +166,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
159 // try child avatar second 166 // try child avatar second
160 foreach (Scene scene in m_Scenes) 167 foreach (Scene scene in m_Scenes)
161 { 168 {
162 m_log.DebugFormat( 169 //m_log.DebugFormat(
163 "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); 170 // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
164 171
165 ScenePresence sp = scene.GetScenePresence(toAgentID); 172 ScenePresence sp = scene.GetScenePresence(toAgentID);
166 if (sp != null) 173 if (sp != null)
@@ -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 41364d7..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 5069803..dc2b0e0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -634,4 +634,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
634 m_assetsLoaded = true; 634 m_assetsLoaded = true;
635 } 635 }
636 } 636 }
637} \ No newline at end of file 637}
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 582aac4..4cfa33d 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
@@ -411,6 +427,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
411 previousParentFolderID = folder.ParentID; 427 previousParentFolderID = folder.ParentID;
412 folder.ParentID = trashFolder.ID; 428 folder.ParentID = trashFolder.ID;
413 invService.MoveFolder(folder); 429 invService.MoveFolder(folder);
430 client.SendBulkUpdateInventory(folder);
414 } 431 }
415 } 432 }
416 433
@@ -524,22 +541,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
524 /// 541 ///
525 /// </summary> 542 /// </summary>
526 /// <param name="msg"></param> 543 /// <param name="msg"></param>
527 private void OnGridInstantMessage(GridInstantMessage msg) 544 private void OnGridInstantMessage(GridInstantMessage im)
528 { 545 {
529 // Check if this is ours to handle 546 // Check if this is ours to handle
530 // 547 //
531 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 548 Scene scene = FindClientScene(new UUID(im.toAgentID));
532 549
533 if (scene == null) 550 if (scene == null)
534 return; 551 return;
535 552
536 // Find agent to deliver to 553 // Find agent to deliver to
537 // 554 //
538 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 555 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
556 if (user == null)
557 return;
558
559 // This requires a little bit of processing because we have to make the
560 // new item visible in the recipient's inventory here
561 //
562 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
563 {
564 if (im.binaryBucket.Length < 17) // Invalid
565 return;
566
567 UUID recipientID = new UUID(im.toAgentID);
568
569 // First byte is the asset type
570 AssetType assetType = (AssetType)im.binaryBucket[0];
571
572 if (AssetType.Folder == assetType)
573 {
574 UUID folderID = new UUID(im.binaryBucket, 1);
539 575
540 // Just forward to local handling 576 InventoryFolderBase given =
541 OnInstantMessage(user.ControllingClient, msg); 577 new InventoryFolderBase(folderID, recipientID);
578 InventoryFolderBase folder =
579 scene.InventoryService.GetFolder(given);
542 580
581 if (folder != null)
582 user.ControllingClient.SendBulkUpdateInventory(folder);
583 }
584 else
585 {
586 UUID itemID = new UUID(im.binaryBucket, 1);
587
588 InventoryItemBase given =
589 new InventoryItemBase(itemID, recipientID);
590 InventoryItemBase item =
591 scene.InventoryService.GetItem(given);
592
593 if (item != null)
594 {
595 user.ControllingClient.SendBulkUpdateInventory(item);
596 }
597 }
598 user.ControllingClient.SendInstantMessage(im);
599 }
600 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
601 {
602 if (im.binaryBucket.Length < 1) // Invalid
603 return;
604
605 UUID recipientID = new UUID(im.toAgentID);
606
607 // Bucket is the asset type
608 AssetType assetType = (AssetType)im.binaryBucket[0];
609
610 if (AssetType.Folder == assetType)
611 {
612 UUID folderID = new UUID(im.imSessionID);
613
614 InventoryFolderBase given =
615 new InventoryFolderBase(folderID, recipientID);
616 InventoryFolderBase folder =
617 scene.InventoryService.GetFolder(given);
618
619 if (folder != null)
620 user.ControllingClient.SendBulkUpdateInventory(folder);
621 }
622 else
623 {
624 UUID itemID = new UUID(im.imSessionID);
625
626 InventoryItemBase given =
627 new InventoryItemBase(itemID, recipientID);
628 InventoryItemBase item =
629 scene.InventoryService.GetItem(given);
630
631 if (item != null)
632 {
633 user.ControllingClient.SendBulkUpdateInventory(item);
634 }
635 }
636
637 // Fix up binary bucket since this may be 17 chars long here
638 Byte[] bucket = new Byte[1];
639 bucket[0] = im.binaryBucket[0];
640 im.binaryBucket = bucket;
641
642 user.ControllingClient.SendInstantMessage(im);
643 }
644 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
645 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
646 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
647 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
648 {
649 user.ControllingClient.SendInstantMessage(im);
650 }
543 } 651 }
544 } 652 }
545} 653}
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..7f30e5a 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -102,7 +102,8 @@ namespace OpenSim.Region.CoreModules.Framework
102 102
103 public void CreateCaps(UUID agentId) 103 public void CreateCaps(UUID agentId)
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);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 3cb1901..7e72d47 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
148 148
149 protected virtual void OnNewClient(IClientAPI client) 149 protected virtual void OnNewClient(IClientAPI client)
150 { 150 {
151 client.OnTeleportHomeRequest += TeleportHome; 151 client.OnTeleportHomeRequest += TriggerTeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
153 } 153 }
154 154
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
222 /// <param name="sp"></param> 222 /// <param name="sp"></param>
223 /// <param name="position"></param> 223 /// <param name="position"></param>
224 /// <param name="lookAt"></param> 224 /// <param name="lookAt"></param>
225 /// <param name="teleportFlags"></param 225 /// <param name="teleportFlags"></param>
226 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 226 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
227 { 227 {
228 m_log.DebugFormat( 228 m_log.DebugFormat(
@@ -266,11 +266,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
266 position.Z = newPosZ; 266 position.Z = newPosZ;
267 } 267 }
268 268
269 if (sp.Flying)
270 teleportFlags |= (uint)TeleportFlags.IsFlying;
271
269 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 272 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
270 273
271 sp.ControllingClient.SendTeleportStart(teleportFlags); 274 sp.ControllingClient.SendTeleportStart(teleportFlags);
272 275
273 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 276 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
277 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
274 sp.Velocity = Vector3.Zero; 278 sp.Velocity = Vector3.Zero;
275 sp.Teleport(position); 279 sp.Teleport(position);
276 280
@@ -446,8 +450,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
446 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 450 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
447 // it's actually doing a lot of work. 451 // it's actually doing a lot of work.
448 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 452 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
449 453 if (endPoint == null || endPoint.Address == null)
450 if (endPoint.Address == null)
451 { 454 {
452 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 455 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
453 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 456 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
@@ -487,6 +490,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
487 // both regions 490 // both regions
488 if (sp.ParentID != (uint)0) 491 if (sp.ParentID != (uint)0)
489 sp.StandUp(); 492 sp.StandUp();
493 else if (sp.Flying)
494 teleportFlags |= (uint)TeleportFlags.IsFlying;
490 495
491 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 496 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
492 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 497 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
@@ -664,7 +669,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
664 // 669 //
665 // This sleep can be increased if necessary. However, whilst it's active, 670 // This sleep can be increased if necessary. However, whilst it's active,
666 // an agent cannot teleport back to this region if it has teleported away. 671 // an agent cannot teleport back to this region if it has teleported away.
667 Thread.Sleep(2000); 672 Thread.Sleep(3000);
668 673
669 sp.Scene.IncomingCloseAgent(sp.UUID, false); 674 sp.Scene.IncomingCloseAgent(sp.UUID, false);
670 } 675 }
@@ -804,7 +809,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
804 809
805 #region Teleport Home 810 #region Teleport Home
806 811
807 public virtual void TeleportHome(UUID id, IClientAPI client) 812 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
813 {
814 TeleportHome(id, client);
815 }
816
817 public virtual bool TeleportHome(UUID id, IClientAPI client)
808 { 818 {
809 m_log.DebugFormat( 819 m_log.DebugFormat(
810 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 820 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -814,12 +824,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
814 824
815 if (uinfo != null) 825 if (uinfo != null)
816 { 826 {
827 if (uinfo.HomeRegionID == UUID.Zero)
828 {
829 // can't find the Home region: Tell viewer and abort
830 client.SendTeleportFailed("You don't have a home position set.");
831 return false;
832 }
817 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 833 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
818 if (regionInfo == null) 834 if (regionInfo == null)
819 { 835 {
820 // can't find the Home region: Tell viewer and abort 836 // can't find the Home region: Tell viewer and abort
821 client.SendTeleportFailed("Your home region could not be found."); 837 client.SendTeleportFailed("Your home region could not be found.");
822 return; 838 return false;
823 } 839 }
824 840
825 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 841 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
@@ -832,10 +848,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
832 } 848 }
833 else 849 else
834 { 850 {
835 m_log.ErrorFormat( 851 // can't find the Home region: Tell viewer and abort
836 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 852 client.SendTeleportFailed("Your home region could not be found.");
837 client.Name, client.AgentId); 853 return false;
838 } 854 }
855 return true;
839 } 856 }
840 857
841 #endregion 858 #endregion
@@ -843,11 +860,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
843 860
844 #region Agent Crossings 861 #region Agent Crossings
845 862
846 public bool Cross(ScenePresence agent, bool isFlying) 863 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
847 { 864 {
848 Scene scene = agent.Scene; 865 version = String.Empty;
849 Vector3 pos = agent.AbsolutePosition; 866 newpos = new Vector3(pos.X, pos.Y, pos.Z);
850 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
851 uint neighbourx = scene.RegionInfo.RegionLocX; 867 uint neighbourx = scene.RegionInfo.RegionLocX;
852 uint neighboury = scene.RegionInfo.RegionLocY; 868 uint neighboury = scene.RegionInfo.RegionLocY;
853 const float boundaryDistance = 1.7f; 869 const float boundaryDistance = 1.7f;
@@ -868,52 +884,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
868 } 884 }
869 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 885 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
870 { 886 {
871 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 887 neighboury--;
872 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 888 newpos.Y = Constants.RegionSize - enterDistance;
873 {
874 neighboury--;
875 newpos.Y = Constants.RegionSize - enterDistance;
876 }
877 else
878 {
879 agent.IsInTransit = true;
880
881 neighboury = b.TriggerRegionY;
882 neighbourx = b.TriggerRegionX;
883
884 Vector3 newposition = pos;
885 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
886 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
887 agent.ControllingClient.SendAgentAlertMessage(
888 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
889 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
890 return true;
891 }
892 }
893
894 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
895 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
896 {
897 neighbourx--;
898 newpos.X = Constants.RegionSize - enterDistance;
899 }
900 else
901 {
902 agent.IsInTransit = true;
903
904 neighboury = ba.TriggerRegionY;
905 neighbourx = ba.TriggerRegionX;
906
907 Vector3 newposition = pos;
908 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
909 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
910 agent.ControllingClient.SendAgentAlertMessage(
911 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
912 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
913
914 return true;
915 } 889 }
916 890
891 neighbourx--;
892 newpos.X = Constants.RegionSize - enterDistance;
917 } 893 }
918 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 894 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
919 { 895 {
@@ -923,26 +899,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
923 899
924 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 900 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
925 { 901 {
926 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 902 neighboury--;
927 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 903 newpos.Y = Constants.RegionSize - enterDistance;
928 {
929 neighboury--;
930 newpos.Y = Constants.RegionSize - enterDistance;
931 }
932 else
933 {
934 agent.IsInTransit = true;
935
936 neighboury = ba.TriggerRegionY;
937 neighbourx = ba.TriggerRegionX;
938 Vector3 newposition = pos;
939 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
940 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
941 agent.ControllingClient.SendAgentAlertMessage(
942 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
943 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
944 return true;
945 }
946 } 904 }
947 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 905 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
948 { 906 {
@@ -954,25 +912,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
954 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 912 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
955 { 913 {
956 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 914 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
957 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 915 neighboury--;
958 { 916 newpos.Y = Constants.RegionSize - enterDistance;
959 neighboury--;
960 newpos.Y = Constants.RegionSize - enterDistance;
961 }
962 else
963 {
964 agent.IsInTransit = true;
965
966 neighboury = b.TriggerRegionY;
967 neighbourx = b.TriggerRegionX;
968 Vector3 newposition = pos;
969 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
970 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
971 agent.ControllingClient.SendAgentAlertMessage(
972 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
973 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
974 return true;
975 }
976 } 917 }
977 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 918 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
978 { 919 {
@@ -1006,19 +947,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1006 } 947 }
1007 */ 948 */
1008 949
1009 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 950 xDest = neighbourx;
951 yDest = neighboury;
1010 952
1011 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 953 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1012 954
955 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
956
1013 ExpiringCache<ulong, DateTime> r; 957 ExpiringCache<ulong, DateTime> r;
1014 DateTime banUntil; 958 DateTime banUntil;
1015 959
1016 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 960 if (m_bannedRegions.TryGetValue(agentID, out r))
1017 { 961 {
1018 if (r.TryGetValue(neighbourHandle, out banUntil)) 962 if (r.TryGetValue(neighbourHandle, out banUntil))
1019 { 963 {
1020 if (DateTime.Now < banUntil) 964 if (DateTime.Now < banUntil)
1021 return false; 965 return null;
1022 r.Remove(neighbourHandle); 966 r.Remove(neighbourHandle);
1023 } 967 }
1024 } 968 }
@@ -1030,28 +974,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1030 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 974 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1031 975
1032 string reason; 976 string reason;
1033 string version; 977 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1034 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1035 { 978 {
1036 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1037 if (r == null) 979 if (r == null)
1038 { 980 {
1039 r = new ExpiringCache<ulong, DateTime>(); 981 r = new ExpiringCache<ulong, DateTime>();
1040 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 982 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1041 983
1042 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 984 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1043 } 985 }
1044 else 986 else
1045 { 987 {
1046 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 988 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1047 } 989 }
990 return null;
991 }
992
993 return neighbourRegion;
994 }
995
996 public bool Cross(ScenePresence agent, bool isFlying)
997 {
998 uint x;
999 uint y;
1000 Vector3 newpos;
1001 string version;
1002
1003 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1004 if (neighbourRegion == null)
1005 {
1006 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1048 return false; 1007 return false;
1049 } 1008 }
1050 1009
1051 agent.IsInTransit = true; 1010 agent.IsInTransit = true;
1052 1011
1053 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1012 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1054 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1013 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1055 1014
1056 return true; 1015 return true;
1057 } 1016 }
@@ -1120,44 +1079,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1120 icon.EndInvoke(iar); 1079 icon.EndInvoke(iar);
1121 } 1080 }
1122 1081
1123 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1082 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1083 {
1084 if (neighbourRegion == null)
1085 return false;
1086
1087 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1088
1089 agent.RemoveFromPhysicalScene();
1090
1091 return true;
1092 }
1124 1093
1125 /// <summary> 1094 /// <summary>
1126 /// This Closes child agents on neighbouring regions 1095 /// This Closes child agents on neighbouring regions
1127 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1096 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1128 /// </summary> 1097 /// </summary>
1129 protected ScenePresence CrossAgentToNewRegionAsync( 1098 public ScenePresence CrossAgentToNewRegionAsync(
1130 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1099 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1131 bool isFlying, string version) 1100 bool isFlying, string version)
1132 { 1101 {
1133 if (neighbourRegion == null) 1102 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1134 return agent; 1103 return agent;
1135 1104
1136 try 1105 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1137 { 1106 return agent;
1138 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1139
1140 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
1141
1142 m_log.DebugFormat(
1143 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1144 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1145
1146 Scene m_scene = agent.Scene;
1147
1148 if (!agent.ValidateAttachments())
1149 m_log.DebugFormat(
1150 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1151 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1152
1153 pos = pos + agent.Velocity;
1154 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1155 1107
1156 agent.RemoveFromPhysicalScene(); 1108 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1109 return agent;
1110 }
1157 1111
1112 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1113 {
1114 try
1115 {
1158 AgentData cAgent = new AgentData(); 1116 AgentData cAgent = new AgentData();
1159 agent.CopyTo(cAgent); 1117 agent.CopyTo(cAgent);
1160 cAgent.Position = pos; 1118 cAgent.Position = pos + agent.Velocity;
1161 if (isFlying) 1119 if (isFlying)
1162 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1120 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1163 1121
@@ -1167,7 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1167 // Beyond this point, extra cleanup is needed beyond removing transit state 1125 // Beyond this point, extra cleanup is needed beyond removing transit state
1168 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1126 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1169 1127
1170 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1128 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1171 { 1129 {
1172 // region doesn't take it 1130 // region doesn't take it
1173 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1131 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1176,93 +1134,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1176 agent.AddToPhysicalScene(isFlying); 1134 agent.AddToPhysicalScene(isFlying);
1177 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1135 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1178 1136
1179 return agent; 1137 return false;
1180 } 1138 }
1181 1139
1182 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1140 }
1183 agent.ControllingClient.RequestClientInfo(); 1141 catch (Exception e)
1142 {
1143 m_log.ErrorFormat(
1144 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1145 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1184 1146
1185 //m_log.Debug("BEFORE CROSS"); 1147 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1186 //Scene.DumpChildrenSeeds(UUID); 1148 return false;
1187 //DumpKnownRegions(); 1149 }
1188 string agentcaps;
1189 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1190 {
1191 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1192 neighbourRegion.RegionHandle);
1193 return agent;
1194 }
1195 // No turning back
1196 agent.IsChildAgent = true;
1197 1150
1198 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1151 return true;
1152 }
1199 1153
1200 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1154 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1155 bool isFlying, string version)
1156 {
1157 agent.ControllingClient.RequestClientInfo();
1201 1158
1202 if (m_eqModule != null) 1159 string agentcaps;
1203 { 1160 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1204 m_eqModule.CrossRegion( 1161 {
1205 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1162 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1206 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1163 neighbourRegion.RegionHandle);
1207 } 1164 return;
1208 else 1165 }
1209 {
1210 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1211 capsPath);
1212 }
1213 1166
1214 // SUCCESS! 1167 // No turning back
1215 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1168 agent.IsChildAgent = true;
1216 1169
1217 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1170 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1218 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1219 1171
1220 agent.MakeChildAgent(); 1172 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1173
1174 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1175
1176 if (m_eqModule != null)
1177 {
1178 m_eqModule.CrossRegion(
1179 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1180 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1181 }
1182 else
1183 {
1184 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1185 capsPath);
1186 }
1221 1187
1222 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1188 // SUCCESS!
1223 // but not sure yet what the side effects would be. 1189 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1224 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1225 1190
1226 // now we have a child agent in this region. Request all interesting data about other (root) agents 1191 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1227 agent.SendOtherAgentsAvatarDataToMe(); 1192 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1228 agent.SendOtherAgentsAppearanceToMe();
1229 1193
1230 // Backwards compatibility. Best effort 1194 agent.MakeChildAgent();
1231 if (version == "Unknown" || version == string.Empty)
1232 {
1233 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1234 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1235 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1236 }
1237 1195
1238 // Next, let's close the child agent connections that are too far away. 1196 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1239 agent.CloseChildAgents(neighbourx, neighboury); 1197 // but not sure yet what the side effects would be.
1198 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1240 1199
1241 AgentHasMovedAway(agent, false); 1200 // now we have a child agent in this region. Request all interesting data about other (root) agents
1201 agent.SendOtherAgentsAvatarDataToMe();
1202 agent.SendOtherAgentsAppearanceToMe();
1242 1203
1243// // the user may change their profile information in other region, 1204 // Backwards compatibility. Best effort
1244// // so the userinfo in UserProfileCache is not reliable any more, delete it 1205 if (version == "Unknown" || version == string.Empty)
1245// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1246// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1247// {
1248// m_log.DebugFormat(
1249// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1250// }
1251
1252 //m_log.Debug("AFTER CROSS");
1253 //Scene.DumpChildrenSeeds(UUID);
1254 //DumpKnownRegions();
1255 }
1256 catch (Exception e)
1257 { 1206 {
1258 m_log.ErrorFormat( 1207 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1259 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", 1208 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1260 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); 1209 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1261
1262 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1263 } 1210 }
1264 1211
1265 return agent; 1212 // Next, let's close the child agent connections that are too far away.
1213 uint neighbourx;
1214 uint neighboury;
1215
1216 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1217
1218 neighbourx /= Constants.RegionSize;
1219 neighboury /= Constants.RegionSize;
1220
1221 agent.CloseChildAgents(neighbourx, neighboury);
1222
1223 AgentHasMovedAway(agent, false);
1224
1225 // the user may change their profile information in other region,
1226 // so the userinfo in UserProfileCache is not reliable any more, delete it
1227 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1228// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1229// {
1230// m_log.DebugFormat(
1231// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1232// }
1233
1234 //m_log.Debug("AFTER CROSS");
1235 //Scene.DumpChildrenSeeds(UUID);
1236 //DumpKnownRegions();
1237
1238 return;
1266 } 1239 }
1267 1240
1268 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1241 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1333,10 +1306,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1333 agent.Id0 = currentAgentCircuit.Id0; 1306 agent.Id0 = currentAgentCircuit.Id0;
1334 } 1307 }
1335 1308
1336 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1309 IPEndPoint external = region.ExternalEndPoint;
1337 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1310 if (external != null)
1311 {
1312 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1313 d.BeginInvoke(sp, agent, region, external, true,
1338 InformClientOfNeighbourCompleted, 1314 InformClientOfNeighbourCompleted,
1339 d); 1315 d);
1316 }
1340 } 1317 }
1341 #endregion 1318 #endregion
1342 1319
@@ -1917,27 +1894,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1917 Utils.LongToUInts(newRegionHandle, out x, out y); 1894 Utils.LongToUInts(newRegionHandle, out x, out y);
1918 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1895 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1919 1896
1920 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 1897 if (destination != null)
1921 { 1898 {
1922 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 1899 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
1900 return; // we did it
1901 }
1923 1902
1924 // We are going to move the object back to the old position so long as the old position 1903 // no one or failed lets go back and tell physics to go on
1925 // is in the region 1904 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
1926 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 1905 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
1927 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 1906 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
1928 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
1929 1907
1930 grp.RootPart.GroupPosition = oldGroupPosition; 1908 grp.AbsolutePosition = oldGroupPosition;
1909 grp.Velocity = Vector3.Zero;
1931 1910
1932 // Need to turn off the physics flags, otherwise the object will continue to attempt to 1911 if (grp.RootPart.PhysActor != null)
1933 // move out of the region creating an infinite loop of failed attempts to cross 1912 grp.RootPart.PhysActor.CrossingFailure();
1934 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1935 1913
1936 grp.ScheduleGroupForFullUpdate(); 1914 if (grp.RootPart.KeyframeMotion != null)
1937 } 1915 grp.RootPart.KeyframeMotion.CrossingFailure();
1916
1917 grp.ScheduleGroupForFullUpdate();
1938 } 1918 }
1939 1919
1940 1920
1921
1941 /// <summary> 1922 /// <summary>
1942 /// Move the given scene object into a new region 1923 /// Move the given scene object into a new region
1943 /// </summary> 1924 /// </summary>
@@ -1988,17 +1969,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1988 grp, e); 1969 grp, e);
1989 } 1970 }
1990 } 1971 }
1972/*
1973 * done on caller ( not in attachments crossing for now)
1991 else 1974 else
1992 { 1975 {
1976
1993 if (!grp.IsDeleted) 1977 if (!grp.IsDeleted)
1994 { 1978 {
1995 PhysicsActor pa = grp.RootPart.PhysActor; 1979 PhysicsActor pa = grp.RootPart.PhysActor;
1996 if (pa != null) 1980 if (pa != null)
1981 {
1997 pa.CrossingFailure(); 1982 pa.CrossingFailure();
1983 if (grp.RootPart.KeyframeMotion != null)
1984 {
1985 // moved to KeyframeMotion.CrossingFailure
1986// grp.RootPart.Velocity = Vector3.Zero;
1987 grp.RootPart.KeyframeMotion.CrossingFailure();
1988// grp.SendGroupRootTerseUpdate();
1989 }
1990 }
1998 } 1991 }
1999 1992
2000 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 1993 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2001 } 1994 }
1995 */
2002 } 1996 }
2003 else 1997 else
2004 { 1998 {
@@ -2083,4 +2077,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2083 #endregion 2077 #endregion
2084 2078
2085 } 2079 }
2086} \ No newline at end of file 2080}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index d0cab49..70dd1bc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
218 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 218 id, m_mod.Scene.RegionInfo.RegionName, currentState));
219 } 219 }
220 220
221 int count = 200; 221 int count = 400;
222 222
223 // There should be no race condition here since no other code should be removing the agent transfer or 223 // There should be no race condition here since no other code should be removing the agent transfer or
224 // changing the state to another other than Transferring => ReceivedAtDestination. 224 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -266,4 +266,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
266 } 266 }
267 } 267 }
268 } 268 }
269} \ No newline at end of file 269}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 41ca13b..f3a0b01 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 8b7c16e..6e5a4a5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -182,44 +182,49 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
182 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 182 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
183 return; 183 return;
184 184
185 if (transactionID == UUID.Zero) 185 InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
186 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
187
188 if (folder == null || folder.Owner != remoteClient.AgentId)
189 return;
190
191 if (transactionID != UUID.Zero)
186 { 192 {
187 ScenePresence presence; 193 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
188 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 194 if (agentTransactions != null)
189 { 195 {
190 byte[] data = null; 196 if (agentTransactions.HandleItemCreationFromTransaction(
197 remoteClient, transactionID, folderID, callbackID, description,
198 name, invType, assetType, wearableType, nextOwnerMask))
199 return;
200 }
201 }
191 202
192 if (invType == (sbyte)InventoryType.Landmark && presence != null) 203 ScenePresence presence;
193 { 204 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
194 string suffix = string.Empty, prefix = string.Empty; 205 {
195 string strdata = GenerateLandmark(presence, out prefix, out suffix); 206 byte[] data = null;
196 data = Encoding.ASCII.GetBytes(strdata);
197 name = prefix + name;
198 description += suffix;
199 }
200 207
201 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); 208 if (invType == (sbyte)InventoryType.Landmark && presence != null)
202 m_Scene.AssetService.Store(asset);
203 m_Scene.CreateNewInventoryItem(
204 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
205 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
206 }
207 else
208 { 209 {
209 m_log.ErrorFormat( 210 string suffix = string.Empty, prefix = string.Empty;
210 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", 211 string strdata = GenerateLandmark(presence, out prefix, out suffix);
211 remoteClient.AgentId); 212 data = Encoding.ASCII.GetBytes(strdata);
213 name = prefix + name;
214 description += suffix;
212 } 215 }
216
217 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
218 m_Scene.AssetService.Store(asset);
219 m_Scene.CreateNewInventoryItem(
220 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
221 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID);
213 } 222 }
214 else 223 else
215 { 224 {
216 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; 225 m_log.ErrorFormat(
217 if (agentTransactions != null) 226 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
218 { 227 remoteClient.AgentId);
219 agentTransactions.HandleItemCreationFromTransaction(
220 remoteClient, transactionID, folderID, callbackID, description,
221 name, invType, assetType, wearableType, nextOwnerMask);
222 }
223 } 228 }
224 } 229 }
225 230
@@ -356,6 +361,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
356 361
357 foreach (SceneObjectGroup objectGroup in objlist) 362 foreach (SceneObjectGroup objectGroup in objlist)
358 { 363 {
364 if (objectGroup.RootPart.KeyframeMotion != null)
365 objectGroup.RootPart.KeyframeMotion.Stop();
366 objectGroup.RootPart.SetForce(Vector3.Zero);
367 objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
368 objectGroup.RootPart.KeyframeMotion = null;
369
359 Vector3 inventoryStoredPosition = new Vector3 370 Vector3 inventoryStoredPosition = new Vector3
360 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 371 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
361 ? 250 372 ? 250
@@ -366,9 +377,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
366 : objectGroup.AbsolutePosition.Y, 377 : objectGroup.AbsolutePosition.Y,
367 objectGroup.AbsolutePosition.Z); 378 objectGroup.AbsolutePosition.Z);
368 379
380 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
369 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 381 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
370 382
383 // Restore attachment data after trip through the sim
384 if (objectGroup.RootPart.AttachPoint > 0)
385 {
386 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
387 inventoryStoredRotation = objectGroup.RootPart.AttachRotation;
388 }
389 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
390
371 objectGroup.AbsolutePosition = inventoryStoredPosition; 391 objectGroup.AbsolutePosition = inventoryStoredPosition;
392 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
372 393
373 // Make sure all bits but the ones we want are clear 394 // Make sure all bits but the ones we want are clear
374 // on take. 395 // on take.
@@ -486,8 +507,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
486 IClientAPI remoteClient) 507 IClientAPI remoteClient)
487 { 508 {
488 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; 509 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
510 // For the porposes of inventory, an object is modify if the prims
511 // are modify. This allows renaming an object that contains no
512 // mod items.
489 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 513 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
490 effectivePerms &= grp.GetEffectivePermissions(); 514 {
515 uint groupPerms = grp.GetEffectivePermissions(true);
516 if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0)
517 groupPerms |= (uint)PermissionMask.Modify;
518
519 effectivePerms &= groupPerms;
520 }
491 effectivePerms |= (uint)PermissionMask.Move; 521 effectivePerms |= (uint)PermissionMask.Move;
492 522
493 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 523 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
@@ -666,7 +696,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
666 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) 696 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
667 { 697 {
668 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 698 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
669 folder = m_Scene.InventoryService.GetFolder(f); 699 if (f != null)
700 folder = m_Scene.InventoryService.GetFolder(f);
670 } 701 }
671 } 702 }
672 703
@@ -696,16 +727,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
696 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 727 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
697 { 728 {
698// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 729// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
699
700 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 730 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
701 item = m_Scene.InventoryService.GetItem(item); 731 item = m_Scene.InventoryService.GetItem(item);
702 732
703 if (item == null) 733 if (item == null)
704 { 734 {
705 m_log.WarnFormat(
706 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
707 itemID, remoteClient.Name);
708
709 return null; 735 return null;
710 } 736 }
711 737
@@ -756,6 +782,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
756 if (e == null || attachment) // Single 782 if (e == null || attachment) // Single
757 { 783 {
758 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 784 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
785 if (!attachment)
786 {
787 g.RootPart.AttachPoint = g.RootPart.Shape.State;
788 g.RootPart.AttachOffset = g.AbsolutePosition;
789 g.RootPart.AttachRotation = g.GroupRotation;
790 g.RootPart.Shape.State = 0;
791 }
759 792
760 objlist.Add(g); 793 objlist.Add(g);
761 veclist.Add(new Vector3(0, 0, 0)); 794 veclist.Add(new Vector3(0, 0, 0));
@@ -785,6 +818,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
785 foreach (XmlNode n in groups) 818 foreach (XmlNode n in groups)
786 { 819 {
787 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); 820 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
821 g.RootPart.AttachPoint = g.RootPart.Shape.State;
822 g.RootPart.AttachOffset = g.AbsolutePosition;
823 g.RootPart.AttachRotation = g.GroupRotation;
824 g.RootPart.Shape.State = 0;
788 825
789 objlist.Add(g); 826 objlist.Add(g);
790 XmlElement el = (XmlElement)n; 827 XmlElement el = (XmlElement)n;
@@ -804,12 +841,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
804 } 841 }
805 } 842 }
806 843
844 int primcount = 0;
845 foreach (SceneObjectGroup g in objlist)
846 primcount += g.PrimCount;
847
848 if (!m_Scene.Permissions.CanRezObject(
849 primcount, remoteClient.AgentId, pos)
850 && !attachment)
851 {
852 // The client operates in no fail mode. It will
853 // have already removed the item from the folder
854 // if it's no copy.
855 // Put it back if it's not an attachment
856 //
857 if (item != null)
858 {
859 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
860 remoteClient.SendBulkUpdateInventory(item);
861 }
862
863 return null;
864 }
865
807 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) 866 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
808 return null; 867 return null;
809 868
810 for (int i = 0; i < objlist.Count; i++) 869 for (int i = 0; i < objlist.Count; i++)
811 { 870 {
812 group = objlist[i]; 871 group = objlist[i];
872 SceneObjectPart rootPart = group.RootPart;
813 873
814// m_log.DebugFormat( 874// m_log.DebugFormat(
815// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 875// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -870,8 +930,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
870 930
871 if (!attachment) 931 if (!attachment)
872 { 932 {
873 SceneObjectPart rootPart = group.RootPart;
874
875 if (rootPart.Shape.PCode == (byte)PCode.Prim) 933 if (rootPart.Shape.PCode == (byte)PCode.Prim)
876 group.ClearPartAttachmentData(); 934 group.ClearPartAttachmentData();
877 935
@@ -889,6 +947,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
889// remoteClient.Name); 947// remoteClient.Name);
890 } 948 }
891 949
950 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
951
892 if (item != null) 952 if (item != null)
893 DoPostRezWhenFromItem(item, attachment); 953 DoPostRezWhenFromItem(item, attachment);
894 954
@@ -967,8 +1027,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
967 { 1027 {
968 rootPart.Name = item.Name; 1028 rootPart.Name = item.Name;
969 rootPart.Description = item.Description; 1029 rootPart.Description = item.Description;
970 rootPart.ObjectSaleType = item.SaleType; 1030 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
971 rootPart.SalePrice = item.SalePrice; 1031 {
1032 rootPart.ObjectSaleType = item.SaleType;
1033 rootPart.SalePrice = item.SalePrice;
1034 }
972 } 1035 }
973 1036
974 so.FromFolderID = item.Folder; 1037 so.FromFolderID = item.Folder;
@@ -978,7 +1041,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
978// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1041// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
979 1042
980 if ((rootPart.OwnerID != item.Owner) || 1043 if ((rootPart.OwnerID != item.Owner) ||
981 (item.CurrentPermissions & 16) != 0) 1044 (item.CurrentPermissions & 16) != 0 ||
1045 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
982 { 1046 {
983 //Need to kill the for sale here 1047 //Need to kill the for sale here
984 rootPart.ObjectSaleType = 0; 1048 rootPart.ObjectSaleType = 0;
@@ -988,31 +1052,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
988 { 1052 {
989 foreach (SceneObjectPart part in so.Parts) 1053 foreach (SceneObjectPart part in so.Parts)
990 { 1054 {
991 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
992 {
993 part.EveryoneMask = item.EveryOnePermissions;
994 part.NextOwnerMask = item.NextPermissions;
995 }
996 part.GroupMask = 0; // DO NOT propagate here 1055 part.GroupMask = 0; // DO NOT propagate here
1056
1057 part.LastOwnerID = part.OwnerID;
1058 part.OwnerID = item.Owner;
1059 part.Inventory.ChangeInventoryOwner(item.Owner);
997 } 1060 }
998 1061
999 so.ApplyNextOwnerPermissions(); 1062 so.ApplyNextOwnerPermissions();
1063
1064 // In case the user has changed flags on a received item
1065 // we have to apply those changes after the slam. Else we
1066 // get a net loss of permissions
1067 foreach (SceneObjectPart part in so.Parts)
1068 {
1069 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1070 {
1071 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1072 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1073 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1074 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1075 }
1076 }
1000 } 1077 }
1001 } 1078 }
1002 1079 else
1003 foreach (SceneObjectPart part in so.Parts)
1004 { 1080 {
1005 part.FromUserInventoryItemID = fromUserInventoryItemId; 1081 foreach (SceneObjectPart part in so.Parts)
1006
1007 if ((part.OwnerID != item.Owner) ||
1008 (item.CurrentPermissions & 16) != 0)
1009 { 1082 {
1010 part.Inventory.ChangeInventoryOwner(item.Owner); 1083 part.FromUserInventoryItemID = fromUserInventoryItemId;
1011 part.GroupMask = 0; // DO NOT propagate here 1084
1085 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1086 part.EveryoneMask = item.EveryOnePermissions;
1087 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1088 part.NextOwnerMask = item.NextPermissions;
1089 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1090 part.GroupMask = item.GroupPermissions;
1012 } 1091 }
1013
1014 part.EveryoneMask = item.EveryOnePermissions;
1015 part.NextOwnerMask = item.NextPermissions;
1016 } 1092 }
1017 1093
1018 rootPart.TrimPermissions(); 1094 rootPart.TrimPermissions();
@@ -1150,4 +1226,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1150 1226
1151 #endregion 1227 #endregion
1152 } 1228 }
1153} \ No newline at end of file 1229}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index e0921ad..ec94420 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..a0ae203 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -398,6 +398,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
398 try 398 try
399 { 399 {
400 Request = (HttpWebRequest) WebRequest.Create(Url); 400 Request = (HttpWebRequest) WebRequest.Create(Url);
401
402 //This works around some buggy HTTP Servers like Lighttpd
403 Request.ServicePoint.Expect100Continue = false;
404
401 Request.Method = HttpMethod; 405 Request.Method = HttpMethod;
402 Request.ContentType = HttpMIMEType; 406 Request.ContentType = HttpMIMEType;
403 407
@@ -474,15 +478,36 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
474 478
475 // continue building the string 479 // continue building the string
476 sb.Append(tempString); 480 sb.Append(tempString);
481 if (sb.Length > 2048)
482 break;
477 } 483 }
478 } while (count > 0); // any more data to read? 484 } while (count > 0); // any more data to read?
479 485
480 ResponseBody = sb.ToString(); 486 ResponseBody = sb.ToString().Replace("\r", "");
481 } 487 }
482 catch (Exception e) 488 catch (Exception e)
483 { 489 {
484 Status = (int)OSHttpStatusCode.ClientErrorJoker; 490 if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError)
485 ResponseBody = e.Message; 491 {
492 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
493 Status = (int)webRsp.StatusCode;
494 try
495 {
496 using (Stream responseStream = webRsp.GetResponseStream())
497 {
498 ResponseBody = responseStream.GetStreamString();
499 }
500 }
501 catch
502 {
503 ResponseBody = webRsp.StatusDescription;
504 }
505 }
506 else
507 {
508 Status = (int)OSHttpStatusCode.ClientErrorJoker;
509 ResponseBody = e.Message;
510 }
486 511
487 _finished = true; 512 _finished = true;
488 return; 513 return;
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index a654477..da59eab 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -42,39 +42,13 @@ 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;
79 } 53 }
80 54
@@ -89,6 +63,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
89 //public ManualResetEvent ev; 63 //public ManualResetEvent ev;
90 public bool requestDone; 64 public bool requestDone;
91 public int startTime; 65 public int startTime;
66 public bool responseSent;
92 public string uri; 67 public string uri;
93 } 68 }
94 69
@@ -102,25 +77,16 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
102 LogManager.GetLogger( 77 LogManager.GetLogger(
103 MethodBase.GetCurrentMethod().DeclaringType); 78 MethodBase.GetCurrentMethod().DeclaringType);
104 79
105 /// <summary> 80 private Dictionary<UUID, UrlData> m_RequestMap =
106 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 81 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 82
115 /// <summary> 83 private Dictionary<string, UrlData> m_UrlMap =
116 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 84 new Dictionary<string, UrlData>();
117 /// </summary>
118 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
119 85
120 /// <summary> 86 /// <summary>
121 /// Maximum number of external urls that can be set up by this module. 87 /// Maximum number of external urls that can be set up by this module.
122 /// </summary> 88 /// </summary>
123 private int m_TotalUrls = 100; 89 private int m_TotalUrls = 15000;
124 90
125 private uint https_port = 0; 91 private uint https_port = 0;
126 private IHttpServer m_HttpServer = null; 92 private IHttpServer m_HttpServer = null;
@@ -146,9 +112,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
146 { 112 {
147 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 113 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
148 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); 114 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
149
150 if (ssl_enabled) 115 if (ssl_enabled)
116 {
151 https_port = (uint) config.Configs["Network"].GetInt("https_port",0); 117 https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
118 }
152 119
153 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 120 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
154 121
@@ -209,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
209 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 176 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
210 return urlcode; 177 return urlcode;
211 } 178 }
212 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 179 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
213 180
214 UrlData urlData = new UrlData(); 181 UrlData urlData = new UrlData();
215 urlData.hostID = host.UUID; 182 urlData.hostID = host.UUID;
@@ -218,18 +185,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
218 urlData.url = url; 185 urlData.url = url;
219 urlData.urlcode = urlcode; 186 urlData.urlcode = urlcode;
220 urlData.requests = new Dictionary<UUID, RequestData>(); 187 urlData.requests = new Dictionary<UUID, RequestData>();
221 188
222 m_UrlMap[url] = urlData; 189 m_UrlMap[url] = urlData;
223 190
224 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 191 string uri = "/lslhttp/" + urlcode.ToString();
225 192
226 m_HttpServer.AddPollServiceHTTPHandler( 193 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
227 uri, 194 args.Type = PollServiceEventArgs.EventType.LslHttp;
228 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 195 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
229 196
230 m_log.DebugFormat( 197// m_log.DebugFormat(
231 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 198// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
232 uri, itemID, host.Name, host.LocalId); 199// uri, itemID, host.Name, host.LocalId);
233 200
234 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 201 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
235 } 202 }
@@ -254,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
254 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 221 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
255 return urlcode; 222 return urlcode;
256 } 223 }
257 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 224 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
258 225
259 UrlData urlData = new UrlData(); 226 UrlData urlData = new UrlData();
260 urlData.hostID = host.UUID; 227 urlData.hostID = host.UUID;
@@ -264,17 +231,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
264 urlData.urlcode = urlcode; 231 urlData.urlcode = urlcode;
265 urlData.requests = new Dictionary<UUID, RequestData>(); 232 urlData.requests = new Dictionary<UUID, RequestData>();
266 233
234
267 m_UrlMap[url] = urlData; 235 m_UrlMap[url] = urlData;
268 236
269 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 237 string uri = "/lslhttps/" + urlcode.ToString();
270 238
271 m_HttpsServer.AddPollServiceHTTPHandler( 239 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
272 uri, 240 args.Type = PollServiceEventArgs.EventType.LslHttp;
273 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 241 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
274 242
275 m_log.DebugFormat( 243// m_log.DebugFormat(
276 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 244// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
277 uri, itemID, host.Name, host.LocalId); 245// uri, itemID, host.Name, host.LocalId);
278 246
279 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 247 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
280 } 248 }
@@ -293,12 +261,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
293 return; 261 return;
294 } 262 }
295 263
296 foreach (UUID req in data.requests.Keys) 264 lock (m_RequestMap)
297 m_RequestMap.Remove(req); 265 {
298 266 foreach (UUID req in data.requests.Keys)
299 m_log.DebugFormat( 267 m_RequestMap.Remove(req);
300 "[URL MODULE]: Releasing url {0} for {1} in {2}", 268 }
301 url, data.itemID, data.hostID); 269
270// m_log.DebugFormat(
271// "[URL MODULE]: Releasing url {0} for {1} in {2}",
272// url, data.itemID, data.hostID);
302 273
303 RemoveUrl(data); 274 RemoveUrl(data);
304 m_UrlMap.Remove(url); 275 m_UrlMap.Remove(url);
@@ -323,15 +294,19 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
323 294
324 public void HttpResponse(UUID request, int status, string body) 295 public void HttpResponse(UUID request, int status, string body)
325 { 296 {
326 lock (m_UrlMap) 297 lock (m_RequestMap)
327 { 298 {
328 if (m_RequestMap.ContainsKey(request)) 299 if (m_RequestMap.ContainsKey(request))
329 { 300 {
330 UrlData urlData = m_RequestMap[request]; 301 UrlData urlData = m_RequestMap[request];
331 urlData.requests[request].responseCode = status; 302 if (!urlData.requests[request].responseSent)
332 urlData.requests[request].responseBody = body; 303 {
333 //urlData.requests[request].ev.Set(); 304 urlData.requests[request].responseCode = status;
334 urlData.requests[request].requestDone =true; 305 urlData.requests[request].responseBody = body;
306 //urlData.requests[request].ev.Set();
307 urlData.requests[request].requestDone = true;
308 urlData.requests[request].responseSent = true;
309 }
335 } 310 }
336 else 311 else
337 { 312 {
@@ -342,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
342 317
343 public string GetHttpHeader(UUID requestId, string header) 318 public string GetHttpHeader(UUID requestId, string header)
344 { 319 {
345 lock (m_UrlMap) 320 lock (m_RequestMap)
346 { 321 {
347 if (m_RequestMap.ContainsKey(requestId)) 322 if (m_RequestMap.ContainsKey(requestId))
348 { 323 {
@@ -356,14 +331,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
356 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 331 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
357 } 332 }
358 } 333 }
359
360 return String.Empty; 334 return String.Empty;
361 } 335 }
362 336
363 public int GetFreeUrls() 337 public int GetFreeUrls()
364 { 338 {
365 lock (m_UrlMap) 339 return m_TotalUrls - m_UrlMap.Count;
366 return m_TotalUrls - m_UrlMap.Count;
367 } 340 }
368 341
369 public void ScriptRemoved(UUID itemID) 342 public void ScriptRemoved(UUID itemID)
@@ -380,8 +353,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
380 { 353 {
381 RemoveUrl(url.Value); 354 RemoveUrl(url.Value);
382 removeURLs.Add(url.Key); 355 removeURLs.Add(url.Key);
383 foreach (UUID req in url.Value.requests.Keys) 356 lock (m_RequestMap)
384 m_RequestMap.Remove(req); 357 {
358 foreach (UUID req in url.Value.requests.Keys)
359 m_RequestMap.Remove(req);
360 }
385 } 361 }
386 } 362 }
387 363
@@ -402,9 +378,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
402 { 378 {
403 RemoveUrl(url.Value); 379 RemoveUrl(url.Value);
404 removeURLs.Add(url.Key); 380 removeURLs.Add(url.Key);
405 381 lock (m_RequestMap)
406 foreach (UUID req in url.Value.requests.Keys) 382 {
407 m_RequestMap.Remove(req); 383 foreach (UUID req in url.Value.requests.Keys)
384 m_RequestMap.Remove(req);
385 }
408 } 386 }
409 } 387 }
410 388
@@ -413,123 +391,125 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
413 } 391 }
414 } 392 }
415 393
394
416 private void RemoveUrl(UrlData data) 395 private void RemoveUrl(UrlData data)
417 { 396 {
418 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 397 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
419 } 398 }
420 399
421 private Hashtable NoEvents(UUID requestID, UUID sessionID) 400 private Hashtable NoEvents(UUID requestID, UUID sessionID)
422 { 401 {
423 Hashtable response = new Hashtable(); 402 Hashtable response = new Hashtable();
424 UrlData urlData; 403 UrlData url;
425 404 int startTime = 0;
426 lock (m_UrlMap) 405 lock (m_RequestMap)
427 { 406 {
428 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
429 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
430 // for the request ID.
431 if (!m_RequestMap.ContainsKey(requestID)) 407 if (!m_RequestMap.ContainsKey(requestID))
432 {
433 response["int_response_code"] = 404;
434 response["str_response_string"] = "";
435 response["keepalive"] = false;
436 response["reusecontext"] = false;
437
438 return response; 408 return response;
439 } 409 url = m_RequestMap[requestID];
410 startTime = url.requests[requestID].startTime;
411 }
440 412
441 urlData = m_RequestMap[requestID]; 413 if (System.Environment.TickCount - startTime > 25000)
414 {
415 response["int_response_code"] = 500;
416 response["str_response_string"] = "Script timeout";
417 response["content_type"] = "text/plain";
418 response["keepalive"] = false;
419 response["reusecontext"] = false;
442 420
443 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 421 //remove from map
422 lock (url.requests)
423 {
424 url.requests.Remove(requestID);
425 }
426 lock (m_RequestMap)
444 { 427 {
445 response["int_response_code"] = 500;
446 response["str_response_string"] = "Script timeout";
447 response["content_type"] = "text/plain";
448 response["keepalive"] = false;
449 response["reusecontext"] = false;
450
451 //remove from map
452 urlData.requests.Remove(requestID);
453 m_RequestMap.Remove(requestID); 428 m_RequestMap.Remove(requestID);
454
455 return response;
456 } 429 }
430
431 return response;
457 } 432 }
458 433
434
459 return response; 435 return response;
460 } 436 }
461 437
462 private bool HasEvents(UUID requestID, UUID sessionID) 438 private bool HasEvents(UUID requestID, UUID sessionID)
463 { 439 {
464 lock (m_UrlMap) 440 UrlData url=null;
441
442 lock (m_RequestMap)
465 { 443 {
466 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
467 // can still make it through to HttpRequestHandler(). That will return without setting up a request
468 // when it detects that the URL has been removed. The poller, however, will continue to ask for
469 // events for that request, so here we will signal that there are events and in GetEvents we will
470 // return a 404.
471 if (!m_RequestMap.ContainsKey(requestID)) 444 if (!m_RequestMap.ContainsKey(requestID))
472 { 445 {
473 return true; 446 return false;
474 } 447 }
475 448 url = m_RequestMap[requestID];
476 UrlData urlData = m_RequestMap[requestID]; 449 }
477 450 lock (url.requests)
478 if (!urlData.requests.ContainsKey(requestID)) 451 {
452 if (!url.requests.ContainsKey(requestID))
479 { 453 {
480 return true; 454 return false;
481 } 455 }
482 456 else
483 // Trigger return of timeout response.
484 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
485 { 457 {
486 return true; 458 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
459 {
460 return true;
461 }
462 if (url.requests[requestID].requestDone)
463 return true;
464 else
465 return false;
487 } 466 }
488
489 return urlData.requests[requestID].requestDone;
490 } 467 }
491 } 468 }
492 469 private Hashtable GetEvents(UUID requestID, UUID sessionID)
493 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
494 { 470 {
495 Hashtable response; 471 UrlData url = null;
472 RequestData requestData = null;
496 473
497 lock (m_UrlMap) 474 lock (m_RequestMap)
498 { 475 {
499 UrlData url = null;
500 RequestData requestData = null;
501
502 if (!m_RequestMap.ContainsKey(requestID)) 476 if (!m_RequestMap.ContainsKey(requestID))
503 return NoEvents(requestID, sessionID); 477 return NoEvents(requestID,sessionID);
504
505 url = m_RequestMap[requestID]; 478 url = m_RequestMap[requestID];
479 }
480 lock (url.requests)
481 {
506 requestData = url.requests[requestID]; 482 requestData = url.requests[requestID];
483 }
484
485 if (!requestData.requestDone)
486 return NoEvents(requestID,sessionID);
487
488 Hashtable response = new Hashtable();
507 489
508 if (!requestData.requestDone) 490 if (System.Environment.TickCount - requestData.startTime > 25000)
509 return NoEvents(requestID, sessionID); 491 {
510 492 response["int_response_code"] = 500;
511 response = new Hashtable(); 493 response["str_response_string"] = "Script timeout";
512 494 response["content_type"] = "text/plain";
513 if (System.Environment.TickCount - requestData.startTime > 25000)
514 {
515 response["int_response_code"] = 500;
516 response["str_response_string"] = "Script timeout";
517 response["content_type"] = "text/plain";
518 response["keepalive"] = false;
519 response["reusecontext"] = false;
520 return response;
521 }
522
523 //put response
524 response["int_response_code"] = requestData.responseCode;
525 response["str_response_string"] = requestData.responseBody;
526 response["content_type"] = requestData.responseType;
527 // response["content_type"] = "text/plain";
528 response["keepalive"] = false; 495 response["keepalive"] = false;
529 response["reusecontext"] = false; 496 response["reusecontext"] = false;
530 497 return response;
531 //remove from map 498 }
499 //put response
500 response["int_response_code"] = requestData.responseCode;
501 response["str_response_string"] = requestData.responseBody;
502 response["content_type"] = "text/plain";
503 response["keepalive"] = false;
504 response["reusecontext"] = false;
505
506 //remove from map
507 lock (url.requests)
508 {
532 url.requests.Remove(requestID); 509 url.requests.Remove(requestID);
510 }
511 lock (m_RequestMap)
512 {
533 m_RequestMap.Remove(requestID); 513 m_RequestMap.Remove(requestID);
534 } 514 }
535 515
@@ -538,41 +518,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
538 518
539 public void HttpRequestHandler(UUID requestID, Hashtable request) 519 public void HttpRequestHandler(UUID requestID, Hashtable request)
540 { 520 {
541 string uri = request["uri"].ToString(); 521 lock (request)
542 bool is_ssl = uri.Contains("lslhttps");
543
544 try
545 { 522 {
546 Hashtable headers = (Hashtable)request["headers"]; 523 string uri = request["uri"].ToString();
547 524 bool is_ssl = uri.Contains("lslhttps");
548// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
549 525
550 int pos1 = uri.IndexOf("/");// /lslhttp 526 try
551 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
552 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
553 string uri_tmp = uri.Substring(0, pos3 + 1);
554 //HTTP server code doesn't provide us with QueryStrings
555 string pathInfo;
556 string queryString;
557 queryString = "";
558
559 pathInfo = uri.Substring(pos3);
560
561 UrlData urlData = null;
562
563 lock (m_UrlMap)
564 { 527 {
565 string url; 528 Hashtable headers = (Hashtable)request["headers"];
529
530// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
566 531
567 if (is_ssl) 532 int pos1 = uri.IndexOf("/");// /lslhttp
568 url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 533 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
534 int pos3 = pos2 + 37; // /lslhttp/urlcode
535 string uri_tmp = uri.Substring(0, pos3);
536 //HTTP server code doesn't provide us with QueryStrings
537 string pathInfo;
538 string queryString;
539 queryString = "";
540
541 pathInfo = uri.Substring(pos3);
542
543 UrlData url = null;
544 string urlkey;
545 if (!is_ssl)
546 urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
547 //m_UrlMap[];
569 else 548 else
570 url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 549 urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
571 550
572 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 551 if (m_UrlMap.ContainsKey(urlkey))
573 // request was being processed. 552 {
574 if (!m_UrlMap.TryGetValue(url, out urlData)) 553 url = m_UrlMap[urlkey];
554 }
555 else
556 {
557 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
575 return; 558 return;
559 }
576 560
577 //for llGetHttpHeader support we need to store original URI here 561 //for llGetHttpHeader support we need to store original URI here
578 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 562 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -592,7 +576,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
592 string value = (string)header.Value; 576 string value = (string)header.Value;
593 requestData.headers.Add(key, value); 577 requestData.headers.Add(key, value);
594 } 578 }
595
596 foreach (DictionaryEntry de in request) 579 foreach (DictionaryEntry de in request)
597 { 580 {
598 if (de.Key.ToString() == "querystringkeys") 581 if (de.Key.ToString() == "querystringkeys")
@@ -603,13 +586,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
603 if (request.ContainsKey(key)) 586 if (request.ContainsKey(key))
604 { 587 {
605 string val = (String)request[key]; 588 string val = (String)request[key];
606 queryString = queryString + key + "=" + val + "&"; 589 if (key != "")
590 {
591 queryString = queryString + key + "=" + val + "&";
592 }
593 else
594 {
595 queryString = queryString + val + "&";
596 }
607 } 597 }
608 } 598 }
609
610 if (queryString.Length > 1) 599 if (queryString.Length > 1)
611 queryString = queryString.Substring(0, queryString.Length - 1); 600 queryString = queryString.Substring(0, queryString.Length - 1);
601
612 } 602 }
603
613 } 604 }
614 605
615 //if this machine is behind DNAT/port forwarding, currently this is being 606 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -617,23 +608,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
617 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 608 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
618 requestData.headers["x-path-info"] = pathInfo; 609 requestData.headers["x-path-info"] = pathInfo;
619 requestData.headers["x-query-string"] = queryString; 610 requestData.headers["x-query-string"] = queryString;
620 requestData.headers["x-script-url"] = urlData.url; 611 requestData.headers["x-script-url"] = url.url;
621 612
622 urlData.requests.Add(requestID, requestData); 613 //requestData.ev = new ManualResetEvent(false);
623 m_RequestMap.Add(requestID, urlData); 614 lock (url.requests)
624 } 615 {
616 url.requests.Add(requestID, requestData);
617 }
618 lock (m_RequestMap)
619 {
620 //add to request map
621 m_RequestMap.Add(requestID, url);
622 }
625 623
626 urlData.engine.PostScriptEvent( 624 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
627 urlData.itemID, 625
628 "http_request", 626 //send initial response?
629 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 627// Hashtable response = new Hashtable();
630 } 628
631 catch (Exception we) 629 return;
632 { 630
633 //Hashtable response = new Hashtable(); 631 }
634 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 632 catch (Exception we)
635 m_log.Warn(we.Message); 633 {
636 m_log.Warn(we.StackTrace); 634 //Hashtable response = new Hashtable();
635 m_log.Warn("[HttpRequestHandler]: http-in request failed");
636 m_log.Warn(we.Message);
637 m_log.Warn(we.StackTrace);
638 }
637 } 639 }
638 } 640 }
639 641
@@ -642,4 +644,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
642 ScriptRemoved(itemID); 644 ScriptRemoved(itemID);
643 } 645 }
644 } 646 }
645} \ No newline at end of file 647}
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 689e8a7..f395441 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -852,4 +852,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
852 return null; 852 return null;
853 } 853 }
854 } 854 }
855} \ No newline at end of file 855}
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 a839086..5836eb9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -93,8 +93,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
93 if (config == null) 93 if (config == null)
94 return; 94 return;
95 95
96 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime")); 96 int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime", "-1"));
97 if (refreshminutes <= 0) 97 if (refreshminutes < 0)
98 { 98 {
99 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled."); 99 m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
100 return; 100 return;
@@ -117,12 +117,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
117 return; 117 return;
118 } 118 }
119 119
120 m_refreshTimer.Enabled = true; 120 if (m_refreshtime > 0)
121 m_refreshTimer.AutoReset = true; 121 {
122 m_refreshTimer.Interval = m_refreshtime; 122 m_refreshTimer.Enabled = true;
123 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh); 123 m_refreshTimer.AutoReset = true;
124 m_refreshTimer.Interval = m_refreshtime;
125 m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
126 }
124 127
125 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}", 128 m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0} min and service object {1}",
126 refreshminutes, service); 129 refreshminutes, service);
127 130
128 m_enabled = true; 131 m_enabled = true;
@@ -227,4 +230,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
227 } 230 }
228 } 231 }
229 } 232 }
230} \ No newline at end of file 233}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 3c18074..b485194 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -303,6 +303,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
303 return false; 303 return false;
304 } 304 }
305 305
306 public bool CloseChildAgent(GridRegion destination, UUID id)
307 {
308 return CloseAgent(destination, id);
309 }
310
306 public bool CloseAgent(GridRegion destination, UUID id) 311 public bool CloseAgent(GridRegion destination, UUID id)
307 { 312 {
308 if (destination == null) 313 if (destination == null)
@@ -317,7 +322,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
317 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); 322 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
318 return true; 323 return true;
319 } 324 }
320
321 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 325 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
322 return false; 326 return false;
323 } 327 }
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 c810242..01f1c63 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
@@ -887,4 +905,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
887 return dearchivedScenes; 905 return dearchivedScenes;
888 } 906 }
889 } 907 }
890} \ No newline at end of file 908}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 103eb47..e2f8833 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -269,18 +269,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
269 269
270 if (asset != null) 270 if (asset != null)
271 { 271 {
272 if (m_options.ContainsKey("verbose")) 272// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
273 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
274
275 m_foundAssetUuids.Add(asset.FullID); 273 m_foundAssetUuids.Add(asset.FullID);
276 274
277 m_assetsArchiver.WriteAsset(PostProcess(asset)); 275 m_assetsArchiver.WriteAsset(PostProcess(asset));
278 } 276 }
279 else 277 else
280 { 278 {
281 if (m_options.ContainsKey("verbose")) 279// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
282 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
283
284 m_notFoundAssetUuids.Add(new UUID(id)); 280 m_notFoundAssetUuids.Add(new UUID(id));
285 } 281 }
286 282
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index eb06fcc..267332d 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
@@ -772,7 +799,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
772 ScenePresence s = Scene.GetScenePresence(prey); 799 ScenePresence s = Scene.GetScenePresence(prey);
773 if (s != null) 800 if (s != null)
774 { 801 {
775 Scene.TeleportClientHome(prey, s.ControllingClient); 802 if (!Scene.TeleportClientHome(prey, s.ControllingClient))
803 {
804 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
805 s.ControllingClient.Close();
806 }
776 } 807 }
777 } 808 }
778 } 809 }
@@ -790,7 +821,13 @@ namespace OpenSim.Region.CoreModules.World.Estate
790 // Also make sure they are actually in the region 821 // Also make sure they are actually in the region
791 ScenePresence p; 822 ScenePresence p;
792 if(Scene.TryGetScenePresence(client.AgentId, out p)) 823 if(Scene.TryGetScenePresence(client.AgentId, out p))
793 Scene.TeleportClientHome(p.UUID, p.ControllingClient); 824 {
825 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
826 {
827 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
828 p.ControllingClient.Close();
829 }
830 }
794 } 831 }
795 }); 832 });
796 } 833 }
@@ -1164,7 +1201,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1164 1201
1165 private void EventManager_OnNewClient(IClientAPI client) 1202 private void EventManager_OnNewClient(IClientAPI client)
1166 { 1203 {
1167 client.OnDetailedEstateDataRequest += sendDetailedEstateData; 1204 client.OnDetailedEstateDataRequest += clientSendDetailedEstateData;
1168 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler; 1205 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler;
1169// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture; 1206// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture;
1170 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture; 1207 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture;
@@ -1216,6 +1253,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1216 flags |= RegionFlags.AllowParcelChanges; 1253 flags |= RegionFlags.AllowParcelChanges;
1217 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1254 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1218 flags |= RegionFlags.BlockParcelSearch; 1255 flags |= RegionFlags.BlockParcelSearch;
1256 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1257 flags |= (RegionFlags)(1 << 11);
1258 if (Scene.RegionInfo.RegionSettings.Casino)
1259 flags |= (RegionFlags)(1 << 10);
1219 1260
1220 if (Scene.RegionInfo.RegionSettings.FixedSun) 1261 if (Scene.RegionInfo.RegionSettings.FixedSun)
1221 flags |= RegionFlags.SunFixed; 1262 flags |= RegionFlags.SunFixed;
@@ -1223,11 +1264,15 @@ namespace OpenSim.Region.CoreModules.World.Estate
1223 flags |= RegionFlags.Sandbox; 1264 flags |= RegionFlags.Sandbox;
1224 if (Scene.RegionInfo.EstateSettings.AllowVoice) 1265 if (Scene.RegionInfo.EstateSettings.AllowVoice)
1225 flags |= RegionFlags.AllowVoice; 1266 flags |= RegionFlags.AllowVoice;
1267 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1268 flags |= RegionFlags.AllowLandmark;
1269 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1270 flags |= RegionFlags.AllowSetHome;
1271 if (Scene.RegionInfo.EstateSettings.BlockDwell)
1272 flags |= RegionFlags.BlockDwell;
1273 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
1274 flags |= RegionFlags.ResetHomeOnTeleport;
1226 1275
1227 // Fudge these to always on, so the menu options activate
1228 //
1229 flags |= RegionFlags.AllowLandmark;
1230 flags |= RegionFlags.AllowSetHome;
1231 1276
1232 // TODO: SkipUpdateInterestList 1277 // TODO: SkipUpdateInterestList
1233 1278
@@ -1268,6 +1313,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1268 flags |= RegionFlags.ResetHomeOnTeleport; 1313 flags |= RegionFlags.ResetHomeOnTeleport;
1269 if (Scene.RegionInfo.EstateSettings.TaxFree) 1314 if (Scene.RegionInfo.EstateSettings.TaxFree)
1270 flags |= RegionFlags.TaxFree; 1315 flags |= RegionFlags.TaxFree;
1316 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1317 flags |= RegionFlags.AllowLandmark;
1318 if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
1319 flags |= RegionFlags.AllowParcelChanges;
1320 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1321 flags |= RegionFlags.AllowSetHome;
1271 if (Scene.RegionInfo.EstateSettings.DenyMinors) 1322 if (Scene.RegionInfo.EstateSettings.DenyMinors)
1272 flags |= (RegionFlags)(1 << 30); 1323 flags |= (RegionFlags)(1 << 30);
1273 1324
@@ -1288,6 +1339,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1288 1339
1289 public void TriggerRegionInfoChange() 1340 public void TriggerRegionInfoChange()
1290 { 1341 {
1342 m_regionChangeTimer.Stop();
1343 m_regionChangeTimer.Start();
1344 }
1345
1346 protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e)
1347 {
1291 ChangeDelegate change = OnRegionInfoChange; 1348 ChangeDelegate change = OnRegionInfoChange;
1292 1349
1293 if (change != null) 1350 if (change != null)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 7149aad..281c143 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)
@@ -162,13 +170,6 @@ namespace OpenSim.Region.CoreModules.World.Land
162 m_scene.UnregisterModuleCommander(m_commander.Name); 170 m_scene.UnregisterModuleCommander(m_commander.Name);
163 } 171 }
164 172
165// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
166// {
167// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
168// reason = "You are not allowed to enter this sim.";
169// return nearestParcel != null;
170// }
171
172 /// <summary> 173 /// <summary>
173 /// Processes commandline input. Do not call directly. 174 /// Processes commandline input. Do not call directly.
174 /// </summary> 175 /// </summary>
@@ -209,6 +210,8 @@ namespace OpenSim.Region.CoreModules.World.Land
209 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 210 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
210 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 211 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
211 client.OnPreAgentUpdate += ClientOnPreAgentUpdate; 212 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
213 client.OnParcelEjectUser += ClientOnParcelEjectUser;
214 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
212 215
213 EntityBase presenceEntity; 216 EntityBase presenceEntity;
214 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 217 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -220,48 +223,6 @@ namespace OpenSim.Region.CoreModules.World.Land
220 223
221 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 224 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
222 { 225 {
223 //If we are forcing a position for them to go
224 if (forcedPosition.ContainsKey(remoteClient.AgentId))
225 {
226 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
227
228 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
229 //When the avatar walks into a ban line on the ground, it prevents getting stuck
230 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
231
232 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
233 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
234 {
235// m_log.DebugFormat(
236// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
237// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
238
239 forcedPosition.Remove(remoteClient.AgentId);
240 }
241 //if we are far away, teleport
242 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
243 {
244 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
245// m_log.DebugFormat(
246// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
247// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
248
249 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
250 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
251
252 forcedPosition.Remove(remoteClient.AgentId);
253 }
254 else
255 {
256// m_log.DebugFormat(
257// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
258// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
259
260 //Forces them toward the forced position we want if they aren't there yet
261 agentData.UseClientAgentPosition = true;
262 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
263 }
264 }
265 } 226 }
266 227
267 public void Close() 228 public void Close()
@@ -286,15 +247,19 @@ namespace OpenSim.Region.CoreModules.World.Land
286 { 247 {
287 LandData newData = data.Copy(); 248 LandData newData = data.Copy();
288 newData.LocalID = local_id; 249 newData.LocalID = local_id;
250 ILandObject landobj = null;
289 251
290 lock (m_landList) 252 lock (m_landList)
291 { 253 {
292 if (m_landList.ContainsKey(local_id)) 254 if (m_landList.ContainsKey(local_id))
293 { 255 {
294 m_landList[local_id].LandData = newData; 256 m_landList[local_id].LandData = newData;
295 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); 257 landobj = m_landList[local_id];
258// m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]);
296 } 259 }
297 } 260 }
261 if(landobj != null)
262 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj);
298 } 263 }
299 264
300 public bool AllowedForcefulBans 265 public bool AllowedForcefulBans
@@ -324,14 +289,14 @@ namespace OpenSim.Region.CoreModules.World.Land
324 protected ILandObject CreateDefaultParcel() 289 protected ILandObject CreateDefaultParcel()
325 { 290 {
326 m_log.DebugFormat( 291 m_log.DebugFormat(
327 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 292 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
328 293
329 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 294 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
330 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 295 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
331 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 296 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
332 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 297 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
333 298
334 return AddLandObject(fullSimParcel); 299 return AddLandObject(fullSimParcel);
335 } 300 }
336 301
337 public List<ILandObject> AllParcels() 302 public List<ILandObject> AllParcels()
@@ -380,10 +345,16 @@ namespace OpenSim.Region.CoreModules.World.Land
380 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 345 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
381 { 346 {
382 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 347 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
383 if (position.HasValue) 348
384 { 349 if (!position.HasValue)
385 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 350 return;
386 } 351
352 bool isFlying = avatar.PhysicsActor.Flying;
353 avatar.RemoveFromPhysicalScene();
354
355 avatar.AbsolutePosition = (Vector3)position;
356
357 avatar.AddToPhysicalScene(isFlying);
387 } 358 }
388 359
389 public void SendYouAreRestrictedNotice(ScenePresence avatar) 360 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -403,29 +374,7 @@ namespace OpenSim.Region.CoreModules.World.Land
403 } 374 }
404 375
405 if (parcelAvatarIsEntering != null) 376 if (parcelAvatarIsEntering != null)
406 { 377 EnforceBans(parcelAvatarIsEntering, avatar);
407 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
408 {
409 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
410 {
411 SendYouAreBannedNotice(avatar);
412 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
413 }
414 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
415 {
416 SendYouAreRestrictedNotice(avatar);
417 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
418 }
419 else
420 {
421 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
422 }
423 }
424 else
425 {
426 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
427 }
428 }
429 } 378 }
430 } 379 }
431 380
@@ -454,30 +403,51 @@ namespace OpenSim.Region.CoreModules.World.Land
454 403
455 public void SendLandUpdate(ScenePresence avatar, bool force) 404 public void SendLandUpdate(ScenePresence avatar, bool force)
456 { 405 {
406
407 /* stop sendind same data twice
408 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
409 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
410
411 if (over != null)
412 {
413
414 if (force)
415 {
416 if (!avatar.IsChildAgent)
417 {
418 over.SendLandUpdateToClient(avatar.ControllingClient);
419 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
420 m_scene.RegionInfo.RegionID);
421 }
422 }
423
424 if (avatar.currentParcelUUID != over.LandData.GlobalID)
425 {
426 if (!avatar.IsChildAgent)
427 {
428 over.SendLandUpdateToClient(avatar.ControllingClient);
429 avatar.currentParcelUUID = over.LandData.GlobalID;
430 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
431 m_scene.RegionInfo.RegionID);
432 }
433 }
434 */
435 if (avatar.IsChildAgent)
436 return;
437
457 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 438 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
458 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 439 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
459 440
460 if (over != null) 441 if (over != null)
461 { 442 {
462 if (force) 443 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
444 if (force || NotsameID)
463 { 445 {
464 if (!avatar.IsChildAgent) 446 over.SendLandUpdateToClient(avatar.ControllingClient);
465 { 447 if (NotsameID)
466 over.SendLandUpdateToClient(avatar.ControllingClient);
467 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
468 m_scene.RegionInfo.RegionID);
469 }
470 }
471
472 if (avatar.currentParcelUUID != over.LandData.GlobalID)
473 {
474 if (!avatar.IsChildAgent)
475 {
476 over.SendLandUpdateToClient(avatar.ControllingClient);
477 avatar.currentParcelUUID = over.LandData.GlobalID; 448 avatar.currentParcelUUID = over.LandData.GlobalID;
478 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 449 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
479 m_scene.RegionInfo.RegionID); 450 m_scene.RegionInfo.RegionID);
480 }
481 } 451 }
482 } 452 }
483 } 453 }
@@ -529,6 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land
529 //when we are finally in a safe place, lets release the forced position lock 499 //when we are finally in a safe place, lets release the forced position lock
530 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 500 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
531 } 501 }
502 EnforceBans(parcel, clientAvatar);
532 } 503 }
533 } 504 }
534 505
@@ -676,21 +647,28 @@ namespace OpenSim.Region.CoreModules.World.Land
676 /// </summary> 647 /// </summary>
677 public void Clear(bool setupDefaultParcel) 648 public void Clear(bool setupDefaultParcel)
678 { 649 {
650 Dictionary<int, ILandObject> landworkList;
651 // move to work pointer since we are deleting it all
679 lock (m_landList) 652 lock (m_landList)
680 { 653 {
681 foreach (ILandObject lo in m_landList.Values) 654 landworkList = m_landList;
682 { 655 m_landList = new Dictionary<int, ILandObject>();
683 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 656 }
684 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
685 }
686 657
687 m_landList.Clear(); 658 // this 2 methods have locks (now)
659 ResetSimLandObjects();
688 660
689 ResetSimLandObjects(); 661 if (setupDefaultParcel)
662 CreateDefaultParcel();
690 663
691 if (setupDefaultParcel) 664 // fire outside events unlocked
692 CreateDefaultParcel(); 665 foreach (ILandObject lo in landworkList.Values)
666 {
667 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
668 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
693 } 669 }
670 landworkList.Clear();
671
694 } 672 }
695 673
696 private void performFinalLandJoin(ILandObject master, ILandObject slave) 674 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -737,7 +715,7 @@ namespace OpenSim.Region.CoreModules.World.Land
737 int x; 715 int x;
738 int y; 716 int y;
739 717
740 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 718 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
741 return null; 719 return null;
742 720
743 try 721 try
@@ -787,14 +765,13 @@ namespace OpenSim.Region.CoreModules.World.Land
787 { 765 {
788 try 766 try
789 { 767 {
790 return m_landList[m_landIDList[x / 4, y / 4]]; 768 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
769 return m_landList[m_landIDList[x / 4, y / 4]];
770 //else
771 // return null;
791 } 772 }
792 catch (IndexOutOfRangeException) 773 catch (IndexOutOfRangeException)
793 { 774 {
794// m_log.WarnFormat(
795// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
796// x, y, m_scene.RegionInfo.RegionName);
797
798 return null; 775 return null;
799 } 776 }
800 } 777 }
@@ -1078,6 +1055,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1078 //Owner Flag 1055 //Owner Flag
1079 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1056 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1080 } 1057 }
1058 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1059 {
1060 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1061 }
1081 else if (currentParcelBlock.LandData.SalePrice > 0 && 1062 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1082 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1063 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1083 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1064 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1158,8 +1139,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1158 { 1139 {
1159 if (!temp.Contains(currentParcel)) 1140 if (!temp.Contains(currentParcel))
1160 { 1141 {
1161 currentParcel.ForceUpdateLandInfo(); 1142 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1162 temp.Add(currentParcel); 1143 {
1144 currentParcel.ForceUpdateLandInfo();
1145 temp.Add(currentParcel);
1146 }
1163 } 1147 }
1164 } 1148 }
1165 } 1149 }
@@ -1378,8 +1362,26 @@ namespace OpenSim.Region.CoreModules.World.Land
1378 1362
1379 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1363 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1380 { 1364 {
1381// m_log.DebugFormat( 1365 Dictionary<int, ILandObject> landworkList;
1382// "[LAND MANAGMENT MODULE]: Processing {0} incoming parcels on {1}", data.Count, m_scene.Name); 1366 // move to work pointer since we are deleting it all
1367 lock (m_landList)
1368 {
1369 landworkList = m_landList;
1370 m_landList = new Dictionary<int, ILandObject>();
1371 }
1372
1373 //Remove all the land objects in the sim and then process our new data
1374 foreach (int n in landworkList.Keys)
1375 {
1376 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1377 }
1378 landworkList.Clear();
1379
1380 lock (m_landList)
1381 {
1382 m_landIDList.Initialize();
1383 m_landList.Clear();
1384 }
1383 1385
1384 for (int i = 0; i < data.Count; i++) 1386 for (int i = 0; i < data.Count; i++)
1385 IncomingLandObjectFromStorage(data[i]); 1387 IncomingLandObjectFromStorage(data[i]);
@@ -1387,10 +1389,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1387 1389
1388 public void IncomingLandObjectFromStorage(LandData data) 1390 public void IncomingLandObjectFromStorage(LandData data)
1389 { 1391 {
1392
1390 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1393 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1391 new_land.LandData = data.Copy(); 1394 new_land.LandData = data.Copy();
1392 new_land.SetLandBitmapFromByteArray(); 1395 new_land.SetLandBitmapFromByteArray();
1393 AddLandObject(new_land); 1396 AddLandObject(new_land);
1397 new_land.SendLandUpdateToAvatarsOverMe();
1394 } 1398 }
1395 1399
1396 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1400 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1408,7 +1412,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1408 1412
1409 public void EventManagerOnNoLandDataFromStorage() 1413 public void EventManagerOnNoLandDataFromStorage()
1410 { 1414 {
1411 lock (m_landList) 1415 // called methods already have locks
1416// lock (m_landList)
1412 { 1417 {
1413 ResetSimLandObjects(); 1418 ResetSimLandObjects();
1414 CreateDefaultParcel(); 1419 CreateDefaultParcel();
@@ -1673,6 +1678,168 @@ namespace OpenSim.Region.CoreModules.World.Land
1673 1678
1674 UpdateLandObject(localID, land.LandData); 1679 UpdateLandObject(localID, land.LandData);
1675 } 1680 }
1681
1682 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1683 {
1684 ILandObject land = null;
1685 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1686 foreach (ILandObject landObject in Land)
1687 {
1688 if (landObject.LandData.LocalID == landID)
1689 {
1690 land = landObject;
1691 }
1692 }
1693 land.DeedToGroup(DefaultGodParcelGroup);
1694 land.LandData.Name = DefaultGodParcelName;
1695 land.SendLandUpdateToAvatarsOverMe();
1696 }
1697
1698 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1699 {
1700 ScenePresence SP;
1701 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1702 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1703 if (SP.UserLevel != 0)
1704 {
1705 if (flags == 0) //All parcels, scripted or not
1706 {
1707 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1708 {
1709 if (e.OwnerID == targetID)
1710 {
1711 returns.Add(e);
1712 }
1713 }
1714 );
1715 }
1716 if (flags == 4) //All parcels, scripted object
1717 {
1718 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1719 {
1720 if (e.OwnerID == targetID)
1721 {
1722 if (e.ContainsScripts())
1723 {
1724 returns.Add(e);
1725 }
1726 }
1727 }
1728 );
1729 }
1730 if (flags == 4) //not target parcel, scripted object
1731 {
1732 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1733 {
1734 if (e.OwnerID == targetID)
1735 {
1736 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1737 if (landobject.LandData.OwnerID != e.OwnerID)
1738 {
1739 if (e.ContainsScripts())
1740 {
1741 returns.Add(e);
1742 }
1743 }
1744 }
1745 }
1746 );
1747 }
1748 foreach (SceneObjectGroup ol in returns)
1749 {
1750 ReturnObject(ol, client);
1751 }
1752 }
1753 }
1754 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1755 {
1756 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1757 objs[0] = obj;
1758 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1759 }
1760
1761 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1762
1763 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1764 {
1765 ScenePresence targetAvatar = null;
1766 ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar);
1767 ScenePresence parcelManager = null;
1768 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1769 System.Threading.Timer Timer;
1770
1771 if (targetAvatar.UserLevel == 0)
1772 {
1773 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1774 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze))
1775 return;
1776 if (flags == 0)
1777 {
1778 targetAvatar.AllowMovement = false;
1779 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
1780 parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen.");
1781 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
1782 Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0);
1783 Timers.Add(targetAvatar.UUID, Timer);
1784 }
1785 else
1786 {
1787 targetAvatar.AllowMovement = true;
1788 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you.");
1789 parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen.");
1790 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1791 Timers.Remove(targetAvatar.UUID);
1792 Timer.Dispose();
1793 }
1794 }
1795 }
1796 private void OnEndParcelFrozen(object avatar)
1797 {
1798 ScenePresence targetAvatar = (ScenePresence)avatar;
1799 targetAvatar.AllowMovement = true;
1800 System.Threading.Timer Timer;
1801 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1802 Timers.Remove(targetAvatar.UUID);
1803 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1804 }
1805
1806
1807 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1808 {
1809 ScenePresence targetAvatar = null;
1810 ScenePresence parcelManager = null;
1811
1812 // Must have presences
1813 if (!m_scene.TryGetScenePresence(target, out targetAvatar) ||
1814 !m_scene.TryGetScenePresence(client.AgentId, out parcelManager))
1815 return;
1816
1817 // Cannot eject estate managers or gods
1818 if (m_scene.Permissions.IsAdministrator(target))
1819 return;
1820
1821 // Check if you even have permission to do this
1822 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1823 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1824 !m_scene.Permissions.IsAdministrator(client.AgentId))
1825 return;
1826
1827 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1828
1829 targetAvatar.TeleportWithMomentum(pos, null);
1830 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1831 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1832
1833 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1834 {
1835 LandAccessEntry entry = new LandAccessEntry();
1836 entry.AgentID = targetAvatar.UUID;
1837 entry.Flags = AccessList.Ban;
1838 entry.Expires = 0; // Perm
1839
1840 land.LandData.ParcelAccessList.Add(entry);
1841 }
1842 }
1676 1843
1677 protected void InstallInterfaces() 1844 protected void InstallInterfaces()
1678 { 1845 {
@@ -1735,5 +1902,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1735 1902
1736 MainConsole.Instance.Output(report.ToString()); 1903 MainConsole.Instance.Output(report.ToString());
1737 } 1904 }
1905
1906 public void EnforceBans(ILandObject land, ScenePresence avatar)
1907 {
1908 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
1909 return;
1910
1911 if (land.IsEitherBannedOrRestricted(avatar.UUID))
1912 {
1913 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
1914 {
1915 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
1916 if (pos == null)
1917 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
1918 else
1919 ForceAvatarToPosition(avatar, (Vector3)pos);
1920 }
1921 else
1922 {
1923 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
1924 }
1925 }
1926 }
1738 } 1927 }
1739} 1928}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 5969d45..8ddff99 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))
@@ -1185,6 +1206,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1185 1206
1186 #endregion 1207 #endregion
1187 1208
1209 private void OnFrame()
1210 {
1211 m_expiryCounter++;
1212
1213 if (m_expiryCounter >= 50)
1214 {
1215 ExpireAccessList();
1216 m_expiryCounter = 0;
1217 }
1218 }
1219
1188 private void ExpireAccessList() 1220 private void ExpireAccessList()
1189 { 1221 {
1190 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1222 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1195,7 +1227,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1195 delete.Add(entry); 1227 delete.Add(entry);
1196 } 1228 }
1197 foreach (LandAccessEntry entry in delete) 1229 foreach (LandAccessEntry entry in delete)
1230 {
1198 LandData.ParcelAccessList.Remove(entry); 1231 LandData.ParcelAccessList.Remove(entry);
1232 ScenePresence presence;
1233
1234 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1235 {
1236 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1237 if (land.LandData.LocalID == LandData.LocalID)
1238 {
1239 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1240 presence.TeleportWithMomentum(pos, null);
1241 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1242 }
1243 }
1244 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1245 }
1199 1246
1200 if (delete.Count > 0) 1247 if (delete.Count > 0)
1201 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1248 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 f9cc0cf..55b8227 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))
@@ -594,4 +594,4 @@ namespace OpenSim.Region.CoreModules.World.Land
594 } 594 }
595 } 595 }
596 } 596 }
597} \ No newline at end of file 597}
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 1e4f0a4..eb4731c 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -176,6 +176,13 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
176 return false; 176 return false;
177 } 177 }
178 178
179 if ((perms & (uint)PermissionMask.Copy) == 0)
180 {
181 if (m_dialogModule != null)
182 m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system");
183 return false;
184 }
185
179 AssetBase asset = m_scene.CreateAsset( 186 AssetBase asset = m_scene.CreateAsset(
180 group.GetPartName(localID), 187 group.GetPartName(localID),
181 group.GetPartDescription(localID), 188 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 52b4313..33aabe4 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 5e0dfa7..7ef44db 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 e2f525c..2184a59 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>();
@@ -231,54 +234,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
231 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 234 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
232 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 235 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
233 236
234 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 237 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
235 { 238 //{
236 ScenePresence avatarPresence = null; 239 // ScenePresence avatarPresence = null;
237 240
238 m_scene.TryGetScenePresence(agentID, out avatarPresence); 241 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
239 242
240 if (avatarPresence != null) 243 // if (avatarPresence != null)
241 { 244 // {
242 bool lookup = false; 245 // bool lookup = false;
243 246
244 lock (cachedMapBlocks) 247 // lock (cachedMapBlocks)
245 { 248 // {
246 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 249 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
247 { 250 // {
248 List<MapBlockData> mapBlocks; 251 // List<MapBlockData> mapBlocks;
249 252
250 mapBlocks = cachedMapBlocks; 253 // mapBlocks = cachedMapBlocks;
251 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 254 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
252 } 255 // }
253 else 256 // else
254 { 257 // {
255 lookup = true; 258 // lookup = true;
256 } 259 // }
257 } 260 // }
258 if (lookup) 261 // if (lookup)
259 { 262 // {
260 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 263 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
261 264
262 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 265 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
263 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 266 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
264 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 267 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
265 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 268 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
266 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 269 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
267 foreach (GridRegion r in regions) 270 // foreach (GridRegion r in regions)
268 { 271 // {
269 MapBlockData block = new MapBlockData(); 272 // MapBlockData block = new MapBlockData();
270 MapBlockFromGridRegion(block, r, 0); 273 // MapBlockFromGridRegion(block, r, 0);
271 mapBlocks.Add(block); 274 // mapBlocks.Add(block);
272 } 275 // }
273 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 276 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
274 277
275 lock (cachedMapBlocks) 278 // lock (cachedMapBlocks)
276 cachedMapBlocks = mapBlocks; 279 // cachedMapBlocks = mapBlocks;
277 280
278 cachedTime = Util.UnixTimeSinceEpoch(); 281 // cachedTime = Util.UnixTimeSinceEpoch();
279 } 282 // }
280 } 283 // }
281 } 284 //}
282 285
283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 286 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 287 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -305,8 +308,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
305 protected static OSDMapLayer GetOSDMapLayerResponse() 308 protected static OSDMapLayer GetOSDMapLayerResponse()
306 { 309 {
307 OSDMapLayer mapLayer = new OSDMapLayer(); 310 OSDMapLayer mapLayer = new OSDMapLayer();
308 mapLayer.Right = 5000; 311 mapLayer.Right = 2048;
309 mapLayer.Top = 5000; 312 mapLayer.Top = 2048;
310 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 313 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
311 314
312 return mapLayer; 315 return mapLayer;
@@ -335,6 +338,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
335 { 338 {
336 m_rootAgents.Remove(AgentId); 339 m_rootAgents.Remove(AgentId);
337 } 340 }
341 lock (m_mapBlockRequestEvent)
342 {
343 if (m_mapBlockRequests.ContainsKey(AgentId))
344 m_mapBlockRequests.Remove(AgentId);
345 }
338 } 346 }
339 #endregion 347 #endregion
340 348
@@ -357,6 +365,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
357 ThreadPriority.BelowNormal, 365 ThreadPriority.BelowNormal,
358 true, 366 true,
359 true); 367 true);
368 Watchdog.StartThread(
369 MapBlockSendThread,
370 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
371 ThreadPriority.BelowNormal,
372 true,
373 true);
360 } 374 }
361 375
362 /// <summary> 376 /// <summary>
@@ -372,7 +386,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
372 st.itemtype=0; 386 st.itemtype=0;
373 st.regionhandle=0; 387 st.regionhandle=0;
374 388
375 requests.Enqueue(st); 389 lock (requests)
390 {
391 queueEvent.Set();
392 requests.Enqueue(st);
393 }
394
395 MapBlockRequestData req = new MapBlockRequestData();
396
397 req.client = null;
398 req.minX = 0;
399 req.maxX = 0;
400 req.minY = 0;
401 req.maxY = 0;
402 req.flags = 0;
403
404 lock (m_mapBlockRequestEvent)
405 {
406 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
407 m_mapBlockRequests[UUID.Zero].Enqueue(req);
408 m_mapBlockRequestEvent.Set();
409 }
376 } 410 }
377 411
378 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 412 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -528,7 +562,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
528 { 562 {
529 while (true) 563 while (true)
530 { 564 {
531 MapRequestState st = requests.Dequeue(1000); 565 MapRequestState st = new MapRequestState();
566 bool valid = false;
567 queueEvent.WaitOne();
568 lock (requests)
569 {
570 if (requests.Count > 0)
571 {
572 st = requests.Dequeue();
573 valid = true;
574 }
575 if (requests.Count == 0)
576 queueEvent.Reset();
577 }
578 if (!valid)
579 continue;
532 580
533 // end gracefully 581 // end gracefully
534 if (st.agentID == STOP_UUID) 582 if (st.agentID == STOP_UUID)
@@ -546,13 +594,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
546 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 594 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
547 { 595 {
548 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 596 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
549 Thread.Sleep(80); 597 Thread.Sleep(100);
550 598
551 RequestMapItemsDelegate d = RequestMapItemsAsync;
552 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
553 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
554 //RequestMapItemsCompleted(response);
555 Interlocked.Increment(ref nAsyncRequests); 599 Interlocked.Increment(ref nAsyncRequests);
600 Util.FireAndForget(x =>
601 {
602 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
603 });
556 } 604 }
557 } 605 }
558 606
@@ -574,110 +622,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
574 /// <param name="state"></param> 622 /// <param name="state"></param>
575 public void EnqueueMapItemRequest(MapRequestState state) 623 public void EnqueueMapItemRequest(MapRequestState state)
576 { 624 {
577 requests.Enqueue(state); 625 lock (requests)
578 }
579
580 /// <summary>
581 /// Sends the mapitem response to the IClientAPI
582 /// </summary>
583 /// <param name="response">The OSDMap Response for the mapitem</param>
584 private void RequestMapItemsCompleted(IAsyncResult iar)
585 {
586 AsyncResult result = (AsyncResult)iar;
587 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
588
589 OSDMap response = (OSDMap)icon.EndInvoke(iar);
590
591 Interlocked.Decrement(ref nAsyncRequests);
592
593 if (!response.ContainsKey("requestID"))
594 return;
595
596 UUID requestID = response["requestID"].AsUUID();
597
598 if (requestID != UUID.Zero)
599 { 626 {
600 MapRequestState mrs = new MapRequestState(); 627 queueEvent.Set();
601 mrs.agentID = UUID.Zero; 628 requests.Enqueue(state);
602 lock (m_openRequests)
603 {
604 if (m_openRequests.ContainsKey(requestID))
605 {
606 mrs = m_openRequests[requestID];
607 m_openRequests.Remove(requestID);
608 }
609 }
610
611 if (mrs.agentID != UUID.Zero)
612 {
613 ScenePresence av = null;
614 m_scene.TryGetScenePresence(mrs.agentID, out av);
615 if (av != null)
616 {
617 if (response.ContainsKey(mrs.itemtype.ToString()))
618 {
619 List<mapItemReply> returnitems = new List<mapItemReply>();
620 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
621 for (int i = 0; i < itemarray.Count; i++)
622 {
623 OSDMap mapitem = (OSDMap)itemarray[i];
624 mapItemReply mi = new mapItemReply();
625 mi.x = (uint)mapitem["X"].AsInteger();
626 mi.y = (uint)mapitem["Y"].AsInteger();
627 mi.id = mapitem["ID"].AsUUID();
628 mi.Extra = mapitem["Extra"].AsInteger();
629 mi.Extra2 = mapitem["Extra2"].AsInteger();
630 mi.name = mapitem["Name"].AsString();
631 returnitems.Add(mi);
632 }
633 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
634 }
635
636 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
637 uint itemtype = 7;
638
639 if (response.ContainsKey(itemtype.ToString()))
640 {
641 List<mapItemReply> returnitems = new List<mapItemReply>();
642 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
643 for (int i = 0; i < itemarray.Count; i++)
644 {
645 OSDMap mapitem = (OSDMap)itemarray[i];
646 mapItemReply mi = new mapItemReply();
647 mi.x = (uint)mapitem["X"].AsInteger();
648 mi.y = (uint)mapitem["Y"].AsInteger();
649 mi.id = mapitem["ID"].AsUUID();
650 mi.Extra = mapitem["Extra"].AsInteger();
651 mi.Extra2 = mapitem["Extra2"].AsInteger();
652 mi.name = mapitem["Name"].AsString();
653 returnitems.Add(mi);
654 }
655 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
656 }
657
658 // Service 1 (MAP_ITEM_TELEHUB)
659 itemtype = 1;
660
661 if (response.ContainsKey(itemtype.ToString()))
662 {
663 List<mapItemReply> returnitems = new List<mapItemReply>();
664 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
665 for (int i = 0; i < itemarray.Count; i++)
666 {
667 OSDMap mapitem = (OSDMap)itemarray[i];
668 mapItemReply mi = new mapItemReply();
669 mi.x = (uint)mapitem["X"].AsInteger();
670 mi.y = (uint)mapitem["Y"].AsInteger();
671 mi.id = mapitem["ID"].AsUUID();
672 mi.Extra = mapitem["Extra"].AsInteger();
673 mi.Extra2 = mapitem["Extra2"].AsInteger();
674 mi.name = mapitem["Name"].AsString();
675 returnitems.Add(mi);
676 }
677 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
678 }
679 }
680 }
681 } 629 }
682 } 630 }
683 631
@@ -704,8 +652,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
704 EnqueueMapItemRequest(st); 652 EnqueueMapItemRequest(st);
705 } 653 }
706 654
707 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
708 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
709 /// <summary> 655 /// <summary>
710 /// Does the actual remote mapitem request 656 /// Does the actual remote mapitem request
711 /// This should be called from an asynchronous thread 657 /// This should be called from an asynchronous thread
@@ -720,7 +666,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
720 /// <param name="itemtype">passed in from packet</param> 666 /// <param name="itemtype">passed in from packet</param>
721 /// <param name="regionhandle">Region we're looking up</param> 667 /// <param name="regionhandle">Region we're looking up</param>
722 /// <returns></returns> 668 /// <returns></returns>
723 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 669 private void RequestMapItemsAsync(UUID id, uint flags,
724 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 670 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
725 { 671 {
726// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 672// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -743,7 +689,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
743 } 689 }
744 690
745 if (blacklisted) 691 if (blacklisted)
746 return new OSDMap(); 692 {
693 Interlocked.Decrement(ref nAsyncRequests);
694 return;
695 }
747 696
748 UUID requestID = UUID.Random(); 697 UUID requestID = UUID.Random();
749 lock (m_cachedRegionMapItemsAddress) 698 lock (m_cachedRegionMapItemsAddress)
@@ -751,6 +700,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
751 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 700 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
752 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 701 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
753 } 702 }
703
754 if (httpserver.Length == 0) 704 if (httpserver.Length == 0)
755 { 705 {
756 uint x = 0, y = 0; 706 uint x = 0, y = 0;
@@ -795,18 +745,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
795 745
796 // Can't find the http server 746 // Can't find the http server
797 if (httpserver.Length == 0 || blacklisted) 747 if (httpserver.Length == 0 || blacklisted)
798 return new OSDMap(); 748 {
799 749 Interlocked.Decrement(ref nAsyncRequests);
800 MapRequestState mrs = new MapRequestState(); 750 return;
801 mrs.agentID = id; 751 }
802 mrs.EstateID = EstateID;
803 mrs.flags = flags;
804 mrs.godlike = godlike;
805 mrs.itemtype=itemtype;
806 mrs.regionhandle = regionhandle;
807
808 lock (m_openRequests)
809 m_openRequests.Add(requestID, mrs);
810 752
811 WebRequest mapitemsrequest = null; 753 WebRequest mapitemsrequest = null;
812 try 754 try
@@ -816,7 +758,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
816 catch (Exception e) 758 catch (Exception e)
817 { 759 {
818 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 760 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
819 return new OSDMap(); 761 Interlocked.Decrement(ref nAsyncRequests);
762 return;
820 } 763 }
821 764
822 mapitemsrequest.Method = "POST"; 765 mapitemsrequest.Method = "POST";
@@ -841,7 +784,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
841 catch (WebException ex) 784 catch (WebException ex)
842 { 785 {
843 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 786 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
844 responseMap["connect"] = OSD.FromBoolean(false);
845 lock (m_blacklistedurls) 787 lock (m_blacklistedurls)
846 { 788 {
847 if (!m_blacklistedurls.ContainsKey(httpserver)) 789 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -850,13 +792,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
850 792
851 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 793 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
852 794
853 return responseMap; 795 Interlocked.Decrement(ref nAsyncRequests);
796 return;
854 } 797 }
855 catch 798 catch
856 { 799 {
857 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 800 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
858 responseMap["connect"] = OSD.FromBoolean(false); 801 Interlocked.Decrement(ref nAsyncRequests);
859 return responseMap; 802 return;
860 } 803 }
861 finally 804 finally
862 { 805 {
@@ -877,12 +820,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
877 } 820 }
878 else 821 else
879 { 822 {
880 return new OSDMap(); 823 Interlocked.Decrement(ref nAsyncRequests);
824 return;
881 } 825 }
882 } 826 }
883 catch (WebException) 827 catch (WebException)
884 { 828 {
885 responseMap["connect"] = OSD.FromBoolean(false);
886 lock (m_blacklistedurls) 829 lock (m_blacklistedurls)
887 { 830 {
888 if (!m_blacklistedurls.ContainsKey(httpserver)) 831 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -891,19 +834,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
891 834
892 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 835 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
893 836
894 return responseMap; 837 Interlocked.Decrement(ref nAsyncRequests);
838 return;
895 } 839 }
896 catch 840 catch
897 { 841 {
898 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 842 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
899 responseMap["connect"] = OSD.FromBoolean(false);
900 lock (m_blacklistedregions) 843 lock (m_blacklistedregions)
901 { 844 {
902 if (!m_blacklistedregions.ContainsKey(regionhandle)) 845 if (!m_blacklistedregions.ContainsKey(regionhandle))
903 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 846 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
904 } 847 }
905 848
906 return responseMap; 849 Interlocked.Decrement(ref nAsyncRequests);
850 return;
907 } 851 }
908 finally 852 finally
909 { 853 {
@@ -922,14 +866,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
922 catch (Exception ex) 866 catch (Exception ex)
923 { 867 {
924 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 868 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
925 responseMap["connect"] = OSD.FromBoolean(false);
926 lock (m_blacklistedregions) 869 lock (m_blacklistedregions)
927 { 870 {
928 if (!m_blacklistedregions.ContainsKey(regionhandle)) 871 if (!m_blacklistedregions.ContainsKey(regionhandle))
929 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 872 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
930 } 873 }
931 874
932 return responseMap; 875 Interlocked.Decrement(ref nAsyncRequests);
876 return;
933 } 877 }
934 } 878 }
935 879
@@ -943,7 +887,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
943 } 887 }
944 } 888 }
945 889
946 return responseMap; 890 Interlocked.Decrement(ref nAsyncRequests);
891
892 if (id != UUID.Zero)
893 {
894 ScenePresence av = null;
895 m_scene.TryGetScenePresence(id, out av);
896 if (av != null)
897 {
898 if (responseMap.ContainsKey(itemtype.ToString()))
899 {
900 List<mapItemReply> returnitems = new List<mapItemReply>();
901 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
902 for (int i = 0; i < itemarray.Count; i++)
903 {
904 OSDMap mapitem = (OSDMap)itemarray[i];
905 mapItemReply mi = new mapItemReply();
906 mi.x = (uint)mapitem["X"].AsInteger();
907 mi.y = (uint)mapitem["Y"].AsInteger();
908 mi.id = mapitem["ID"].AsUUID();
909 mi.Extra = mapitem["Extra"].AsInteger();
910 mi.Extra2 = mapitem["Extra2"].AsInteger();
911 mi.name = mapitem["Name"].AsString();
912 returnitems.Add(mi);
913 }
914 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
915 }
916
917 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
918 itemtype = 7;
919
920 if (responseMap.ContainsKey(itemtype.ToString()))
921 {
922 List<mapItemReply> returnitems = new List<mapItemReply>();
923 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
924 for (int i = 0; i < itemarray.Count; i++)
925 {
926 OSDMap mapitem = (OSDMap)itemarray[i];
927 mapItemReply mi = new mapItemReply();
928 mi.x = (uint)mapitem["X"].AsInteger();
929 mi.y = (uint)mapitem["Y"].AsInteger();
930 mi.id = mapitem["ID"].AsUUID();
931 mi.Extra = mapitem["Extra"].AsInteger();
932 mi.Extra2 = mapitem["Extra2"].AsInteger();
933 mi.name = mapitem["Name"].AsString();
934 returnitems.Add(mi);
935 }
936 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
937 }
938
939 // Service 1 (MAP_ITEM_TELEHUB)
940 itemtype = 1;
941
942 if (responseMap.ContainsKey(itemtype.ToString()))
943 {
944 List<mapItemReply> returnitems = new List<mapItemReply>();
945 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
946 for (int i = 0; i < itemarray.Count; i++)
947 {
948 OSDMap mapitem = (OSDMap)itemarray[i];
949 mapItemReply mi = new mapItemReply();
950 mi.x = (uint)mapitem["X"].AsInteger();
951 mi.y = (uint)mapitem["Y"].AsInteger();
952 mi.id = mapitem["ID"].AsUUID();
953 mi.Extra = mapitem["Extra"].AsInteger();
954 mi.Extra2 = mapitem["Extra2"].AsInteger();
955 mi.name = mapitem["Name"].AsString();
956 returnitems.Add(mi);
957 }
958 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
959 }
960 }
961 }
947 } 962 }
948 963
949 /// <summary> 964 /// <summary>
@@ -953,7 +968,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
953 /// <param name="minY"></param> 968 /// <param name="minY"></param>
954 /// <param name="maxX"></param> 969 /// <param name="maxX"></param>
955 /// <param name="maxY"></param> 970 /// <param name="maxY"></param>
956 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 971 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
957 { 972 {
958 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 973 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
959 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 974 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1006,21 +1021,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1006 1021
1007 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1022 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1008 { 1023 {
1024 MapBlockRequestData req = new MapBlockRequestData();
1025
1026 req.client = remoteClient;
1027 req.minX = minX;
1028 req.maxX = maxX;
1029 req.minY = minY;
1030 req.maxY = maxY;
1031 req.flags = flag;
1032
1033 lock (m_mapBlockRequestEvent)
1034 {
1035 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1036 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1037 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1038 m_mapBlockRequestEvent.Set();
1039 }
1040
1041 return new List<MapBlockData>();
1042 }
1043
1044 protected void MapBlockSendThread()
1045 {
1046 while (true)
1047 {
1048 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1049
1050 m_mapBlockRequestEvent.WaitOne();
1051 lock (m_mapBlockRequestEvent)
1052 {
1053 int total = 0;
1054 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1055 {
1056 if (q.Count > 0)
1057 thisRunData.Add(q.Dequeue());
1058
1059 total += q.Count;
1060 }
1061
1062 if (total == 0)
1063 m_mapBlockRequestEvent.Reset();
1064 }
1065
1066 foreach (MapBlockRequestData req in thisRunData)
1067 {
1068 // Null client stops thread
1069 if (req.client == null)
1070 return;
1071
1072 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1073 }
1074
1075 Thread.Sleep(50);
1076 }
1077 }
1078
1079 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1080 {
1081 List<MapBlockData> allBlocks = new List<MapBlockData>();
1009 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1082 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1010 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1083 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1011 (minX - 4) * (int)Constants.RegionSize, 1084 minX * (int)Constants.RegionSize,
1012 (maxX + 4) * (int)Constants.RegionSize, 1085 maxX * (int)Constants.RegionSize,
1013 (minY - 4) * (int)Constants.RegionSize, 1086 minY * (int)Constants.RegionSize,
1014 (maxY + 4) * (int)Constants.RegionSize); 1087 maxY * (int)Constants.RegionSize);
1088// (minX - 4) * (int)Constants.RegionSize,
1089// (maxX + 4) * (int)Constants.RegionSize,
1090// (minY - 4) * (int)Constants.RegionSize,
1091// (maxY + 4) * (int)Constants.RegionSize);
1015 foreach (GridRegion r in regions) 1092 foreach (GridRegion r in regions)
1016 { 1093 {
1017 MapBlockData block = new MapBlockData(); 1094 MapBlockData block = new MapBlockData();
1018 MapBlockFromGridRegion(block, r, flag); 1095 MapBlockFromGridRegion(block, r, flag);
1019 mapBlocks.Add(block); 1096 mapBlocks.Add(block);
1097 allBlocks.Add(block);
1098 if (mapBlocks.Count >= 10)
1099 {
1100 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1101 mapBlocks.Clear();
1102 Thread.Sleep(50);
1103 }
1020 } 1104 }
1021 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1105 if (mapBlocks.Count > 0)
1106 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1022 1107
1023 return mapBlocks; 1108 return allBlocks;
1024 } 1109 }
1025 1110
1026 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1111 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1244,7 +1329,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1244 } 1329 }
1245 else 1330 else
1246 { 1331 {
1247 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1332 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1248 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1333 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1249 { 1334 {
1250 OSDMap responsemapdata = new OSDMap(); 1335 OSDMap responsemapdata = new OSDMap();
@@ -1420,6 +1505,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1420 { 1505 {
1421 m_rootAgents.Remove(avatar.UUID); 1506 m_rootAgents.Remove(avatar.UUID);
1422 } 1507 }
1508
1509 lock (m_mapBlockRequestEvent)
1510 {
1511 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1512 m_mapBlockRequests.Remove(avatar.UUID);
1513 }
1423 } 1514 }
1424 1515
1425 public void OnRegionUp(GridRegion otherRegion) 1516 public void OnRegionUp(GridRegion otherRegion)
@@ -1464,9 +1555,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1464 Color background = Color.FromArgb(0, 0, 0, 0); 1555 Color background = Color.FromArgb(0, 0, 0, 0);
1465 SolidBrush transparent = new SolidBrush(background); 1556 SolidBrush transparent = new SolidBrush(background);
1466 Graphics g = Graphics.FromImage(overlay); 1557 Graphics g = Graphics.FromImage(overlay);
1467 g.FillRectangle(transparent, 0, 0, 256, 256); 1558 g.FillRectangle(transparent, 0, 0, 255, 255);
1468 1559
1469 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1560 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1561 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1470 1562
1471 foreach (ILandObject land in parcels) 1563 foreach (ILandObject land in parcels)
1472 { 1564 {
@@ -1474,8 +1566,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1474 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1566 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1475 { 1567 {
1476 landForSale = true; 1568 landForSale = true;
1569
1570 bool[,] landBitmap = land.GetLandBitmap();
1571
1572 for (int x = 0 ; x < 64 ; x++)
1573 {
1574 for (int y = 0 ; y < 64 ; y++)
1575 {
1576 if (landBitmap[x, y])
1577 {
1578 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1579
1580 if (x > 0)
1581 {
1582 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1583 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1584 }
1585 if (y > 0)
1586 {
1587 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1588 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1589 }
1590 if (x < 63)
1591 {
1592 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1593 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1594 }
1595 if (y < 63)
1596 {
1597 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1598 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1599 }
1600 }
1601 }
1602 }
1477 1603
1478 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1604 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1479 } 1605 }
1480 } 1606 }
1481 1607
@@ -1487,15 +1613,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1487 1613
1488 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1614 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1489 1615
1490 for (int x = 0 ; x < 64 ; x++)
1491 {
1492 for (int y = 0 ; y < 64 ; y++)
1493 {
1494 if (saleBitmap[x, y])
1495 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1496 }
1497 }
1498
1499 try 1616 try
1500 { 1617 {
1501 return OpenJPEG.EncodeFromImage(overlay, true); 1618 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1517,4 +1634,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1517 public uint itemtype; 1634 public uint itemtype;
1518 public ulong regionhandle; 1635 public ulong regionhandle;
1519 } 1636 }
1637
1638 public struct MapBlockRequestData
1639 {
1640 public IClientAPI client;
1641 public int minX;
1642 public int minY;
1643 public int maxX;
1644 public int maxY;
1645 public uint flags;
1646 }
1520} 1647}