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.cs142
-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.cs158
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs203
-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.cs52
-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.cs424
-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.cs186
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/LightShare/LightShareModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs31
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs405
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs75
-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.cs8
-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.cs83
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs440
-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/Objects/BuySell/BuySellModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs2
-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.cs161
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs547
49 files changed, 2618 insertions, 1296 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 73d1f72..4bb8986 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..f6dd5af 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
@@ -393,6 +402,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
393 402
394 private void CompleteCreateItem(uint callbackID) 403 private void CompleteCreateItem(uint callbackID)
395 { 404 {
405 ValidateAssets();
396 m_Scene.AssetService.Store(m_asset); 406 m_Scene.AssetService.Store(m_asset);
397 407
398 InventoryItemBase item = new InventoryItemBase(); 408 InventoryItemBase item = new InventoryItemBase();
@@ -413,6 +423,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
413 item.Flags = (uint) wearableType; 423 item.Flags = (uint) wearableType;
414 item.CreationDate = Util.UnixTimeSinceEpoch(); 424 item.CreationDate = Util.UnixTimeSinceEpoch();
415 425
426 m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
427 item.ID, item.AssetID);
428
416 if (m_Scene.AddInventoryItem(item)) 429 if (m_Scene.AddInventoryItem(item))
417 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 430 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
418 else 431 else
@@ -420,5 +433,132 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
420 433
421 m_transactions.RemoveXferUploader(m_transactionID); 434 m_transactions.RemoveXferUploader(m_transactionID);
422 } 435 }
436
437 private void ValidateAssets()
438 {
439 if (m_asset.Type == (sbyte)AssetType.Clothing ||
440 m_asset.Type == (sbyte)AssetType.Bodypart)
441 {
442 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
443 string[] lines = content.Split(new char[] {'\n'});
444
445 List<string> validated = new List<string>();
446
447 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
448
449 int textures = 0;
450
451 foreach (string line in lines)
452 {
453 try
454 {
455 if (line.StartsWith("textures "))
456 {
457 textures = Convert.ToInt32(line.Substring(9));
458 validated.Add(line);
459 }
460 else if (textures > 0)
461 {
462 string[] parts = line.Split(new char[] {' '});
463
464 UUID tx = new UUID(parts[1]);
465 int id = Convert.ToInt32(parts[0]);
466
467 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
468 (allowed.ContainsKey(id) && allowed[id] == tx))
469 {
470 validated.Add(parts[0] + " " + tx.ToString());
471 }
472 else
473 {
474 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
475 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
476
477 if ((perms & full) != full)
478 {
479 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
480 validated.Add(parts[0] + " " + UUID.Zero.ToString());
481 }
482 else
483 {
484 validated.Add(line);
485 }
486 }
487 textures--;
488 }
489 else
490 {
491 validated.Add(line);
492 }
493 }
494 catch
495 {
496 // If it's malformed, skip it
497 }
498 }
499
500 string final = String.Join("\n", validated.ToArray());
501
502 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
503 }
504 }
505
506 /// <summary>
507 /// Get the asset data uploaded in this transfer.
508 /// </summary>
509 /// <returns>null if the asset has not finished uploading</returns>
510 public AssetBase GetAssetData()
511 {
512 if (m_uploadState == UploadState.Complete)
513 {
514 ValidateAssets();
515 return m_asset;
516 }
517
518 return null;
519 }
520
521 public void SetOldData(byte[] d)
522 {
523 m_oldData = d;
524 }
525
526 private Dictionary<int,UUID> ExtractTexturesFromOldData()
527 {
528 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
529 if (m_oldData == null)
530 return result;
531
532 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
533 string[] lines = content.Split(new char[] {'\n'});
534
535 int textures = 0;
536
537 foreach (string line in lines)
538 {
539 try
540 {
541 if (line.StartsWith("textures "))
542 {
543 textures = Convert.ToInt32(line.Substring(9));
544 }
545 else if (textures > 0)
546 {
547 string[] parts = line.Split(new char[] {' '});
548
549 UUID tx = new UUID(parts[1]);
550 int id = Convert.ToInt32(parts[0]);
551 result[id] = tx;
552 textures--;
553 }
554 }
555 catch
556 {
557 // If it's malformed, skip it
558 }
559 }
560
561 return result;
562 }
423 } 563 }
424} \ No newline at end of file 564}
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index b8e2820..78d597d 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -145,6 +145,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
145 { 145 {
146 byte[] fileData = NewFiles[fileName].Data; 146 byte[] fileData = NewFiles[fileName].Data;
147 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 147 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
148 if (fileName.StartsWith("inventory_"))
149 transaction.isTaskInventory = true;
148 150
149 Transfers.Add(xferID, transaction); 151 Transfers.Add(xferID, transaction);
150 152
@@ -228,6 +230,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
228 public uint Packet = 0; 230 public uint Packet = 0;
229 public uint Serial = 1; 231 public uint Serial = 1;
230 public ulong XferID = 0; 232 public ulong XferID = 0;
233 public bool isTaskInventory = false;
231 234
232 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) 235 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
233 { 236 {
@@ -253,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
253 byte[] transferData = new byte[Data.Length + 4]; 256 byte[] transferData = new byte[Data.Length + 4];
254 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 257 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
255 Array.Copy(Data, 0, transferData, 4, Data.Length); 258 Array.Copy(Data, 0, transferData, 4, Data.Length);
256 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); 259 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData, isTaskInventory);
257 complete = true; 260 complete = true;
258 } 261 }
259 else 262 else
@@ -261,7 +264,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
261 byte[] transferData = new byte[1000 + 4]; 264 byte[] transferData = new byte[1000 + 4];
262 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4); 265 Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
263 Array.Copy(Data, 0, transferData, 4, 1000); 266 Array.Copy(Data, 0, transferData, 4, 1000);
264 Client.SendXferPacket(XferID, 0, transferData); 267 Client.SendXferPacket(XferID, 0, transferData, isTaskInventory);
265 Packet++; 268 Packet++;
266 DataPointer = 1000; 269 DataPointer = 1000;
267 } 270 }
@@ -282,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
282 { 285 {
283 byte[] transferData = new byte[1000]; 286 byte[] transferData = new byte[1000];
284 Array.Copy(Data, DataPointer, transferData, 0, 1000); 287 Array.Copy(Data, DataPointer, transferData, 0, 1000);
285 Client.SendXferPacket(XferID, Packet, transferData); 288 Client.SendXferPacket(XferID, Packet, transferData, isTaskInventory);
286 Packet++; 289 Packet++;
287 DataPointer += 1000; 290 DataPointer += 1000;
288 } 291 }
@@ -291,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
291 byte[] transferData = new byte[Data.Length - DataPointer]; 294 byte[] transferData = new byte[Data.Length - DataPointer];
292 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); 295 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
293 uint endPacket = Packet |= (uint) 0x80000000; 296 uint endPacket = Packet |= (uint) 0x80000000;
294 Client.SendXferPacket(XferID, endPacket, transferData); 297 Client.SendXferPacket(XferID, endPacket, transferData, isTaskInventory);
295 Packet++; 298 Packet++;
296 DataPointer += (Data.Length - DataPointer); 299 DataPointer += (Data.Length - DataPointer);
297 300
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 8aa173a..d1a563c 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -253,57 +253,70 @@ namespace OpenSim.Region.CoreModules.Asset
253 253
254 private void UpdateFileCache(string key, AssetBase asset) 254 private void UpdateFileCache(string key, AssetBase asset)
255 { 255 {
256 string filename = GetFileName(asset.ID); 256 // TODO: Spawn this off to some seperate thread to do the actual writing
257 257 if (asset != null)
258 try
259 { 258 {
260 // If the file is already cached just update access time. 259 string filename = GetFileName(key);
261 if (File.Exists(filename)) 260
262 { 261 try
263 lock (m_CurrentlyWriting)
264 {
265 if (!m_CurrentlyWriting.Contains(filename))
266 File.SetLastAccessTime(filename, DateTime.Now);
267 }
268 }
269 else
270 { 262 {
271 // Once we start writing, make sure we flag that we're writing 263 // If the file is already cached, don't cache it, just touch it so access time is updated
272 // that object to the cache so that we don't try to write the 264 if (File.Exists(filename))
273 // same file multiple times.
274 lock (m_CurrentlyWriting)
275 { 265 {
276#if WAIT_ON_INPROGRESS_REQUESTS 266 // We don't really want to know about sharing
277 if (m_CurrentlyWriting.ContainsKey(filename)) 267 // violations here. If the file is locked, then
268 // the other thread has updated the time for us.
269 try
278 { 270 {
279 return; 271 lock (m_CurrentlyWriting)
272 {
273 if (!m_CurrentlyWriting.Contains(filename))
274 File.SetLastAccessTime(filename, DateTime.Now);
275 }
280 } 276 }
281 else 277 catch
282 {
283 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
284 }
285
286#else
287 if (m_CurrentlyWriting.Contains(filename))
288 { 278 {
289 return;
290 } 279 }
291 else 280 } else {
281
282 // Once we start writing, make sure we flag that we're writing
283 // that object to the cache so that we don't try to write the
284 // same file multiple times.
285 lock (m_CurrentlyWriting)
292 { 286 {
293 m_CurrentlyWriting.Add(filename); 287#if WAIT_ON_INPROGRESS_REQUESTS
294 } 288 if (m_CurrentlyWriting.ContainsKey(filename))
289 {
290 return;
291 }
292 else
293 {
294 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
295 }
296
297#else
298 if (m_CurrentlyWriting.Contains(filename))
299 {
300 return;
301 }
302 else
303 {
304 m_CurrentlyWriting.Add(filename);
305 }
295#endif 306#endif
296 }
297 307
298 Util.FireAndForget( 308 }
299 delegate { WriteFileCache(filename, asset); }); 309
310 Util.FireAndForget(
311 delegate { WriteFileCache(filename, asset); });
312 }
313 }
314 catch (Exception e)
315 {
316 m_log.ErrorFormat(
317 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
318 asset.ID, e.Message, e.StackTrace);
300 } 319 }
301 }
302 catch (Exception e)
303 {
304 m_log.ErrorFormat(
305 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
306 asset.ID, e.Message, e.StackTrace);
307 } 320 }
308 } 321 }
309 322
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 2a513e9..e711afb 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 b5b0082..e3bf997 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -567,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
567 /// <param name="client"></param> 567 /// <param name="client"></param>
568 private void Client_OnRequestWearables(IClientAPI client) 568 private void Client_OnRequestWearables(IClientAPI client)
569 { 569 {
570 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 570 Util.FireAndForget(delegate(object x)
571 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 571 {
572 if (sp != null) 572 Thread.Sleep(4000);
573 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 573
574 else 574 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
575 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 575 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
576 if (sp != null)
577 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
578 else
579 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
580 });
576 } 581 }
577 582
578 /// <summary> 583 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index e4452fb..dbbb0ae 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -49,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
49 private int m_shoutdistance = 100; 49 private int m_shoutdistance = 100;
50 private int m_whisperdistance = 10; 50 private int m_whisperdistance = 10;
51 private List<Scene> m_scenes = new List<Scene>(); 51 private List<Scene> m_scenes = new List<Scene>();
52 52 private List<string> FreezeCache = new List<string>();
53 private string m_adminPrefix = "";
53 internal object m_syncy = new object(); 54 internal object m_syncy = new object();
54 55
55 internal IConfig m_config; 56 internal IConfig m_config;
@@ -76,6 +77,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
76 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 77 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
77 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 78 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
78 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 79 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
80 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
79 } 81 }
80 82
81 public virtual void AddRegion(Scene scene) 83 public virtual void AddRegion(Scene scene)
@@ -171,7 +173,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
171 return; 173 return;
172 } 174 }
173 175
174 DeliverChatToAvatars(ChatSourceType.Agent, c); 176 if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
177 {
178 if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
179 c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
180 }
181 else
182 {
183 DeliverChatToAvatars(ChatSourceType.Agent, c);
184 }
175 } 185 }
176 186
177 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 187 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -185,10 +195,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
185 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 195 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
186 { 196 {
187 string fromName = c.From; 197 string fromName = c.From;
198 string fromNamePrefix = "";
188 UUID fromID = UUID.Zero; 199 UUID fromID = UUID.Zero;
189 UUID targetID = c.TargetUUID;
190 string message = c.Message; 200 string message = c.Message;
191 IScene scene = c.Scene; 201 IScene scene = c.Scene;
202 UUID destination = c.Destination;
192 Vector3 fromPos = c.Position; 203 Vector3 fromPos = c.Position;
193 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 204 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
194 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 205 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -208,7 +219,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
208 fromPos = avatar.AbsolutePosition; 219 fromPos = avatar.AbsolutePosition;
209 fromName = avatar.Name; 220 fromName = avatar.Name;
210 fromID = c.Sender.AgentId; 221 fromID = c.Sender.AgentId;
211 222 if (avatar.GodLevel >= 200)
223 {
224 fromNamePrefix = m_adminPrefix;
225 }
226 destination = UUID.Zero; // Avatars cant "SayTo"
212 break; 227 break;
213 228
214 case ChatSourceType.Object: 229 case ChatSourceType.Object:
@@ -222,38 +237,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
222 message = message.Substring(0, 1000); 237 message = message.Substring(0, 1000);
223 238
224// m_log.DebugFormat( 239// m_log.DebugFormat(
225// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", 240// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}",
226// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 241// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
227 242
228 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 243 HashSet<UUID> receiverIDs = new HashSet<UUID>();
229 244
230 foreach (Scene s in m_scenes) 245 foreach (Scene s in m_scenes)
231 { 246 {
232 if (targetID == UUID.Zero) 247 // This should use ForEachClient, but clients don't have a position.
233 { 248 // If camera is moved into client, then camera position can be used
234 // This should use ForEachClient, but clients don't have a position. 249 // MT: No, it can't, as chat is heard from the avatar position, not
235 // If camera is moved into client, then camera position can be used 250 // the camera position.
236 s.ForEachRootScenePresence( 251 s.ForEachRootScenePresence(
237 delegate(ScenePresence presence) 252 delegate(ScenePresence presence)
253 {
254 if (destination != UUID.Zero && presence.UUID != destination)
255 return;
256 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
257 if (Presencecheck != null)
238 { 258 {
239 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType, false)) 259 // This will pass all chat from objects. Not
240 receiverIDs.Add(presence.UUID); 260 // perfect, but it will do. For now. Better
261 // than the prior behavior of muting all
262 // objects on a parcel with access restrictions
263 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
264 {
265 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType))
266 receiverIDs.Add(presence.UUID);
267 }
241 } 268 }
242 );
243 }
244 else
245 {
246 // This is a send to a specific client eg from llRegionSayTo
247 // no need to check distance etc, jand send is as say
248 ScenePresence presence = s.GetScenePresence(targetID);
249 if (presence != null && !presence.IsChildAgent)
250 {
251 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, ChatTypeEnum.Say, message, sourceType, true))
252 receiverIDs.Add(presence.UUID);
253 } 269 }
254 } 270 );
255 } 271 }
256 272
257 (scene as Scene).EventManager.TriggerOnChatToClients( 273 (scene as Scene).EventManager.TriggerOnChatToClients(
258 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 274 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
259 } 275 }
@@ -293,26 +309,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
293 } 309 }
294 310
295 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 311 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
296
297 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 312 HashSet<UUID> receiverIDs = new HashSet<UUID>();
298 313
299 ((Scene)c.Scene).ForEachRootClient( 314 if (c.Scene != null)
300 delegate(IClientAPI client) 315 {
301 { 316 ((Scene)c.Scene).ForEachRootClient
302 // don't forward SayOwner chat from objects to 317 (
303 // non-owner agents 318 delegate(IClientAPI client)
304 if ((c.Type == ChatTypeEnum.Owner) && 319 {
305 (null != c.SenderObject) && 320 // don't forward SayOwner chat from objects to
306 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 321 // non-owner agents
307 return; 322 if ((c.Type == ChatTypeEnum.Owner) &&
308 323 (null != c.SenderObject) &&
309 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, 324 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
310 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 325 return;
311 receiverIDs.Add(client.AgentId); 326
312 }); 327 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
313 328 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
314 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 329 receiverIDs.Add(client.AgentId);
315 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 330 }
331 );
332 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
333 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
334 }
316 } 335 }
317 336
318 /// <summary> 337 /// <summary>
@@ -330,9 +349,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
330 /// precondition</returns> 349 /// precondition</returns>
331 protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, 350 protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
332 UUID fromAgentID, string fromName, ChatTypeEnum type, 351 UUID fromAgentID, string fromName, ChatTypeEnum type,
333 string message, ChatSourceType src, bool ignoreDistance) 352 string message, ChatSourceType src)
334 { 353 {
335 // don't send stuff to child agents 354 // don't send chat to child agents
336 if (presence.IsChildAgent) return false; 355 if (presence.IsChildAgent) return false;
337 356
338 Vector3 fromRegionPos = fromPos + regionPos; 357 Vector3 fromRegionPos = fromPos + regionPos;
@@ -341,15 +360,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
341 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 360 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
342 361
343 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 362 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
344 363
345 if (!ignoreDistance) 364 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
365 type == ChatTypeEnum.Say && dis > m_saydistance ||
366 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
346 { 367 {
347 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 368 return false;
348 type == ChatTypeEnum.Say && dis > m_saydistance ||
349 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
350 {
351 return false;
352 }
353 } 369 }
354 370
355 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 371 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
@@ -358,5 +374,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
358 374
359 return true; 375 return true;
360 } 376 }
377
378 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
379 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
380 {
381 System.Threading.Timer Timer;
382 if (flags == 0)
383 {
384 FreezeCache.Add(target.ToString());
385 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
386 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
387 Timers.Add(target, Timer);
388 }
389 else
390 {
391 FreezeCache.Remove(target.ToString());
392 Timers.TryGetValue(target, out Timer);
393 Timers.Remove(target);
394 Timer.Dispose();
395 }
396 }
397
398 private void OnEndParcelFrozen(object avatar)
399 {
400 UUID target = (UUID)avatar;
401 FreezeCache.Remove(target.ToString());
402 System.Threading.Timer Timer;
403 Timers.TryGetValue(target, out Timer);
404 Timers.Remove(target);
405 Timer.Dispose();
406 }
361 } 407 }
362} 408}
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index 325067c..3c294bb 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -216,4 +216,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
216 return result; 216 return result;
217 } 217 }
218 } 218 }
219} \ No newline at end of file 219}
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 2e3312f..82816d9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -31,16 +31,40 @@ using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
34using System;
35using System.Reflection;
36using System.Collections;
37using System.Collections.Specialized;
38using System.Reflection;
39using System.IO;
40using System.Web;
41using System.Xml;
42using log4net;
43using Mono.Addins;
44using OpenMetaverse.Messages.Linden;
45using OpenMetaverse.StructuredData;
46using OpenSim.Framework.Capabilities;
47using OpenSim.Framework.Servers;
48using OpenSim.Framework.Servers.HttpServer;
49using Caps = OpenSim.Framework.Capabilities.Caps;
50using OSDArray = OpenMetaverse.StructuredData.OSDArray;
51using OSDMap = OpenMetaverse.StructuredData.OSDMap;
34 52
35namespace OpenSim.Region.CoreModules.Avatar.Gods 53namespace OpenSim.Region.CoreModules.Avatar.Gods
36{ 54{
37 public class GodsModule : IRegionModule, IGodsModule 55 public class GodsModule : IRegionModule, IGodsModule
38 { 56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
39 /// <summary>Special UUID for actions that apply to all agents</summary> 60 /// <summary>Special UUID for actions that apply to all agents</summary>
40 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); 61 private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
41 62
42 protected Scene m_scene; 63 protected Scene m_scene;
43 protected IDialogModule m_dialogModule; 64 protected IDialogModule m_dialogModule;
65
66 protected Dictionary<UUID, string> m_capsDict =
67 new Dictionary<UUID, string>();
44 68
45 public void Initialise(Scene scene, IConfigSource source) 69 public void Initialise(Scene scene, IConfigSource source)
46 { 70 {
@@ -48,6 +72,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
48 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); 72 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
49 m_scene.RegisterModuleInterface<IGodsModule>(this); 73 m_scene.RegisterModuleInterface<IGodsModule>(this);
50 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 74 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
75 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
76 m_scene.EventManager.OnClientClosed += OnClientClosed;
77 scene.EventManager.OnIncomingInstantMessage +=
78 OnIncomingInstantMessage;
51 } 79 }
52 80
53 public void PostInitialise() {} 81 public void PostInitialise() {}
@@ -67,6 +95,54 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
67 client.OnRequestGodlikePowers -= RequestGodlikePowers; 95 client.OnRequestGodlikePowers -= RequestGodlikePowers;
68 } 96 }
69 97
98 private void OnClientClosed(UUID agentID, Scene scene)
99 {
100 m_capsDict.Remove(agentID);
101 }
102
103 private void OnRegisterCaps(UUID agentID, Caps caps)
104 {
105 string uri = "/CAPS/" + UUID.Random();
106 m_capsDict[agentID] = uri;
107
108 caps.RegisterHandler("UntrustedSimulatorMessage",
109 new RestStreamHandler("POST", uri,
110 HandleUntrustedSimulatorMessage));
111 }
112
113 private string HandleUntrustedSimulatorMessage(string request,
114 string path, string param, IOSHttpRequest httpRequest,
115 IOSHttpResponse httpResponse)
116 {
117 OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
118
119 string message = osd["message"].AsString();
120
121 if (message == "GodKickUser")
122 {
123 OSDMap body = (OSDMap)osd["body"];
124 OSDArray userInfo = (OSDArray)body["UserInfo"];
125 OSDMap userData = (OSDMap)userInfo[0];
126
127 UUID agentID = userData["AgentID"].AsUUID();
128 UUID godID = userData["GodID"].AsUUID();
129 UUID godSessionID = userData["GodSessionID"].AsUUID();
130 uint kickFlags = userData["KickFlags"].AsUInteger();
131 string reason = userData["Reason"].AsString();
132
133 ScenePresence god = m_scene.GetScenePresence(godID);
134 if (god == null || god.ControllingClient.SessionId != godSessionID)
135 return String.Empty;
136
137 KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
138 }
139 else
140 {
141 m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
142 }
143 return String.Empty;
144 }
145
70 public void RequestGodlikePowers( 146 public void RequestGodlikePowers(
71 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) 147 UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
72 { 148 {
@@ -115,69 +191,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
115 /// <param name="reason">The message to send to the user after it's been turned into a field</param> 191 /// <param name="reason">The message to send to the user after it's been turned into a field</param>
116 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) 192 public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
117 { 193 {
118 UUID kickUserID = ALL_AGENTS; 194 if (!m_scene.Permissions.IsGod(godID))
119 195 return;
196
120 ScenePresence sp = m_scene.GetScenePresence(agentID); 197 ScenePresence sp = m_scene.GetScenePresence(agentID);
121 198
122 if (sp != null || agentID == kickUserID) 199 if (sp == null && agentID != ALL_AGENTS)
123 { 200 {
124 if (m_scene.Permissions.IsGod(godID)) 201 IMessageTransferModule transferModule =
202 m_scene.RequestModuleInterface<IMessageTransferModule>();
203 if (transferModule != null)
125 { 204 {
126 if (kickflags == 0) 205 m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
127 { 206 transferModule.SendInstantMessage(new GridInstantMessage(
128 if (agentID == kickUserID) 207 m_scene, godID, "God", agentID, (byte)250, false,
129 { 208 Utils.BytesToString(reason), UUID.Zero, true,
130 string reasonStr = Utils.BytesToString(reason); 209 new Vector3(), new byte[] {(byte)kickflags}, true),
131 210 delegate(bool success) {} );
132 m_scene.ForEachClient( 211 }
133 delegate(IClientAPI controller) 212 return;
134 { 213 }
135 if (controller.AgentId != godID)
136 controller.Kick(reasonStr);
137 }
138 );
139
140 // This is a bit crude. It seems the client will be null before it actually stops the thread
141 // The thread will kill itself eventually :/
142 // Is there another way to make sure *all* clients get this 'inter region' message?
143 m_scene.ForEachRootClient(
144 delegate(IClientAPI client)
145 {
146 if (client.AgentId != godID)
147 {
148 client.Close();
149 }
150 }
151 );
152 }
153 else
154 {
155 m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
156 214
157 sp.ControllingClient.Kick(Utils.BytesToString(reason)); 215 switch (kickflags)
158 sp.ControllingClient.Close(); 216 {
159 } 217 case 0:
160 } 218 if (sp != null)
161 219 {
162 if (kickflags == 1) 220 KickPresence(sp, Utils.BytesToString(reason));
163 {
164 sp.AllowMovement = false;
165 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
166 m_dialogModule.SendAlertToUser(godID, "User Frozen");
167 }
168
169 if (kickflags == 2)
170 {
171 sp.AllowMovement = true;
172 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
173 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
174 }
175 } 221 }
176 else 222 else if (agentID == ALL_AGENTS)
177 { 223 {
178 m_dialogModule.SendAlertToUser(godID, "Kick request denied"); 224 m_scene.ForEachRootScenePresence(
225 delegate(ScenePresence p)
226 {
227 if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
228 KickPresence(p, Utils.BytesToString(reason));
229 }
230 );
179 } 231 }
232 break;
233 case 1:
234 if (sp != null)
235 {
236 sp.AllowMovement = false;
237 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
238 m_dialogModule.SendAlertToUser(godID, "User Frozen");
239 }
240 break;
241 case 2:
242 if (sp != null)
243 {
244 sp.AllowMovement = true;
245 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
246 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
247 }
248 break;
249 default:
250 break;
251 }
252 }
253
254 private void KickPresence(ScenePresence sp, string reason)
255 {
256 if (sp.IsChildAgent)
257 return;
258 sp.ControllingClient.Kick(reason);
259 sp.MakeChildAgent();
260 sp.ControllingClient.Close();
261 }
262
263 private void OnIncomingInstantMessage(GridInstantMessage msg)
264 {
265 if (msg.dialog == (uint)250) // Nonlocal kick
266 {
267 UUID agentID = new UUID(msg.toAgentID);
268 string reason = msg.message;
269 UUID godID = new UUID(msg.fromAgentID);
270 uint kickMode = (uint)msg.binaryBucket[0];
271
272 KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
180 } 273 }
181 } 274 }
182 } 275 }
183} \ No newline at end of file 276}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index ca5d485..727f1c9 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 Nini.Config; 32using Nini.Config;
32using OpenMetaverse; 33using OpenMetaverse;
@@ -42,6 +43,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
42 private static readonly ILog m_log = LogManager.GetLogger( 43 private static readonly ILog m_log = LogManager.GetLogger(
43 MethodBase.GetCurrentMethod().DeclaringType); 44 MethodBase.GetCurrentMethod().DeclaringType);
44 45
46 private Timer m_logTimer = new Timer(10000);
47 private List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
48 private string m_restUrl;
49
45 /// <value> 50 /// <value>
46 /// Is this module enabled? 51 /// Is this module enabled?
47 /// </value> 52 /// </value>
@@ -61,9 +66,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
61 "InstantMessageModule", "InstantMessageModule") != 66 "InstantMessageModule", "InstantMessageModule") !=
62 "InstantMessageModule") 67 "InstantMessageModule")
63 return; 68 return;
69 m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
64 } 70 }
65 71
66 m_enabled = true; 72 m_enabled = true;
73 m_logTimer.AutoReset = false;
74 m_logTimer.Elapsed += LogTimerElapsed;
67 } 75 }
68 76
69 public void AddRegion(Scene scene) 77 public void AddRegion(Scene scene)
@@ -148,6 +156,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
148 { 156 {
149 byte dialog = im.dialog; 157 byte dialog = im.dialog;
150 158
159 if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
160 LogInstantMesssage(im);
161
151 if (dialog != (byte)InstantMessageDialog.MessageFromAgent 162 if (dialog != (byte)InstantMessageDialog.MessageFromAgent
152 && dialog != (byte)InstantMessageDialog.StartTyping 163 && dialog != (byte)InstantMessageDialog.StartTyping
153 && dialog != (byte)InstantMessageDialog.StopTyping 164 && dialog != (byte)InstantMessageDialog.StopTyping
@@ -157,6 +168,32 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
157 return; 168 return;
158 } 169 }
159 170
171 //DateTime dt = DateTime.UtcNow;
172
173 // Ticks from UtcNow, but make it look like local. Evil, huh?
174 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
175
176 //try
177 //{
178 // // Convert that to the PST timezone
179 // TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
180 // dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
181 //}
182 //catch
183 //{
184 // //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
185 //}
186
187 //// And make it look local again to fool the unix time util
188 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
189
190 // If client is null, this message comes from storage and IS offline
191 if (client != null)
192 im.offline = 0;
193
194 if (im.offline == 0)
195 im.timestamp = (uint)Util.UnixTimeSinceEpoch();
196
160 if (m_TransferModule != null) 197 if (m_TransferModule != null)
161 { 198 {
162 if (client != null) 199 if (client != null)
@@ -200,5 +237,35 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
200 // 237 //
201 OnInstantMessage(null, msg); 238 OnInstantMessage(null, msg);
202 } 239 }
240
241 private void LogInstantMesssage(GridInstantMessage im)
242 {
243 if (m_logData.Count < 20)
244 {
245 // Restart the log write timer
246 m_logTimer.Stop();
247 }
248 if (!m_logTimer.Enabled)
249 m_logTimer.Start();
250
251 lock (m_logData)
252 {
253 m_logData.Add(im);
254 }
255 }
256
257 private void LogTimerElapsed(object source, ElapsedEventArgs e)
258 {
259 lock (m_logData)
260 {
261 if (m_restUrl != String.Empty && m_logData.Count > 0)
262 {
263 bool success = SynchronousRestObjectRequester.MakeRequest<List<GridInstantMessage>, bool>("POST", m_restUrl + "/LogMessages/", m_logData);
264 if (!success)
265 m_log.ErrorFormat("[INSTANT MESSAGE]: Failed to save log data");
266 }
267 m_logData.Clear();
268 }
269 }
203 } 270 }
204} 271}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 596174b..edd9707 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -48,6 +48,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private bool m_Enabled = false; 50 private bool m_Enabled = false;
51 protected string m_MessageKey = String.Empty;
51 protected List<Scene> m_Scenes = new List<Scene>(); 52 protected List<Scene> m_Scenes = new List<Scene>();
52 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); 53 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
53 54
@@ -67,14 +68,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
67 public virtual void Initialise(IConfigSource config) 68 public virtual void Initialise(IConfigSource config)
68 { 69 {
69 IConfig cnf = config.Configs["Messaging"]; 70 IConfig cnf = config.Configs["Messaging"];
70 if (cnf != null && cnf.GetString( 71 if (cnf != null)
71 "MessageTransferModule", "MessageTransferModule") !=
72 "MessageTransferModule")
73 { 72 {
74 m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); 73 if (cnf.GetString("MessageTransferModule",
75 return; 74 "MessageTransferModule") != "MessageTransferModule")
76 } 75 {
76 return;
77 }
77 78
79 m_MessageKey = cnf.GetString("MessageKey", String.Empty);
80 }
81 m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
78 m_Enabled = true; 82 m_Enabled = true;
79 } 83 }
80 84
@@ -133,6 +137,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
133 { 137 {
134 UUID toAgentID = new UUID(im.toAgentID); 138 UUID toAgentID = new UUID(im.toAgentID);
135 139
140 if (toAgentID == UUID.Zero)
141 return;
142
136 // Try root avatar only first 143 // Try root avatar only first
137 foreach (Scene scene in m_Scenes) 144 foreach (Scene scene in m_Scenes)
138 { 145 {
@@ -157,8 +164,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
157 // try child avatar second 164 // try child avatar second
158 foreach (Scene scene in m_Scenes) 165 foreach (Scene scene in m_Scenes)
159 { 166 {
160 m_log.DebugFormat( 167 //m_log.DebugFormat(
161 "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); 168 // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
162 169
163 ScenePresence sp = scene.GetScenePresence(toAgentID); 170 ScenePresence sp = scene.GetScenePresence(toAgentID);
164 if (sp != null) 171 if (sp != null)
@@ -247,6 +254,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
247 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 254 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
248 && requestData.ContainsKey("binary_bucket")) 255 && requestData.ContainsKey("binary_bucket"))
249 { 256 {
257 if (m_MessageKey != String.Empty)
258 {
259 XmlRpcResponse error_resp = new XmlRpcResponse();
260 Hashtable error_respdata = new Hashtable();
261 error_respdata["success"] = "FALSE";
262 error_resp.Value = error_respdata;
263
264 if (!requestData.Contains("message_key"))
265 return error_resp;
266 if (m_MessageKey != (string)requestData["message_key"])
267 return error_resp;
268 }
269
250 // Do the easy way of validating the UUIDs 270 // Do the easy way of validating the UUIDs
251 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 271 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
252 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 272 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -423,24 +443,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
423 return resp; 443 return resp;
424 } 444 }
425 445
426 /// <summary> 446 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
427 /// delegate for sending a grid instant message asynchronously
428 /// </summary>
429 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
430 447
431 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 448 private class GIM {
432 { 449 public GridInstantMessage im;
433 GridInstantMessageDelegate icon = 450 public MessageResultNotification result;
434 (GridInstantMessageDelegate)iar.AsyncState; 451 };
435 icon.EndInvoke(iar);
436 }
437 452
453 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
454 private int numInstantMessageThreads = 0;
438 455
439 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 456 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
440 { 457 {
441 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 458 lock (pendingInstantMessages) {
459 if (numInstantMessageThreads >= 4) {
460 GIM gim = new GIM();
461 gim.im = im;
462 gim.result = result;
463 pendingInstantMessages.Enqueue(gim);
464 } else {
465 ++ numInstantMessageThreads;
466 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
467 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
468 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
469 }
470 }
471 }
442 472
443 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 473 private void GridInstantMessageCompleted(IAsyncResult iar)
474 {
475 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
476 d.EndInvoke(iar);
444 } 477 }
445 478
446 /// <summary> 479 /// <summary>
@@ -455,8 +488,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
455 /// Pass in 0 the first time this method is called. It will be called recursively with the last 488 /// Pass in 0 the first time this method is called. It will be called recursively with the last
456 /// regionhandle tried 489 /// regionhandle tried
457 /// </param> 490 /// </param>
458 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 491 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
459 { 492 {
493 GIM gim;
494 do {
495 try {
496 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
497 } catch (Exception e) {
498 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
499 }
500 lock (pendingInstantMessages) {
501 if (pendingInstantMessages.Count > 0) {
502 gim = pendingInstantMessages.Dequeue();
503 im = gim.im;
504 result = gim.result;
505 } else {
506 gim = null;
507 -- numInstantMessageThreads;
508 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
509 }
510 }
511 } while (gim != null);
512 }
513 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
514 {
515
460 UUID toAgentID = new UUID(im.toAgentID); 516 UUID toAgentID = new UUID(im.toAgentID);
461 517
462 PresenceInfo upd = null; 518 PresenceInfo upd = null;
@@ -523,7 +579,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
523 579
524 if (upd != null) 580 if (upd != null)
525 { 581 {
526 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 582 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
527 upd.RegionID); 583 upd.RegionID);
528 if (reginfo != null) 584 if (reginfo != null)
529 { 585 {
@@ -672,6 +728,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
672 gim["position_z"] = msg.Position.Z.ToString(); 728 gim["position_z"] = msg.Position.Z.ToString();
673 gim["region_id"] = msg.RegionID.ToString(); 729 gim["region_id"] = msg.RegionID.ToString();
674 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 730 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
731 if (m_MessageKey != String.Empty)
732 gim["message_key"] = m_MessageKey;
675 return gim; 733 return gim;
676 } 734 }
677 735
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index de25048..b27b07d 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -171,7 +171,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
171 171
172 private void RetrieveInstantMessages(IClientAPI client) 172 private void RetrieveInstantMessages(IClientAPI client)
173 { 173 {
174 if (m_RestURL != "") 174 if (m_RestURL == String.Empty)
175 {
176 return;
177 }
178 else
175 { 179 {
176 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); 180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
177 181
@@ -179,22 +183,25 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
179 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>( 183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
180 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
181 185
182 if (msglist == null) 186 if (msglist != null)
183 m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
184
185 foreach (GridInstantMessage im in msglist)
186 { 187 {
187 // client.SendInstantMessage(im); 188 foreach (GridInstantMessage im in msglist)
188 189 {
189 // Send through scene event manager so all modules get a chance 190 // client.SendInstantMessage(im);
190 // to look at this message before it gets delivered. 191
191 // 192 // Send through scene event manager so all modules get a chance
192 // Needed for proper state management for stored group 193 // to look at this message before it gets delivered.
193 // invitations 194 //
194 // 195 // Needed for proper state management for stored group
195 Scene s = FindScene(client.AgentId); 196 // invitations
196 if (s != null) 197 //
197 s.EventManager.TriggerIncomingInstantMessage(im); 198
199 im.offline = 1;
200
201 Scene s = FindScene(client.AgentId);
202 if (s != null)
203 s.EventManager.TriggerIncomingInstantMessage(im);
204 }
198 } 205 }
199 } 206 }
200 } 207 }
@@ -205,24 +212,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
205 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 212 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
206 im.dialog != (byte)InstantMessageDialog.GroupNotice && 213 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
207 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 214 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
208 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 215 im.dialog != (byte)InstantMessageDialog.InventoryOffered &&
216 im.dialog != (byte)InstantMessageDialog.TaskInventoryOffered)
209 { 217 {
210 return; 218 return;
211 } 219 }
212 220
213 if (!m_ForwardOfflineGroupMessages)
214 {
215 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
216 im.dialog != (byte)InstantMessageDialog.GroupInvitation)
217 return;
218 }
219
220 Scene scene = FindScene(new UUID(im.fromAgentID)); 221 Scene scene = FindScene(new UUID(im.fromAgentID));
221 if (scene == null) 222 if (scene == null)
222 scene = m_SceneList[0]; 223 scene = m_SceneList[0];
223 224
224 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 225 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
225 "POST", m_RestURL+"/SaveMessage/", im); 226 "POST", m_RestURL+"/SaveMessage/?scope=" +
227 scene.RegionInfo.ScopeID.ToString(), im);
226 228
227 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 229 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
228 { 230 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index ee10d04..0833154 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -635,4 +635,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
635 m_assetsLoaded = true; 635 m_assetsLoaded = true;
636 } 636 }
637 } 637 }
638} \ No newline at end of file 638}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index cf87010..7d1fe68 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -492,6 +492,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
492 return null; 492 return null;
493 } 493 }
494 494
495 return account;
496 /*
495 try 497 try
496 { 498 {
497 string encpass = Util.Md5Hash(pass); 499 string encpass = Util.Md5Hash(pass);
@@ -512,6 +514,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
512 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message); 514 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message);
513 return null; 515 return null;
514 } 516 }
517 */
515 } 518 }
516 519
517 /// <summary> 520 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 33b4839..21dff4b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -175,8 +175,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
175 if (im.binaryBucket.Length < 17) // Invalid 175 if (im.binaryBucket.Length < 17) // Invalid
176 return; 176 return;
177 177
178 UUID receipientID = new UUID(im.toAgentID); 178 UUID recipientID = new UUID(im.toAgentID);
179 ScenePresence user = scene.GetScenePresence(receipientID); 179 ScenePresence user = scene.GetScenePresence(recipientID);
180 UUID copyID; 180 UUID copyID;
181 181
182 // First byte is the asset type 182 // First byte is the asset type
@@ -191,7 +191,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
191 folderID, new UUID(im.toAgentID)); 191 folderID, new UUID(im.toAgentID));
192 192
193 InventoryFolderBase folderCopy 193 InventoryFolderBase folderCopy
194 = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); 194 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
195 195
196 if (folderCopy == null) 196 if (folderCopy == null)
197 { 197 {
@@ -244,6 +244,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
244 im.imSessionID = itemID.Guid; 244 im.imSessionID = itemID.Guid;
245 } 245 }
246 246
247 im.offline = 0;
248
247 // Send the IM to the recipient. The item is already 249 // Send the IM to the recipient. The item is already
248 // in their inventory, so it will not be lost if 250 // in their inventory, so it will not be lost if
249 // they are offline. 251 // they are offline.
@@ -263,8 +265,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
263 }); 265 });
264 } 266 }
265 } 267 }
266 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) 268 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
269 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
267 { 270 {
271 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
272 IInventoryService invService = scene.InventoryService;
273
274 // Special case: folder redirect.
275 // RLV uses this
276 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
277 {
278 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, client.AgentId);
279 folder = invService.GetFolder(folder);
280
281 if (folder != null)
282 {
283 if (im.binaryBucket.Length >= 16)
284 {
285 UUID destFolderID = new UUID(im.binaryBucket, 0);
286 if (destFolderID != UUID.Zero)
287 {
288 InventoryFolderBase destFolder = new InventoryFolderBase(destFolderID, client.AgentId);
289 destFolder = invService.GetFolder(destFolder);
290 if (destFolder != null)
291 {
292 if (folder.ParentID != destFolder.ID)
293 {
294 folder.ParentID = destFolder.ID;
295 invService.MoveFolder(folder);
296 client.SendBulkUpdateInventory(folder);
297 }
298 }
299 }
300 }
301 }
302 }
303
268 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 304 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
269 305
270 if (user != null) // Local 306 if (user != null) // Local
@@ -274,27 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
274 else 310 else
275 { 311 {
276 if (m_TransferModule != null) 312 if (m_TransferModule != null)
277 m_TransferModule.SendInstantMessage(im, delegate(bool success) { 313 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
278
279 // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
280 // and is apparently supposed to fix bulk inventory updates after accepting items. But
281 // instead it appears to cause two copies of an accepted folder for the receiving user in
282 // at least some cases. Folder/item update is already done when the offer is made (see code above)
283
284// // Send BulkUpdateInventory
285// IInventoryService invService = scene.InventoryService;
286// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
287//
288// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
289// folder = invService.GetFolder(folder);
290//
291// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
292//
293// // If the user has left the scene by the time the message comes back then we can't send
294// // them the update.
295// if (fromUser != null)
296// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
297 });
298 } 314 }
299 } 315 }
300 316
@@ -406,6 +422,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
406 previousParentFolderID = folder.ParentID; 422 previousParentFolderID = folder.ParentID;
407 folder.ParentID = trashFolder.ID; 423 folder.ParentID = trashFolder.ID;
408 invService.MoveFolder(folder); 424 invService.MoveFolder(folder);
425 client.SendBulkUpdateInventory(folder);
409 } 426 }
410 } 427 }
411 428
@@ -516,22 +533,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
516 /// 533 ///
517 /// </summary> 534 /// </summary>
518 /// <param name="msg"></param> 535 /// <param name="msg"></param>
519 private void OnGridInstantMessage(GridInstantMessage msg) 536 private void OnGridInstantMessage(GridInstantMessage im)
520 { 537 {
521 // Check if this is ours to handle 538 // Check if this is ours to handle
522 // 539 //
523 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 540 Scene scene = FindClientScene(new UUID(im.toAgentID));
524 541
525 if (scene == null) 542 if (scene == null)
526 return; 543 return;
527 544
528 // Find agent to deliver to 545 // Find agent to deliver to
529 // 546 //
530 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 547 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
548 if (user == null)
549 return;
550
551 // This requires a little bit of processing because we have to make the
552 // new item visible in the recipient's inventory here
553 //
554 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
555 {
556 if (im.binaryBucket.Length < 17) // Invalid
557 return;
558
559 UUID recipientID = new UUID(im.toAgentID);
560
561 // First byte is the asset type
562 AssetType assetType = (AssetType)im.binaryBucket[0];
563
564 if (AssetType.Folder == assetType)
565 {
566 UUID folderID = new UUID(im.binaryBucket, 1);
531 567
532 // Just forward to local handling 568 InventoryFolderBase given =
533 OnInstantMessage(user.ControllingClient, msg); 569 new InventoryFolderBase(folderID, recipientID);
570 InventoryFolderBase folder =
571 scene.InventoryService.GetFolder(given);
534 572
573 if (folder != null)
574 user.ControllingClient.SendBulkUpdateInventory(folder);
575 }
576 else
577 {
578 UUID itemID = new UUID(im.binaryBucket, 1);
579
580 InventoryItemBase given =
581 new InventoryItemBase(itemID, recipientID);
582 InventoryItemBase item =
583 scene.InventoryService.GetItem(given);
584
585 if (item != null)
586 {
587 user.ControllingClient.SendBulkUpdateInventory(item);
588 }
589 }
590 user.ControllingClient.SendInstantMessage(im);
591 }
592 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
593 {
594 if (im.binaryBucket.Length < 1) // Invalid
595 return;
596
597 UUID recipientID = new UUID(im.toAgentID);
598
599 // Bucket is the asset type
600 AssetType assetType = (AssetType)im.binaryBucket[0];
601
602 if (AssetType.Folder == assetType)
603 {
604 UUID folderID = new UUID(im.imSessionID);
605
606 InventoryFolderBase given =
607 new InventoryFolderBase(folderID, recipientID);
608 InventoryFolderBase folder =
609 scene.InventoryService.GetFolder(given);
610
611 if (folder != null)
612 user.ControllingClient.SendBulkUpdateInventory(folder);
613 }
614 else
615 {
616 UUID itemID = new UUID(im.imSessionID);
617
618 InventoryItemBase given =
619 new InventoryItemBase(itemID, recipientID);
620 InventoryItemBase item =
621 scene.InventoryService.GetItem(given);
622
623 if (item != null)
624 {
625 user.ControllingClient.SendBulkUpdateInventory(item);
626 }
627 }
628
629 // Fix up binary bucket since this may be 17 chars long here
630 Byte[] bucket = new Byte[1];
631 bucket[0] = im.binaryBucket[0];
632 im.binaryBucket = bucket;
633
634 user.ControllingClient.SendInstantMessage(im);
635 }
636 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
637 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
638 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
639 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
640 {
641 user.ControllingClient.SendInstantMessage(im);
642 }
535 } 643 }
536 } 644 }
537} 645}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 6ce9556..1949459 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -161,16 +161,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
161 scene.RegionInfo.RegionHandle, 161 scene.RegionInfo.RegionHandle,
162 (uint)presence.AbsolutePosition.X, 162 (uint)presence.AbsolutePosition.X,
163 (uint)presence.AbsolutePosition.Y, 163 (uint)presence.AbsolutePosition.Y,
164 (uint)Math.Ceiling(presence.AbsolutePosition.Z)); 164 (uint)presence.AbsolutePosition.Z + 2);
165 165
166 m_log.DebugFormat("TP invite with message {0}", message); 166 m_log.DebugFormat("[LURE]: TP invite with message {0}", message);
167
168 GridInstantMessage m;
169
170 if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
171 {
172 m = new GridInstantMessage(scene, client.AgentId,
173 client.FirstName+" "+client.LastName, targetid,
174 (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
175 message, dest, false, presence.AbsolutePosition,
176 new Byte[0], true);
177 }
178 else
179 {
180 m = new GridInstantMessage(scene, client.AgentId,
181 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, dest, false, presence.AbsolutePosition,
184 new Byte[0], true);
185 }
167 186
168 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
169 client.FirstName+" "+client.LastName, targetid,
170 (byte)InstantMessageDialog.RequestTeleport, false,
171 message, dest, false, presence.AbsolutePosition,
172 new Byte[0], true);
173
174 if (m_TransferModule != null) 187 if (m_TransferModule != null)
175 { 188 {
176 m_TransferModule.SendInstantMessage(m, 189 m_TransferModule.SendInstantMessage(m,
@@ -205,7 +218,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
205 { 218 {
206 // Forward remote teleport requests 219 // Forward remote teleport requests
207 // 220 //
208 if (msg.dialog != 22) 221 if (msg.dialog != (byte)InstantMessageDialog.RequestTeleport &&
222 msg.dialog != (byte)InstantMessageDialog.GodLikeRequestTeleport)
209 return; 223 return;
210 224
211 if (m_TransferModule != null) 225 if (m_TransferModule != null)
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 4ea85a8..dbe75b5 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 90fe430..ffc362f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
146 146
147 protected virtual void OnNewClient(IClientAPI client) 147 protected virtual void OnNewClient(IClientAPI client)
148 { 148 {
149 client.OnTeleportHomeRequest += TeleportHome; 149 client.OnTeleportHomeRequest += TriggerTeleportHome;
150 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 150 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
151 } 151 }
152 152
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
220 /// <param name="sp"></param> 220 /// <param name="sp"></param>
221 /// <param name="position"></param> 221 /// <param name="position"></param>
222 /// <param name="lookAt"></param> 222 /// <param name="lookAt"></param>
223 /// <param name="teleportFlags"></param 223 /// <param name="teleportFlags"></param>
224 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) 224 private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags)
225 { 225 {
226 m_log.DebugFormat( 226 m_log.DebugFormat(
@@ -264,11 +264,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
264 position.Z = newPosZ; 264 position.Z = newPosZ;
265 } 265 }
266 266
267 if (sp.Flying)
268 teleportFlags |= (uint)TeleportFlags.IsFlying;
269
267 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 270 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
268 271
269 sp.ControllingClient.SendTeleportStart(teleportFlags); 272 sp.ControllingClient.SendTeleportStart(teleportFlags);
270 273
271 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 274 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
275 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
272 sp.Velocity = Vector3.Zero; 276 sp.Velocity = Vector3.Zero;
273 sp.Teleport(position); 277 sp.Teleport(position);
274 278
@@ -444,8 +448,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
444 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 448 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
445 // it's actually doing a lot of work. 449 // it's actually doing a lot of work.
446 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 450 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
447 451 if (endPoint == null || endPoint.Address == null)
448 if (endPoint.Address == null)
449 { 452 {
450 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 453 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
451 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 454 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
@@ -485,6 +488,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
485 // both regions 488 // both regions
486 if (sp.ParentID != (uint)0) 489 if (sp.ParentID != (uint)0)
487 sp.StandUp(); 490 sp.StandUp();
491 else if (sp.Flying)
492 teleportFlags |= (uint)TeleportFlags.IsFlying;
488 493
489 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 494 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
490 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 495 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
@@ -662,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
662 // 667 //
663 // This sleep can be increased if necessary. However, whilst it's active, 668 // This sleep can be increased if necessary. However, whilst it's active,
664 // an agent cannot teleport back to this region if it has teleported away. 669 // an agent cannot teleport back to this region if it has teleported away.
665 Thread.Sleep(2000); 670 Thread.Sleep(3000);
666 671
667 sp.Scene.IncomingCloseAgent(sp.UUID, false); 672 sp.Scene.IncomingCloseAgent(sp.UUID, false);
668 } 673 }
@@ -801,7 +806,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
801 806
802 #region Teleport Home 807 #region Teleport Home
803 808
804 public virtual void TeleportHome(UUID id, IClientAPI client) 809 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
810 {
811 TeleportHome(id, client);
812 }
813
814 public virtual bool TeleportHome(UUID id, IClientAPI client)
805 { 815 {
806 m_log.DebugFormat( 816 m_log.DebugFormat(
807 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 817 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -811,12 +821,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
811 821
812 if (uinfo != null) 822 if (uinfo != null)
813 { 823 {
824 if (uinfo.HomeRegionID == UUID.Zero)
825 {
826 // can't find the Home region: Tell viewer and abort
827 client.SendTeleportFailed("You don't have a home position set.");
828 return false;
829 }
814 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 830 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
815 if (regionInfo == null) 831 if (regionInfo == null)
816 { 832 {
817 // can't find the Home region: Tell viewer and abort 833 // can't find the Home region: Tell viewer and abort
818 client.SendTeleportFailed("Your home region could not be found."); 834 client.SendTeleportFailed("Your home region could not be found.");
819 return; 835 return false;
820 } 836 }
821 837
822 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 838 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
@@ -829,10 +845,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
829 } 845 }
830 else 846 else
831 { 847 {
832 m_log.ErrorFormat( 848 // can't find the Home region: Tell viewer and abort
833 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 849 client.SendTeleportFailed("Your home region could not be found.");
834 client.Name, client.AgentId); 850 return false;
835 } 851 }
852 return true;
836 } 853 }
837 854
838 #endregion 855 #endregion
@@ -840,11 +857,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
840 857
841 #region Agent Crossings 858 #region Agent Crossings
842 859
843 public bool Cross(ScenePresence agent, bool isFlying) 860 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
844 { 861 {
845 Scene scene = agent.Scene; 862 version = String.Empty;
846 Vector3 pos = agent.AbsolutePosition; 863 newpos = new Vector3(pos.X, pos.Y, pos.Z);
847 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
848 uint neighbourx = scene.RegionInfo.RegionLocX; 864 uint neighbourx = scene.RegionInfo.RegionLocX;
849 uint neighboury = scene.RegionInfo.RegionLocY; 865 uint neighboury = scene.RegionInfo.RegionLocY;
850 const float boundaryDistance = 1.7f; 866 const float boundaryDistance = 1.7f;
@@ -865,52 +881,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
865 } 881 }
866 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 882 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
867 { 883 {
868 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 884 neighboury--;
869 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 885 newpos.Y = Constants.RegionSize - enterDistance;
870 {
871 neighboury--;
872 newpos.Y = Constants.RegionSize - enterDistance;
873 }
874 else
875 {
876 agent.IsInTransit = true;
877
878 neighboury = b.TriggerRegionY;
879 neighbourx = b.TriggerRegionX;
880
881 Vector3 newposition = pos;
882 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
883 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
884 agent.ControllingClient.SendAgentAlertMessage(
885 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
886 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
887 return true;
888 }
889 }
890
891 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
892 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
893 {
894 neighbourx--;
895 newpos.X = Constants.RegionSize - enterDistance;
896 }
897 else
898 {
899 agent.IsInTransit = true;
900
901 neighboury = ba.TriggerRegionY;
902 neighbourx = ba.TriggerRegionX;
903
904 Vector3 newposition = pos;
905 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
906 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
907 agent.ControllingClient.SendAgentAlertMessage(
908 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
909 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
910
911 return true;
912 } 886 }
913 887
888 neighbourx--;
889 newpos.X = Constants.RegionSize - enterDistance;
914 } 890 }
915 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 891 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
916 { 892 {
@@ -920,26 +896,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
920 896
921 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 897 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
922 { 898 {
923 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 899 neighboury--;
924 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 900 newpos.Y = Constants.RegionSize - enterDistance;
925 {
926 neighboury--;
927 newpos.Y = Constants.RegionSize - enterDistance;
928 }
929 else
930 {
931 agent.IsInTransit = true;
932
933 neighboury = ba.TriggerRegionY;
934 neighbourx = ba.TriggerRegionX;
935 Vector3 newposition = pos;
936 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
937 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
938 agent.ControllingClient.SendAgentAlertMessage(
939 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
940 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
941 return true;
942 }
943 } 901 }
944 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 902 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
945 { 903 {
@@ -951,25 +909,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
951 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 909 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
952 { 910 {
953 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 911 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
954 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 912 neighboury--;
955 { 913 newpos.Y = Constants.RegionSize - enterDistance;
956 neighboury--;
957 newpos.Y = Constants.RegionSize - enterDistance;
958 }
959 else
960 {
961 agent.IsInTransit = true;
962
963 neighboury = b.TriggerRegionY;
964 neighbourx = b.TriggerRegionX;
965 Vector3 newposition = pos;
966 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
967 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
968 agent.ControllingClient.SendAgentAlertMessage(
969 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
970 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
971 return true;
972 }
973 } 914 }
974 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 915 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
975 { 916 {
@@ -1003,19 +944,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1003 } 944 }
1004 */ 945 */
1005 946
1006 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 947 xDest = neighbourx;
948 yDest = neighboury;
1007 949
1008 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 950 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
1009 951
952 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
953
1010 ExpiringCache<ulong, DateTime> r; 954 ExpiringCache<ulong, DateTime> r;
1011 DateTime banUntil; 955 DateTime banUntil;
1012 956
1013 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 957 if (m_bannedRegions.TryGetValue(agentID, out r))
1014 { 958 {
1015 if (r.TryGetValue(neighbourHandle, out banUntil)) 959 if (r.TryGetValue(neighbourHandle, out banUntil))
1016 { 960 {
1017 if (DateTime.Now < banUntil) 961 if (DateTime.Now < banUntil)
1018 return false; 962 return null;
1019 r.Remove(neighbourHandle); 963 r.Remove(neighbourHandle);
1020 } 964 }
1021 } 965 }
@@ -1027,28 +971,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1027 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 971 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1028 972
1029 string reason; 973 string reason;
1030 string version; 974 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1031 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1032 { 975 {
1033 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1034 if (r == null) 976 if (r == null)
1035 { 977 {
1036 r = new ExpiringCache<ulong, DateTime>(); 978 r = new ExpiringCache<ulong, DateTime>();
1037 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 979 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1038 980
1039 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 981 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1040 } 982 }
1041 else 983 else
1042 { 984 {
1043 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 985 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1044 } 986 }
987 return null;
988 }
989
990 return neighbourRegion;
991 }
992
993 public bool Cross(ScenePresence agent, bool isFlying)
994 {
995 uint x;
996 uint y;
997 Vector3 newpos;
998 string version;
999
1000 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
1001 if (neighbourRegion == null)
1002 {
1003 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1045 return false; 1004 return false;
1046 } 1005 }
1047 1006
1048 agent.IsInTransit = true; 1007 agent.IsInTransit = true;
1049 1008
1050 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1009 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1051 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1010 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1052 1011
1053 return true; 1012 return true;
1054 } 1013 }
@@ -1117,44 +1076,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1117 icon.EndInvoke(iar); 1076 icon.EndInvoke(iar);
1118 } 1077 }
1119 1078
1120 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); 1079 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion)
1080 {
1081 if (neighbourRegion == null)
1082 return false;
1083
1084 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1085
1086 agent.RemoveFromPhysicalScene();
1087
1088 return true;
1089 }
1121 1090
1122 /// <summary> 1091 /// <summary>
1123 /// This Closes child agents on neighbouring regions 1092 /// This Closes child agents on neighbouring regions
1124 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1093 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1125 /// </summary> 1094 /// </summary>
1126 protected ScenePresence CrossAgentToNewRegionAsync( 1095 public ScenePresence CrossAgentToNewRegionAsync(
1127 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1096 ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1128 bool isFlying, string version) 1097 bool isFlying, string version)
1129 { 1098 {
1130 if (neighbourRegion == null) 1099 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1131 return agent; 1100 return agent;
1132 1101
1133 try 1102 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1134 { 1103 return agent;
1135 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1136
1137 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
1138
1139 m_log.DebugFormat(
1140 "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}",
1141 agent.Firstname, agent.Lastname, neighbourx, neighboury, version);
1142
1143 Scene m_scene = agent.Scene;
1144
1145 if (!agent.ValidateAttachments())
1146 m_log.DebugFormat(
1147 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
1148 agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
1149
1150 pos = pos + agent.Velocity;
1151 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1152 1104
1153 agent.RemoveFromPhysicalScene(); 1105 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1106 return agent;
1107 }
1154 1108
1109 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying)
1110 {
1111 try
1112 {
1155 AgentData cAgent = new AgentData(); 1113 AgentData cAgent = new AgentData();
1156 agent.CopyTo(cAgent); 1114 agent.CopyTo(cAgent);
1157 cAgent.Position = pos; 1115 cAgent.Position = pos + agent.Velocity;
1158 if (isFlying) 1116 if (isFlying)
1159 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1117 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1160 1118
@@ -1164,7 +1122,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1164 // Beyond this point, extra cleanup is needed beyond removing transit state 1122 // Beyond this point, extra cleanup is needed beyond removing transit state
1165 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1123 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1166 1124
1167 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1125 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
1168 { 1126 {
1169 // region doesn't take it 1127 // region doesn't take it
1170 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1128 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1173,93 +1131,108 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1173 agent.AddToPhysicalScene(isFlying); 1131 agent.AddToPhysicalScene(isFlying);
1174 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1132 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1175 1133
1176 return agent; 1134 return false;
1177 } 1135 }
1178 1136
1179 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 1137 }
1180 agent.ControllingClient.RequestClientInfo(); 1138 catch (Exception e)
1139 {
1140 m_log.ErrorFormat(
1141 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}",
1142 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace);
1181 1143
1182 //m_log.Debug("BEFORE CROSS"); 1144 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc.
1183 //Scene.DumpChildrenSeeds(UUID); 1145 return false;
1184 //DumpKnownRegions(); 1146 }
1185 string agentcaps;
1186 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1187 {
1188 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1189 neighbourRegion.RegionHandle);
1190 return agent;
1191 }
1192 // No turning back
1193 agent.IsChildAgent = true;
1194 1147
1195 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1148 return true;
1149 }
1196 1150
1197 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1151 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1152 bool isFlying, string version)
1153 {
1154 agent.ControllingClient.RequestClientInfo();
1198 1155
1199 if (m_eqModule != null) 1156 string agentcaps;
1200 { 1157 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1201 m_eqModule.CrossRegion( 1158 {
1202 neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1159 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1203 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1160 neighbourRegion.RegionHandle);
1204 } 1161 return;
1205 else 1162 }
1206 {
1207 agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1208 capsPath);
1209 }
1210 1163
1211 // SUCCESS! 1164 // No turning back
1212 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1165 agent.IsChildAgent = true;
1213 1166
1214 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1167 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1215 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1216 1168
1217 agent.MakeChildAgent(); 1169 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1170
1171 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1172
1173 if (m_eqModule != null)
1174 {
1175 m_eqModule.CrossRegion(
1176 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint,
1177 capsPath, agent.UUID, agent.ControllingClient.SessionId);
1178 }
1179 else
1180 {
1181 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1182 capsPath);
1183 }
1218 1184
1219 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1185 // SUCCESS!
1220 // but not sure yet what the side effects would be. 1186 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1221 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1222 1187
1223 // now we have a child agent in this region. Request all interesting data about other (root) agents 1188 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1224 agent.SendOtherAgentsAvatarDataToMe(); 1189 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1225 agent.SendOtherAgentsAppearanceToMe();
1226 1190
1227 // Backwards compatibility. Best effort 1191 agent.MakeChildAgent();
1228 if (version == "Unknown" || version == string.Empty)
1229 {
1230 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1231 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1232 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1233 }
1234 1192
1235 // Next, let's close the child agent connections that are too far away. 1193 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1236 agent.CloseChildAgents(neighbourx, neighboury); 1194 // but not sure yet what the side effects would be.
1195 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1237 1196
1238 AgentHasMovedAway(agent, false); 1197 // now we have a child agent in this region. Request all interesting data about other (root) agents
1198 agent.SendOtherAgentsAvatarDataToMe();
1199 agent.SendOtherAgentsAppearanceToMe();
1239 1200
1240 // the user may change their profile information in other region, 1201 // Backwards compatibility. Best effort
1241 // so the userinfo in UserProfileCache is not reliable any more, delete it 1202 if (version == "Unknown" || version == string.Empty)
1242 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1243 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1244 {
1245 m_log.DebugFormat(
1246 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1247 }
1248
1249 //m_log.Debug("AFTER CROSS");
1250 //Scene.DumpChildrenSeeds(UUID);
1251 //DumpKnownRegions();
1252 }
1253 catch (Exception e)
1254 { 1203 {
1255 m_log.ErrorFormat( 1204 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1256 "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", 1205 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1257 agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); 1206 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1207 }
1258 1208
1259 // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. 1209 // Next, let's close the child agent connections that are too far away.
1210 uint neighbourx;
1211 uint neighboury;
1212
1213 Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1214
1215 neighbourx /= Constants.RegionSize;
1216 neighboury /= Constants.RegionSize;
1217
1218 agent.CloseChildAgents(neighbourx, neighboury);
1219
1220 AgentHasMovedAway(agent, false);
1221
1222 // the user may change their profile information in other region,
1223 // so the userinfo in UserProfileCache is not reliable any more, delete it
1224 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1225 if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1226 {
1227 m_log.DebugFormat(
1228 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1260 } 1229 }
1261 1230
1262 return agent; 1231 //m_log.Debug("AFTER CROSS");
1232 //Scene.DumpChildrenSeeds(UUID);
1233 //DumpKnownRegions();
1234
1235 return;
1263 } 1236 }
1264 1237
1265 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1238 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -1330,10 +1303,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1330 agent.Id0 = currentAgentCircuit.Id0; 1303 agent.Id0 = currentAgentCircuit.Id0;
1331 } 1304 }
1332 1305
1333 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1306 IPEndPoint external = region.ExternalEndPoint;
1334 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1307 if (external != null)
1308 {
1309 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1310 d.BeginInvoke(sp, agent, region, external, true,
1335 InformClientOfNeighbourCompleted, 1311 InformClientOfNeighbourCompleted,
1336 d); 1312 d);
1313 }
1337 } 1314 }
1338 #endregion 1315 #endregion
1339 1316
@@ -1914,27 +1891,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1914 Utils.LongToUInts(newRegionHandle, out x, out y); 1891 Utils.LongToUInts(newRegionHandle, out x, out y);
1915 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1892 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1916 1893
1917 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 1894 if (destination != null)
1918 { 1895 {
1919 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 1896 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
1897 return; // we did it
1898 }
1920 1899
1921 // We are going to move the object back to the old position so long as the old position 1900 // no one or failed lets go back and tell physics to go on
1922 // is in the region 1901 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
1923 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 1902 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
1924 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 1903 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
1925 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
1926 1904
1927 grp.RootPart.GroupPosition = oldGroupPosition; 1905 grp.AbsolutePosition = oldGroupPosition;
1906 grp.Velocity = Vector3.Zero;
1928 1907
1929 // Need to turn off the physics flags, otherwise the object will continue to attempt to 1908 if (grp.RootPart.PhysActor != null)
1930 // move out of the region creating an infinite loop of failed attempts to cross 1909 grp.RootPart.PhysActor.CrossingFailure();
1931 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1932 1910
1933 grp.ScheduleGroupForFullUpdate(); 1911 if (grp.RootPart.KeyframeMotion != null)
1934 } 1912 grp.RootPart.KeyframeMotion.CrossingFailure();
1913
1914 grp.ScheduleGroupForFullUpdate();
1935 } 1915 }
1936 1916
1937 1917
1918
1938 /// <summary> 1919 /// <summary>
1939 /// Move the given scene object into a new region 1920 /// Move the given scene object into a new region
1940 /// </summary> 1921 /// </summary>
@@ -1985,17 +1966,30 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1985 grp, e); 1966 grp, e);
1986 } 1967 }
1987 } 1968 }
1969/*
1970 * done on caller ( not in attachments crossing for now)
1988 else 1971 else
1989 { 1972 {
1973
1990 if (!grp.IsDeleted) 1974 if (!grp.IsDeleted)
1991 { 1975 {
1992 PhysicsActor pa = grp.RootPart.PhysActor; 1976 PhysicsActor pa = grp.RootPart.PhysActor;
1993 if (pa != null) 1977 if (pa != null)
1978 {
1994 pa.CrossingFailure(); 1979 pa.CrossingFailure();
1980 if (grp.RootPart.KeyframeMotion != null)
1981 {
1982 // moved to KeyframeMotion.CrossingFailure
1983// grp.RootPart.Velocity = Vector3.Zero;
1984 grp.RootPart.KeyframeMotion.CrossingFailure();
1985// grp.SendGroupRootTerseUpdate();
1986 }
1987 }
1995 } 1988 }
1996 1989
1997 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 1990 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
1998 } 1991 }
1992 */
1999 } 1993 }
2000 else 1994 else
2001 { 1995 {
@@ -2080,4 +2074,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2080 #endregion 2074 #endregion
2081 2075
2082 } 2076 }
2083} \ No newline at end of file 2077}
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 679be18..0aee0d4 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -182,7 +182,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
182 182
183 protected override void OnNewClient(IClientAPI client) 183 protected override void OnNewClient(IClientAPI client)
184 { 184 {
185 client.OnTeleportHomeRequest += TeleportHome; 185 client.OnTeleportHomeRequest += TriggerTeleportHome;
186 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 186 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
187 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 187 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
188 } 188 }
@@ -289,6 +289,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
289 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 289 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
290 } 290 }
291 291
292 public void TriggerTeleportHome(UUID id, IClientAPI client)
293 {
294 TeleportHome(id, client);
295 }
296
292 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) 297 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
293 { 298 {
294 reason = "Please wear your grid's allowed appearance before teleporting to another grid"; 299 reason = "Please wear your grid's allowed appearance before teleporting to another grid";
@@ -407,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
407 // return base.UpdateAgent(reg, finalDestination, agentData, sp); 412 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
408 //} 413 //}
409 414
410 public override void TeleportHome(UUID id, IClientAPI client) 415 public override bool TeleportHome(UUID id, IClientAPI client)
411 { 416 {
412 m_log.DebugFormat( 417 m_log.DebugFormat(
413 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 418 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -418,8 +423,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
418 { 423 {
419 // local grid user 424 // local grid user
420 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); 425 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
421 base.TeleportHome(id, client); 426 return base.TeleportHome(id, client);
422 return;
423 } 427 }
424 428
425 // Foreign user wants to go home 429 // Foreign user wants to go home
@@ -429,7 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
429 { 433 {
430 client.SendTeleportFailed("Your information has been lost"); 434 client.SendTeleportFailed("Your information has been lost");
431 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); 435 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information");
432 return; 436 return false;
433 } 437 }
434 438
435 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); 439 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString());
@@ -439,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
439 { 443 {
440 client.SendTeleportFailed("Your home region could not be found"); 444 client.SendTeleportFailed("Your home region could not be found");
441 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); 445 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found");
442 return; 446 return false;
443 } 447 }
444 448
445 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); 449 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId);
@@ -447,7 +451,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
447 { 451 {
448 client.SendTeleportFailed("Internal error"); 452 client.SendTeleportFailed("Internal error");
449 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); 453 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be");
450 return; 454 return false;
451 } 455 }
452 456
453 GridRegion homeGatekeeper = MakeRegion(aCircuit); 457 GridRegion homeGatekeeper = MakeRegion(aCircuit);
@@ -455,9 +459,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
455 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 459 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
456 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 460 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
457 461
458 DoTeleport( 462 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
459 sp, homeGatekeeper, finalDestination, 463 return true;
460 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
461 } 464 }
462 465
463 /// <summary> 466 /// <summary>
@@ -584,4 +587,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
584 return region; 587 return region;
585 } 588 }
586 } 589 }
587} \ No newline at end of file 590}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 8b34c28..50f5f68 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -186,44 +186,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
186 if (folder == null || folder.Owner != remoteClient.AgentId) 186 if (folder == null || folder.Owner != remoteClient.AgentId)
187 return; 187 return;
188 188
189 if (transactionID == UUID.Zero) 189 if (transactionID != UUID.Zero)
190 { 190 {
191 ScenePresence presence; 191 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
192 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 192 if (agentTransactions != null)
193 { 193 {
194 byte[] data = null; 194 if (agentTransactions.HandleItemCreationFromTransaction(
195 remoteClient, transactionID, folderID, callbackID, description,
196 name, invType, assetType, wearableType, nextOwnerMask))
197 return;
198 }
199 }
195 200
196 if (invType == (sbyte)InventoryType.Landmark && presence != null) 201 ScenePresence presence;
197 { 202 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
198 string suffix = string.Empty, prefix = string.Empty; 203 {
199 string strdata = GenerateLandmark(presence, out prefix, out suffix); 204 byte[] data = null;
200 data = Encoding.ASCII.GetBytes(strdata);
201 name = prefix + name;
202 description += suffix;
203 }
204 205
205 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); 206 if (invType == (sbyte)InventoryType.Landmark && presence != null)
206 m_Scene.AssetService.Store(asset);
207 m_Scene.CreateNewInventoryItem(
208 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
209 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
210 }
211 else
212 { 207 {
213 m_log.ErrorFormat( 208 string suffix = string.Empty, prefix = string.Empty;
214 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", 209 string strdata = GenerateLandmark(presence, out prefix, out suffix);
215 remoteClient.AgentId); 210 data = Encoding.ASCII.GetBytes(strdata);
211 name = prefix + name;
212 description += suffix;
216 } 213 }
214
215 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
216 m_Scene.AssetService.Store(asset);
217 m_Scene.CreateNewInventoryItem(
218 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
219 name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID);
217 } 220 }
218 else 221 else
219 { 222 {
220 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; 223 m_log.ErrorFormat(
221 if (agentTransactions != null) 224 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
222 { 225 remoteClient.AgentId);
223 agentTransactions.HandleItemCreationFromTransaction(
224 remoteClient, transactionID, folderID, callbackID, description,
225 name, invType, assetType, wearableType, nextOwnerMask);
226 }
227 } 226 }
228 } 227 }
229 228
@@ -360,6 +359,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
360 359
361 foreach (SceneObjectGroup objectGroup in objlist) 360 foreach (SceneObjectGroup objectGroup in objlist)
362 { 361 {
362 if (objectGroup.RootPart.KeyframeMotion != null)
363 objectGroup.RootPart.KeyframeMotion.Stop();
364 objectGroup.RootPart.SetForce(Vector3.Zero);
365 objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
366 objectGroup.RootPart.KeyframeMotion = null;
367
363 Vector3 inventoryStoredPosition = new Vector3 368 Vector3 inventoryStoredPosition = new Vector3
364 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 369 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
365 ? 250 370 ? 250
@@ -370,9 +375,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
370 : objectGroup.AbsolutePosition.Y, 375 : objectGroup.AbsolutePosition.Y,
371 objectGroup.AbsolutePosition.Z); 376 objectGroup.AbsolutePosition.Z);
372 377
378 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
373 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 379 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
374 380
381 // Restore attachment data after trip through the sim
382 if (objectGroup.RootPart.AttachPoint > 0)
383 {
384 inventoryStoredPosition = objectGroup.RootPart.AttachOffset;
385 inventoryStoredRotation = objectGroup.RootPart.AttachRotation;
386 }
387 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
388
375 objectGroup.AbsolutePosition = inventoryStoredPosition; 389 objectGroup.AbsolutePosition = inventoryStoredPosition;
390 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
376 391
377 // Make sure all bits but the ones we want are clear 392 // Make sure all bits but the ones we want are clear
378 // on take. 393 // on take.
@@ -490,8 +505,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
490 IClientAPI remoteClient) 505 IClientAPI remoteClient)
491 { 506 {
492 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; 507 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7;
508 // For the porposes of inventory, an object is modify if the prims
509 // are modify. This allows renaming an object that contains no
510 // mod items.
493 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 511 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
494 effectivePerms &= grp.GetEffectivePermissions(); 512 {
513 uint groupPerms = grp.GetEffectivePermissions(true);
514 if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0)
515 groupPerms |= (uint)PermissionMask.Modify;
516
517 effectivePerms &= groupPerms;
518 }
495 effectivePerms |= (uint)PermissionMask.Move; 519 effectivePerms |= (uint)PermissionMask.Move;
496 520
497 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 521 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
@@ -670,7 +694,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
670 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) 694 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
671 { 695 {
672 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 696 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
673 folder = m_Scene.InventoryService.GetFolder(f); 697 if (f != null)
698 folder = m_Scene.InventoryService.GetFolder(f);
674 } 699 }
675 } 700 }
676 701
@@ -700,16 +725,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
700 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 725 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
701 { 726 {
702// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 727// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
703
704 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 728 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
705 item = m_Scene.InventoryService.GetItem(item); 729 item = m_Scene.InventoryService.GetItem(item);
706 730
707 if (item == null) 731 if (item == null)
708 { 732 {
709 m_log.WarnFormat(
710 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
711 itemID, remoteClient.Name);
712
713 return null; 733 return null;
714 } 734 }
715 735
@@ -760,6 +780,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
760 if (e == null || attachment) // Single 780 if (e == null || attachment) // Single
761 { 781 {
762 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 782 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
783 if (!attachment)
784 {
785 g.RootPart.AttachPoint = g.RootPart.Shape.State;
786 g.RootPart.AttachOffset = g.AbsolutePosition;
787 g.RootPart.AttachRotation = g.GroupRotation;
788 g.RootPart.Shape.State = 0;
789 }
763 790
764 objlist.Add(g); 791 objlist.Add(g);
765 veclist.Add(new Vector3(0, 0, 0)); 792 veclist.Add(new Vector3(0, 0, 0));
@@ -789,6 +816,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
789 foreach (XmlNode n in groups) 816 foreach (XmlNode n in groups)
790 { 817 {
791 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); 818 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
819 g.RootPart.AttachPoint = g.RootPart.Shape.State;
820 g.RootPart.AttachOffset = g.AbsolutePosition;
821 g.RootPart.AttachRotation = g.GroupRotation;
822 g.RootPart.Shape.State = 0;
792 823
793 objlist.Add(g); 824 objlist.Add(g);
794 XmlElement el = (XmlElement)n; 825 XmlElement el = (XmlElement)n;
@@ -808,12 +839,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
808 } 839 }
809 } 840 }
810 841
842 int primcount = 0;
843 foreach (SceneObjectGroup g in objlist)
844 primcount += g.PrimCount;
845
846 if (!m_Scene.Permissions.CanRezObject(
847 primcount, remoteClient.AgentId, pos)
848 && !attachment)
849 {
850 // The client operates in no fail mode. It will
851 // have already removed the item from the folder
852 // if it's no copy.
853 // Put it back if it's not an attachment
854 //
855 if (item != null)
856 {
857 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
858 remoteClient.SendBulkUpdateInventory(item);
859 }
860
861 return null;
862 }
863
811 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) 864 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
812 return null; 865 return null;
813 866
814 for (int i = 0; i < objlist.Count; i++) 867 for (int i = 0; i < objlist.Count; i++)
815 { 868 {
816 group = objlist[i]; 869 group = objlist[i];
870 SceneObjectPart rootPart = group.RootPart;
817 871
818// m_log.DebugFormat( 872// m_log.DebugFormat(
819// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 873// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -874,8 +928,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
874 928
875 if (!attachment) 929 if (!attachment)
876 { 930 {
877 SceneObjectPart rootPart = group.RootPart;
878
879 if (rootPart.Shape.PCode == (byte)PCode.Prim) 931 if (rootPart.Shape.PCode == (byte)PCode.Prim)
880 group.ClearPartAttachmentData(); 932 group.ClearPartAttachmentData();
881 933
@@ -893,6 +945,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
893// remoteClient.Name); 945// remoteClient.Name);
894 } 946 }
895 947
948 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
949
896 if (item != null) 950 if (item != null)
897 DoPostRezWhenFromItem(item, attachment); 951 DoPostRezWhenFromItem(item, attachment);
898 952
@@ -971,8 +1025,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
971 { 1025 {
972 rootPart.Name = item.Name; 1026 rootPart.Name = item.Name;
973 rootPart.Description = item.Description; 1027 rootPart.Description = item.Description;
974 rootPart.ObjectSaleType = item.SaleType; 1028 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
975 rootPart.SalePrice = item.SalePrice; 1029 {
1030 rootPart.ObjectSaleType = item.SaleType;
1031 rootPart.SalePrice = item.SalePrice;
1032 }
976 } 1033 }
977 1034
978 so.FromFolderID = item.Folder; 1035 so.FromFolderID = item.Folder;
@@ -982,7 +1039,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
982// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1039// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
983 1040
984 if ((rootPart.OwnerID != item.Owner) || 1041 if ((rootPart.OwnerID != item.Owner) ||
985 (item.CurrentPermissions & 16) != 0) 1042 (item.CurrentPermissions & 16) != 0 ||
1043 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
986 { 1044 {
987 //Need to kill the for sale here 1045 //Need to kill the for sale here
988 rootPart.ObjectSaleType = 0; 1046 rootPart.ObjectSaleType = 0;
@@ -992,31 +1050,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
992 { 1050 {
993 foreach (SceneObjectPart part in so.Parts) 1051 foreach (SceneObjectPart part in so.Parts)
994 { 1052 {
995 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
996 {
997 part.EveryoneMask = item.EveryOnePermissions;
998 part.NextOwnerMask = item.NextPermissions;
999 }
1000 part.GroupMask = 0; // DO NOT propagate here 1053 part.GroupMask = 0; // DO NOT propagate here
1054
1055 part.LastOwnerID = part.OwnerID;
1056 part.OwnerID = item.Owner;
1057 part.Inventory.ChangeInventoryOwner(item.Owner);
1001 } 1058 }
1002 1059
1003 so.ApplyNextOwnerPermissions(); 1060 so.ApplyNextOwnerPermissions();
1061
1062 // In case the user has changed flags on a received item
1063 // we have to apply those changes after the slam. Else we
1064 // get a net loss of permissions
1065 foreach (SceneObjectPart part in so.Parts)
1066 {
1067 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1068 {
1069 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1070 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1071 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1072 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1073 }
1074 }
1004 } 1075 }
1005 } 1076 }
1006 1077 else
1007 foreach (SceneObjectPart part in so.Parts)
1008 { 1078 {
1009 part.FromUserInventoryItemID = fromUserInventoryItemId; 1079 foreach (SceneObjectPart part in so.Parts)
1010
1011 if ((part.OwnerID != item.Owner) ||
1012 (item.CurrentPermissions & 16) != 0)
1013 { 1080 {
1014 part.Inventory.ChangeInventoryOwner(item.Owner); 1081 part.FromUserInventoryItemID = fromUserInventoryItemId;
1015 part.GroupMask = 0; // DO NOT propagate here 1082
1083 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1084 part.EveryoneMask = item.EveryOnePermissions;
1085 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1086 part.NextOwnerMask = item.NextPermissions;
1087 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1088 part.GroupMask = item.GroupPermissions;
1016 } 1089 }
1017
1018 part.EveryoneMask = item.EveryOnePermissions;
1019 part.NextOwnerMask = item.NextPermissions;
1020 } 1090 }
1021 1091
1022 rootPart.TrimPermissions(); 1092 rootPart.TrimPermissions();
@@ -1154,4 +1224,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1154 1224
1155 #endregion 1225 #endregion
1156 } 1226 }
1157} \ No newline at end of file 1227}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 0c60391..4f18b53 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -90,9 +90,9 @@ namespace OpenSim.Region.CoreModules.Hypergrid
90 } 90 }
91 } 91 }
92 92
93 protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 93 protected override List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
94 { 94 {
95 List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); 95 List<MapBlockData> mapBlocks = base.GetAndSendBlocksInternal(remoteClient, minX, minY, maxX, maxY, flag);
96 lock (m_SeenMapBlocks) 96 lock (m_SeenMapBlocks)
97 { 97 {
98 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId)) 98 if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
diff --git a/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs
index 16cbbf5..f49641f 100644
--- a/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs
+++ b/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs
@@ -170,7 +170,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
170 170
171 private void EventManager_OnMakeRootAgent(ScenePresence presence) 171 private void EventManager_OnMakeRootAgent(ScenePresence presence)
172 { 172 {
173 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); 173 if (m_enableWindlight && m_scene.RegionInfo.WindlightSettings.valid)
174 m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client");
174 SendProfileToClient(presence.ControllingClient); 175 SendProfileToClient(presence.ControllingClient);
175 } 176 }
176 177
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index d328eb3..9dac6b9 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -382,6 +382,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
382 try 382 try
383 { 383 {
384 Request = (HttpWebRequest) WebRequest.Create(Url); 384 Request = (HttpWebRequest) WebRequest.Create(Url);
385
386 //This works around some buggy HTTP Servers like Lighttpd
387 Request.ServicePoint.Expect100Continue = false;
388
385 Request.Method = HttpMethod; 389 Request.Method = HttpMethod;
386 Request.ContentType = HttpMIMEType; 390 Request.ContentType = HttpMIMEType;
387 391
@@ -458,15 +462,36 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
458 462
459 // continue building the string 463 // continue building the string
460 sb.Append(tempString); 464 sb.Append(tempString);
465 if (sb.Length > 2048)
466 break;
461 } 467 }
462 } while (count > 0); // any more data to read? 468 } while (count > 0); // any more data to read?
463 469
464 ResponseBody = sb.ToString(); 470 ResponseBody = sb.ToString().Replace("\r", "");
465 } 471 }
466 catch (Exception e) 472 catch (Exception e)
467 { 473 {
468 Status = (int)OSHttpStatusCode.ClientErrorJoker; 474 if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError)
469 ResponseBody = e.Message; 475 {
476 HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response;
477 Status = (int)webRsp.StatusCode;
478 try
479 {
480 using (Stream responseStream = webRsp.GetResponseStream())
481 {
482 ResponseBody = responseStream.GetStreamString();
483 }
484 }
485 catch
486 {
487 ResponseBody = webRsp.StatusDescription;
488 }
489 }
490 else
491 {
492 Status = (int)OSHttpStatusCode.ClientErrorJoker;
493 ResponseBody = e.Message;
494 }
470 495
471 _finished = true; 496 _finished = true;
472 return; 497 return;
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 53a9679..0b9174f 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -41,39 +41,13 @@ using OpenSim.Region.Framework.Scenes;
41 41
42namespace OpenSim.Region.CoreModules.Scripting.LSLHttp 42namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
43{ 43{
44 /// <summary>
45 /// Data describing an external URL set up by a script.
46 /// </summary>
47 public class UrlData 44 public class UrlData
48 { 45 {
49 /// <summary>
50 /// Scene object part hosting the script
51 /// </summary>
52 public UUID hostID; 46 public UUID hostID;
53
54 /// <summary>
55 /// The item ID of the script that requested the URL.
56 /// </summary>
57 public UUID itemID; 47 public UUID itemID;
58
59 /// <summary>
60 /// The script engine that runs the script.
61 /// </summary>
62 public IScriptModule engine; 48 public IScriptModule engine;
63
64 /// <summary>
65 /// The generated URL.
66 /// </summary>
67 public string url; 49 public string url;
68
69 /// <summary>
70 /// The random UUID component of the generated URL.
71 /// </summary>
72 public UUID urlcode; 50 public UUID urlcode;
73
74 /// <summary>
75 /// The external requests currently being processed or awaiting retrieval for this URL.
76 /// </summary>
77 public Dictionary<UUID, RequestData> requests; 51 public Dictionary<UUID, RequestData> requests;
78 } 52 }
79 53
@@ -88,37 +62,26 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
88 //public ManualResetEvent ev; 62 //public ManualResetEvent ev;
89 public bool requestDone; 63 public bool requestDone;
90 public int startTime; 64 public int startTime;
65 public bool responseSent;
91 public string uri; 66 public string uri;
92 } 67 }
93 68
94 /// <summary>
95 /// This module provides external URLs for in-world scripts.
96 /// </summary>
97 public class UrlModule : ISharedRegionModule, IUrlModule 69 public class UrlModule : ISharedRegionModule, IUrlModule
98 { 70 {
99 private static readonly ILog m_log = 71 private static readonly ILog m_log =
100 LogManager.GetLogger( 72 LogManager.GetLogger(
101 MethodBase.GetCurrentMethod().DeclaringType); 73 MethodBase.GetCurrentMethod().DeclaringType);
102 74
103 /// <summary> 75 private Dictionary<UUID, UrlData> m_RequestMap =
104 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 76 new Dictionary<UUID, UrlData>();
105 /// randomly generated when a request is received for this URL.
106 /// </summary>
107 /// <remarks>
108 /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
109 /// m_UrlMap
110 /// </remarks>
111 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
112 77
113 /// <summary> 78 private Dictionary<string, UrlData> m_UrlMap =
114 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 79 new Dictionary<string, UrlData>();
115 /// </summary>
116 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
117 80
118 /// <summary> 81 /// <summary>
119 /// Maximum number of external urls that can be set up by this module. 82 /// Maximum number of external urls that can be set up by this module.
120 /// </summary> 83 /// </summary>
121 private int m_TotalUrls = 100; 84 private int m_TotalUrls = 15000;
122 85
123 private uint https_port = 0; 86 private uint https_port = 0;
124 private IHttpServer m_HttpServer = null; 87 private IHttpServer m_HttpServer = null;
@@ -144,9 +107,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
144 { 107 {
145 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 108 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
146 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); 109 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
147
148 if (ssl_enabled) 110 if (ssl_enabled)
111 {
149 https_port = (uint) config.Configs["Network"].GetInt("https_port",0); 112 https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
113 }
150 114
151 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 115 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
152 116
@@ -207,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
207 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 171 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
208 return urlcode; 172 return urlcode;
209 } 173 }
210 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 174 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
211 175
212 UrlData urlData = new UrlData(); 176 UrlData urlData = new UrlData();
213 urlData.hostID = host.UUID; 177 urlData.hostID = host.UUID;
@@ -216,18 +180,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
216 urlData.url = url; 180 urlData.url = url;
217 urlData.urlcode = urlcode; 181 urlData.urlcode = urlcode;
218 urlData.requests = new Dictionary<UUID, RequestData>(); 182 urlData.requests = new Dictionary<UUID, RequestData>();
219 183
220 m_UrlMap[url] = urlData; 184 m_UrlMap[url] = urlData;
221 185
222 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 186 string uri = "/lslhttp/" + urlcode.ToString();
223 187
224 m_HttpServer.AddPollServiceHTTPHandler( 188 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
225 uri, 189 args.Type = PollServiceEventArgs.EventType.LslHttp;
226 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 190 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
227 191
228 m_log.DebugFormat( 192// m_log.DebugFormat(
229 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 193// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
230 uri, itemID, host.Name, host.LocalId); 194// uri, itemID, host.Name, host.LocalId);
231 195
232 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 196 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
233 } 197 }
@@ -252,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
252 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 216 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
253 return urlcode; 217 return urlcode;
254 } 218 }
255 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 219 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
256 220
257 UrlData urlData = new UrlData(); 221 UrlData urlData = new UrlData();
258 urlData.hostID = host.UUID; 222 urlData.hostID = host.UUID;
@@ -262,17 +226,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
262 urlData.urlcode = urlcode; 226 urlData.urlcode = urlcode;
263 urlData.requests = new Dictionary<UUID, RequestData>(); 227 urlData.requests = new Dictionary<UUID, RequestData>();
264 228
229
265 m_UrlMap[url] = urlData; 230 m_UrlMap[url] = urlData;
266 231
267 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 232 string uri = "/lslhttps/" + urlcode.ToString();
268 233
269 m_HttpsServer.AddPollServiceHTTPHandler( 234 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
270 uri, 235 args.Type = PollServiceEventArgs.EventType.LslHttp;
271 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 236 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
272 237
273 m_log.DebugFormat( 238// m_log.DebugFormat(
274 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 239// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
275 uri, itemID, host.Name, host.LocalId); 240// uri, itemID, host.Name, host.LocalId);
276 241
277 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); 242 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
278 } 243 }
@@ -291,12 +256,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
291 return; 256 return;
292 } 257 }
293 258
294 foreach (UUID req in data.requests.Keys) 259 lock (m_RequestMap)
295 m_RequestMap.Remove(req); 260 {
296 261 foreach (UUID req in data.requests.Keys)
297 m_log.DebugFormat( 262 m_RequestMap.Remove(req);
298 "[URL MODULE]: Releasing url {0} for {1} in {2}", 263 }
299 url, data.itemID, data.hostID); 264
265// m_log.DebugFormat(
266// "[URL MODULE]: Releasing url {0} for {1} in {2}",
267// url, data.itemID, data.hostID);
300 268
301 RemoveUrl(data); 269 RemoveUrl(data);
302 m_UrlMap.Remove(url); 270 m_UrlMap.Remove(url);
@@ -321,15 +289,19 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
321 289
322 public void HttpResponse(UUID request, int status, string body) 290 public void HttpResponse(UUID request, int status, string body)
323 { 291 {
324 lock (m_UrlMap) 292 lock (m_RequestMap)
325 { 293 {
326 if (m_RequestMap.ContainsKey(request)) 294 if (m_RequestMap.ContainsKey(request))
327 { 295 {
328 UrlData urlData = m_RequestMap[request]; 296 UrlData urlData = m_RequestMap[request];
329 urlData.requests[request].responseCode = status; 297 if (!urlData.requests[request].responseSent)
330 urlData.requests[request].responseBody = body; 298 {
331 //urlData.requests[request].ev.Set(); 299 urlData.requests[request].responseCode = status;
332 urlData.requests[request].requestDone =true; 300 urlData.requests[request].responseBody = body;
301 //urlData.requests[request].ev.Set();
302 urlData.requests[request].requestDone = true;
303 urlData.requests[request].responseSent = true;
304 }
333 } 305 }
334 else 306 else
335 { 307 {
@@ -340,7 +312,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
340 312
341 public string GetHttpHeader(UUID requestId, string header) 313 public string GetHttpHeader(UUID requestId, string header)
342 { 314 {
343 lock (m_UrlMap) 315 lock (m_RequestMap)
344 { 316 {
345 if (m_RequestMap.ContainsKey(requestId)) 317 if (m_RequestMap.ContainsKey(requestId))
346 { 318 {
@@ -354,14 +326,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
354 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 326 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
355 } 327 }
356 } 328 }
357
358 return String.Empty; 329 return String.Empty;
359 } 330 }
360 331
361 public int GetFreeUrls() 332 public int GetFreeUrls()
362 { 333 {
363 lock (m_UrlMap) 334 return m_TotalUrls - m_UrlMap.Count;
364 return m_TotalUrls - m_UrlMap.Count;
365 } 335 }
366 336
367 public void ScriptRemoved(UUID itemID) 337 public void ScriptRemoved(UUID itemID)
@@ -378,8 +348,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
378 { 348 {
379 RemoveUrl(url.Value); 349 RemoveUrl(url.Value);
380 removeURLs.Add(url.Key); 350 removeURLs.Add(url.Key);
381 foreach (UUID req in url.Value.requests.Keys) 351 lock (m_RequestMap)
382 m_RequestMap.Remove(req); 352 {
353 foreach (UUID req in url.Value.requests.Keys)
354 m_RequestMap.Remove(req);
355 }
383 } 356 }
384 } 357 }
385 358
@@ -400,9 +373,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
400 { 373 {
401 RemoveUrl(url.Value); 374 RemoveUrl(url.Value);
402 removeURLs.Add(url.Key); 375 removeURLs.Add(url.Key);
403 376 lock (m_RequestMap)
404 foreach (UUID req in url.Value.requests.Keys) 377 {
405 m_RequestMap.Remove(req); 378 foreach (UUID req in url.Value.requests.Keys)
379 m_RequestMap.Remove(req);
380 }
406 } 381 }
407 } 382 }
408 383
@@ -411,123 +386,125 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
411 } 386 }
412 } 387 }
413 388
389
414 private void RemoveUrl(UrlData data) 390 private void RemoveUrl(UrlData data)
415 { 391 {
416 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 392 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
417 } 393 }
418 394
419 private Hashtable NoEvents(UUID requestID, UUID sessionID) 395 private Hashtable NoEvents(UUID requestID, UUID sessionID)
420 { 396 {
421 Hashtable response = new Hashtable(); 397 Hashtable response = new Hashtable();
422 UrlData urlData; 398 UrlData url;
423 399 int startTime = 0;
424 lock (m_UrlMap) 400 lock (m_RequestMap)
425 { 401 {
426 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
427 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
428 // for the request ID.
429 if (!m_RequestMap.ContainsKey(requestID)) 402 if (!m_RequestMap.ContainsKey(requestID))
430 {
431 response["int_response_code"] = 404;
432 response["str_response_string"] = "";
433 response["keepalive"] = false;
434 response["reusecontext"] = false;
435
436 return response; 403 return response;
437 } 404 url = m_RequestMap[requestID];
405 startTime = url.requests[requestID].startTime;
406 }
438 407
439 urlData = m_RequestMap[requestID]; 408 if (System.Environment.TickCount - startTime > 25000)
409 {
410 response["int_response_code"] = 500;
411 response["str_response_string"] = "Script timeout";
412 response["content_type"] = "text/plain";
413 response["keepalive"] = false;
414 response["reusecontext"] = false;
440 415
441 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 416 //remove from map
417 lock (url.requests)
418 {
419 url.requests.Remove(requestID);
420 }
421 lock (m_RequestMap)
442 { 422 {
443 response["int_response_code"] = 500;
444 response["str_response_string"] = "Script timeout";
445 response["content_type"] = "text/plain";
446 response["keepalive"] = false;
447 response["reusecontext"] = false;
448
449 //remove from map
450 urlData.requests.Remove(requestID);
451 m_RequestMap.Remove(requestID); 423 m_RequestMap.Remove(requestID);
452
453 return response;
454 } 424 }
425
426 return response;
455 } 427 }
456 428
429
457 return response; 430 return response;
458 } 431 }
459 432
460 private bool HasEvents(UUID requestID, UUID sessionID) 433 private bool HasEvents(UUID requestID, UUID sessionID)
461 { 434 {
462 lock (m_UrlMap) 435 UrlData url=null;
436
437 lock (m_RequestMap)
463 { 438 {
464 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
465 // can still make it through to HttpRequestHandler(). That will return without setting up a request
466 // when it detects that the URL has been removed. The poller, however, will continue to ask for
467 // events for that request, so here we will signal that there are events and in GetEvents we will
468 // return a 404.
469 if (!m_RequestMap.ContainsKey(requestID)) 439 if (!m_RequestMap.ContainsKey(requestID))
470 { 440 {
471 return true; 441 return false;
472 } 442 }
473 443 url = m_RequestMap[requestID];
474 UrlData urlData = m_RequestMap[requestID]; 444 }
475 445 lock (url.requests)
476 if (!urlData.requests.ContainsKey(requestID)) 446 {
447 if (!url.requests.ContainsKey(requestID))
477 { 448 {
478 return true; 449 return false;
479 } 450 }
480 451 else
481 // Trigger return of timeout response.
482 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
483 { 452 {
484 return true; 453 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
454 {
455 return true;
456 }
457 if (url.requests[requestID].requestDone)
458 return true;
459 else
460 return false;
485 } 461 }
486
487 return urlData.requests[requestID].requestDone;
488 } 462 }
489 } 463 }
490 464 private Hashtable GetEvents(UUID requestID, UUID sessionID)
491 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
492 { 465 {
493 Hashtable response; 466 UrlData url = null;
467 RequestData requestData = null;
494 468
495 lock (m_UrlMap) 469 lock (m_RequestMap)
496 { 470 {
497 UrlData url = null;
498 RequestData requestData = null;
499
500 if (!m_RequestMap.ContainsKey(requestID)) 471 if (!m_RequestMap.ContainsKey(requestID))
501 return NoEvents(requestID, sessionID); 472 return NoEvents(requestID,sessionID);
502
503 url = m_RequestMap[requestID]; 473 url = m_RequestMap[requestID];
474 }
475 lock (url.requests)
476 {
504 requestData = url.requests[requestID]; 477 requestData = url.requests[requestID];
478 }
479
480 if (!requestData.requestDone)
481 return NoEvents(requestID,sessionID);
482
483 Hashtable response = new Hashtable();
505 484
506 if (!requestData.requestDone) 485 if (System.Environment.TickCount - requestData.startTime > 25000)
507 return NoEvents(requestID, sessionID); 486 {
508 487 response["int_response_code"] = 500;
509 response = new Hashtable(); 488 response["str_response_string"] = "Script timeout";
510 489 response["content_type"] = "text/plain";
511 if (System.Environment.TickCount - requestData.startTime > 25000)
512 {
513 response["int_response_code"] = 500;
514 response["str_response_string"] = "Script timeout";
515 response["content_type"] = "text/plain";
516 response["keepalive"] = false;
517 response["reusecontext"] = false;
518 return response;
519 }
520
521 //put response
522 response["int_response_code"] = requestData.responseCode;
523 response["str_response_string"] = requestData.responseBody;
524 response["content_type"] = requestData.responseType;
525 // response["content_type"] = "text/plain";
526 response["keepalive"] = false; 490 response["keepalive"] = false;
527 response["reusecontext"] = false; 491 response["reusecontext"] = false;
528 492 return response;
529 //remove from map 493 }
494 //put response
495 response["int_response_code"] = requestData.responseCode;
496 response["str_response_string"] = requestData.responseBody;
497 response["content_type"] = "text/plain";
498 response["keepalive"] = false;
499 response["reusecontext"] = false;
500
501 //remove from map
502 lock (url.requests)
503 {
530 url.requests.Remove(requestID); 504 url.requests.Remove(requestID);
505 }
506 lock (m_RequestMap)
507 {
531 m_RequestMap.Remove(requestID); 508 m_RequestMap.Remove(requestID);
532 } 509 }
533 510
@@ -536,41 +513,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
536 513
537 public void HttpRequestHandler(UUID requestID, Hashtable request) 514 public void HttpRequestHandler(UUID requestID, Hashtable request)
538 { 515 {
539 string uri = request["uri"].ToString(); 516 lock (request)
540 bool is_ssl = uri.Contains("lslhttps");
541
542 try
543 { 517 {
544 Hashtable headers = (Hashtable)request["headers"]; 518 string uri = request["uri"].ToString();
545 519 bool is_ssl = uri.Contains("lslhttps");
546// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
547
548 int pos1 = uri.IndexOf("/");// /lslhttp
549 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
550 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
551 string uri_tmp = uri.Substring(0, pos3 + 1);
552 //HTTP server code doesn't provide us with QueryStrings
553 string pathInfo;
554 string queryString;
555 queryString = "";
556 520
557 pathInfo = uri.Substring(pos3); 521 try
558
559 UrlData urlData = null;
560
561 lock (m_UrlMap)
562 { 522 {
563 string url; 523 Hashtable headers = (Hashtable)request["headers"];
524
525// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
564 526
565 if (is_ssl) 527 int pos1 = uri.IndexOf("/");// /lslhttp
566 url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 528 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
529 int pos3 = pos2 + 37; // /lslhttp/urlcode
530 string uri_tmp = uri.Substring(0, pos3);
531 //HTTP server code doesn't provide us with QueryStrings
532 string pathInfo;
533 string queryString;
534 queryString = "";
535
536 pathInfo = uri.Substring(pos3);
537
538 UrlData url = null;
539 string urlkey;
540 if (!is_ssl)
541 urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
542 //m_UrlMap[];
567 else 543 else
568 url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 544 urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
569 545
570 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 546 if (m_UrlMap.ContainsKey(urlkey))
571 // request was being processed. 547 {
572 if (!m_UrlMap.TryGetValue(url, out urlData)) 548 url = m_UrlMap[urlkey];
549 }
550 else
551 {
552 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
573 return; 553 return;
554 }
574 555
575 //for llGetHttpHeader support we need to store original URI here 556 //for llGetHttpHeader support we need to store original URI here
576 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 557 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -590,7 +571,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
590 string value = (string)header.Value; 571 string value = (string)header.Value;
591 requestData.headers.Add(key, value); 572 requestData.headers.Add(key, value);
592 } 573 }
593
594 foreach (DictionaryEntry de in request) 574 foreach (DictionaryEntry de in request)
595 { 575 {
596 if (de.Key.ToString() == "querystringkeys") 576 if (de.Key.ToString() == "querystringkeys")
@@ -601,13 +581,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
601 if (request.ContainsKey(key)) 581 if (request.ContainsKey(key))
602 { 582 {
603 string val = (String)request[key]; 583 string val = (String)request[key];
604 queryString = queryString + key + "=" + val + "&"; 584 if (key != "")
585 {
586 queryString = queryString + key + "=" + val + "&";
587 }
588 else
589 {
590 queryString = queryString + val + "&";
591 }
605 } 592 }
606 } 593 }
607
608 if (queryString.Length > 1) 594 if (queryString.Length > 1)
609 queryString = queryString.Substring(0, queryString.Length - 1); 595 queryString = queryString.Substring(0, queryString.Length - 1);
596
610 } 597 }
598
611 } 599 }
612 600
613 //if this machine is behind DNAT/port forwarding, currently this is being 601 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -615,23 +603,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
615 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 603 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
616 requestData.headers["x-path-info"] = pathInfo; 604 requestData.headers["x-path-info"] = pathInfo;
617 requestData.headers["x-query-string"] = queryString; 605 requestData.headers["x-query-string"] = queryString;
618 requestData.headers["x-script-url"] = urlData.url; 606 requestData.headers["x-script-url"] = url.url;
619 607
620 urlData.requests.Add(requestID, requestData); 608 //requestData.ev = new ManualResetEvent(false);
621 m_RequestMap.Add(requestID, urlData); 609 lock (url.requests)
622 } 610 {
611 url.requests.Add(requestID, requestData);
612 }
613 lock (m_RequestMap)
614 {
615 //add to request map
616 m_RequestMap.Add(requestID, url);
617 }
623 618
624 urlData.engine.PostScriptEvent( 619 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
625 urlData.itemID, 620
626 "http_request", 621 //send initial response?
627 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 622// Hashtable response = new Hashtable();
628 } 623
629 catch (Exception we) 624 return;
630 { 625
631 //Hashtable response = new Hashtable(); 626 }
632 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 627 catch (Exception we)
633 m_log.Warn(we.Message); 628 {
634 m_log.Warn(we.StackTrace); 629 //Hashtable response = new Hashtable();
630 m_log.Warn("[HttpRequestHandler]: http-in request failed");
631 m_log.Warn(we.Message);
632 m_log.Warn(we.StackTrace);
633 }
635 } 634 }
636 } 635 }
637 636
@@ -640,4 +639,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
640 ScriptRemoved(itemID); 639 ScriptRemoved(itemID);
641 } 640 }
642 } 641 }
643} \ No newline at end of file 642}
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index b4e3d77..673c2d1 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -840,4 +840,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
840 return null; 840 return null;
841 } 841 }
842 } 842 }
843} \ No newline at end of file 843}
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 8358bc0..07bb291 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -90,6 +90,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
90 // private static readonly ILog m_log = 90 // private static readonly ILog m_log =
91 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 91 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
92 92
93 private const int DEBUG_CHANNEL = 2147483647;
94
93 private ListenerManager m_listenerManager; 95 private ListenerManager m_listenerManager;
94 private Queue m_pending; 96 private Queue m_pending;
95 private Queue m_pendingQ; 97 private Queue m_pendingQ;
@@ -308,56 +310,59 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
308 /// <param name='msg'> 310 /// <param name='msg'>
309 /// Message. 311 /// Message.
310 /// </param> 312 /// </param>
311 public void DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg) 313 public bool DeliverMessageTo(UUID target, int channel, Vector3 pos, string name, UUID id, string msg, out string error)
312 { 314 {
315 error = null;
316
317 if (channel == DEBUG_CHANNEL)
318 return true;
319
313 // Is id an avatar? 320 // Is id an avatar?
314 ScenePresence sp = m_scene.GetScenePresence(target); 321 ScenePresence sp = m_scene.GetScenePresence(target);
315 322
316 if (sp != null) 323 if (sp != null)
317 { 324 {
318 // ignore if a child agent this is restricted to inside one region 325 // Send message to avatar
319 if (sp.IsChildAgent)
320 return;
321
322 // Send message to the avatar.
323 // Channel zero only goes to the avatar
324 // non zero channel messages only go to the attachments
325 if (channel == 0) 326 if (channel == 0)
326 { 327 {
327 m_scene.SimChatToAgent(target, Utils.StringToBytes(msg), pos, name, id, false); 328 // Channel 0 goes to viewer ONLY
328 } 329 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target);
329 else 330 return true;
330 { 331 }
331 List<SceneObjectGroup> attachments = sp.GetAttachments();
332 if (attachments.Count == 0)
333 return;
334 332
335 // Get uuid of attachments 333 List<SceneObjectGroup> attachments = sp.GetAttachments();
336 List<UUID> targets = new List<UUID>();
337 foreach (SceneObjectGroup sog in attachments)
338 {
339 if (!sog.IsDeleted)
340 targets.Add(sog.UUID);
341 }
342 334
343 // Need to check each attachment 335 if (attachments.Count == 0)
344 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 336 return true;
345 {
346 if (li.GetHostID().Equals(id))
347 continue;
348 337
349 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null) 338 // Get uuid of attachments
350 continue; 339 List<UUID> targets = new List<UUID>();
340 foreach (SceneObjectGroup sog in attachments)
341 {
342 if (!sog.IsDeleted)
343 targets.Add(sog.UUID);
344 }
351 345
352 if (targets.Contains(li.GetHostID())) 346 // Need to check each attachment
353 QueueMessage(new ListenerInfo(li, name, id, msg)); 347 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
354 } 348 {
349 if (li.GetHostID().Equals(id))
350 continue;
351
352 if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
353 continue;
354
355 if (targets.Contains(li.GetHostID()))
356 QueueMessage(new ListenerInfo(li, name, id, msg));
355 } 357 }
356 358
357 return; 359 return true;
358 } 360 }
359 361
360 // No avatar found so look for an object 362 SceneObjectPart part = m_scene.GetSceneObjectPart(target);
363 if (part == null) // Not even an object
364 return true; // No error
365
361 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 366 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
362 { 367 {
363 // Dont process if this message is from yourself! 368 // Dont process if this message is from yourself!
@@ -375,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
375 } 380 }
376 } 381 }
377 382
378 return; 383 return true;
379 } 384 }
380 385
381 protected void QueueMessage(ListenerInfo li) 386 protected void QueueMessage(ListenerInfo li)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
index 9484a5a..d809ac2 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
@@ -137,6 +137,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
137 137
138 #region IAuthenticationService 138 #region IAuthenticationService
139 139
140 public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
141 {
142 // Not implemented at the regions
143 realID = UUID.Zero;
144 return string.Empty;
145 }
146
140 public string Authenticate(UUID principalID, string password, int lifetime) 147 public string Authenticate(UUID principalID, string password, int lifetime)
141 { 148 {
142 // Not implemented at the regions 149 // Not implemented at the regions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 9d282b8..e4c6c1a 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 1e52d37..8ed1833 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -301,6 +301,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
301 return false; 301 return false;
302 } 302 }
303 303
304 public bool CloseChildAgent(GridRegion destination, UUID id)
305 {
306 return CloseAgent(destination, id);
307 }
308
304 public bool CloseAgent(GridRegion destination, UUID id) 309 public bool CloseAgent(GridRegion destination, UUID id)
305 { 310 {
306 if (destination == null) 311 if (destination == null)
@@ -315,7 +320,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
315 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); 320 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
316 return true; 321 return true;
317 } 322 }
318
319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 323 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
320 return false; 324 return false;
321 } 325 }
@@ -374,4 +378,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
374 378
375 #endregion 379 #endregion
376 } 380 }
377} \ No newline at end of file 381}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index bd4a23b..68be552 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -260,6 +260,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
260 return false; 260 return false;
261 } 261 }
262 262
263 public bool CloseChildAgent(GridRegion destination, UUID id)
264 {
265 if (destination == null)
266 return false;
267
268 // Try local first
269 if (m_localBackend.CloseChildAgent(destination, id))
270 return true;
271
272 // else do the remote thing
273 if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
274 return m_remoteConnector.CloseChildAgent(destination, id);
275
276 return false;
277 }
263 278
264 public bool CloseAgent(GridRegion destination, UUID id) 279 public bool CloseAgent(GridRegion destination, UUID id)
265 { 280 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
index 0a0ce3c..1ffd480 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
127 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner 127 // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner
128 // user account service?! 128 // user account service?!
129 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService); 129 scene.RegisterModuleInterface<IUserAccountService>(UserAccountService);
130 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
130 } 131 }
131 132
132 public void RemoveRegion(Scene scene) 133 public void RemoveRegion(Scene scene)
@@ -179,6 +180,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
179 return UserAccountService.GetUserAccount(scopeID, Email); 180 return UserAccountService.GetUserAccount(scopeID, Email);
180 } 181 }
181 182
183 public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
184 {
185 return null;
186 }
187
182 public List<UserAccount> GetUserAccounts(UUID scopeID, string query) 188 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
183 { 189 {
184 return UserAccountService.GetUserAccounts(scopeID, query); 190 return UserAccountService.GetUserAccounts(scopeID, query);
@@ -193,4 +199,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
193 199
194 #endregion 200 #endregion
195 } 201 }
196} \ No newline at end of file 202}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
index 3321b38..f6b6aeb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
@@ -33,6 +33,7 @@ using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
35using OpenSim.Services.Connectors; 35using OpenSim.Services.Connectors;
36using OpenSim.Framework;
36 37
37using OpenMetaverse; 38using OpenMetaverse;
38 39
@@ -101,6 +102,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
101 return; 102 return;
102 103
103 scene.RegisterModuleInterface<IUserAccountService>(this); 104 scene.RegisterModuleInterface<IUserAccountService>(this);
105 scene.RegisterModuleInterface<IUserAccountCacheModule>(m_Cache);
106
107 scene.EventManager.OnNewClient += OnNewClient;
104 } 108 }
105 109
106 public void RemoveRegion(Scene scene) 110 public void RemoveRegion(Scene scene)
@@ -115,6 +119,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
115 return; 119 return;
116 } 120 }
117 121
122 // When a user actually enters the sim, clear them from
123 // cache so the sim will have the current values for
124 // flags, title, etc. And country, don't forget country!
125 private void OnNewClient(IClientAPI client)
126 {
127 m_Cache.Remove(client.Name);
128 }
129
118 #region Overwritten methods from IUserAccountService 130 #region Overwritten methods from IUserAccountService
119 131
120 public override UserAccount GetUserAccount(UUID scopeID, UUID userID) 132 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 a6923ef..2127f4d 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
@@ -878,4 +896,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
878 return dearchivedScenes; 896 return dearchivedScenes;
879 } 897 }
880 } 898 }
881} \ No newline at end of file 899}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 5787279..bf58591 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -265,18 +265,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
265 265
266 if (asset != null) 266 if (asset != null)
267 { 267 {
268 if (m_options.ContainsKey("verbose")) 268// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
269 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
270
271 m_foundAssetUuids.Add(asset.FullID); 269 m_foundAssetUuids.Add(asset.FullID);
272 270
273 m_assetsArchiver.WriteAsset(PostProcess(asset)); 271 m_assetsArchiver.WriteAsset(PostProcess(asset));
274 } 272 }
275 else 273 else
276 { 274 {
277 if (m_options.ContainsKey("verbose")) 275// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
278 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
279
280 m_notFoundAssetUuids.Add(new UUID(id)); 276 m_notFoundAssetUuids.Add(new UUID(id));
281 } 277 }
282 278
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 0e6d663..5fd1bce 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
@@ -60,8 +62,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
60 public event ChangeDelegate OnEstateInfoChange; 62 public event ChangeDelegate OnEstateInfoChange;
61 public event MessageDelegate OnEstateMessage; 63 public event MessageDelegate OnEstateMessage;
62 64
65 private int m_delayCount = 0;
66
63 #region Packet Data Responders 67 #region Packet Data Responders
64 68
69 private void clientSendDetailedEstateData(IClientAPI remote_client, UUID invoice)
70 {
71 sendDetailedEstateData(remote_client, invoice);
72 sendEstateLists(remote_client, invoice);
73 }
74
65 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) 75 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice)
66 { 76 {
67 uint sun = 0; 77 uint sun = 0;
@@ -84,7 +94,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
84 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime, 94 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime,
85 Scene.RegionInfo.EstateSettings.AbuseEmail, 95 Scene.RegionInfo.EstateSettings.AbuseEmail,
86 estateOwner); 96 estateOwner);
97 }
87 98
99 private void sendEstateLists(IClientAPI remote_client, UUID invoice)
100 {
88 remote_client.SendEstateList(invoice, 101 remote_client.SendEstateList(invoice,
89 (int)Constants.EstateAccessCodex.EstateManagers, 102 (int)Constants.EstateAccessCodex.EstateManagers,
90 Scene.RegionInfo.EstateSettings.EstateManagers, 103 Scene.RegionInfo.EstateSettings.EstateManagers,
@@ -258,6 +271,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
258 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 271 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
259 if (restartModule != null) 272 if (restartModule != null)
260 { 273 {
274 if (timeInSeconds == -1)
275 {
276 m_delayCount++;
277 if (m_delayCount > 3)
278 return;
279
280 restartModule.DelayRestart(3600, "Restart delayed by region manager");
281 return;
282 }
283
261 List<int> times = new List<int>(); 284 List<int> times = new List<int>();
262 while (timeInSeconds > 0) 285 while (timeInSeconds > 0)
263 { 286 {
@@ -270,7 +293,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
270 timeInSeconds -= 15; 293 timeInSeconds -= 15;
271 } 294 }
272 295
273 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); 296 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false);
274 } 297 }
275 } 298 }
276 299
@@ -478,7 +501,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
478 { 501 {
479 if (!s.IsChildAgent) 502 if (!s.IsChildAgent)
480 { 503 {
481 Scene.TeleportClientHome(user, s.ControllingClient); 504 if (!Scene.TeleportClientHome(user, s.ControllingClient))
505 {
506 s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out.");
507 s.ControllingClient.Close();
508 }
482 } 509 }
483 } 510 }
484 511
@@ -487,7 +514,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
487 { 514 {
488 remote_client.SendAlertMessage("User is already on the region ban list"); 515 remote_client.SendAlertMessage("User is already on the region ban list");
489 } 516 }
490 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 517 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
491 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 518 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
492 } 519 }
493 else 520 else
@@ -542,7 +569,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
542 remote_client.SendAlertMessage("User is not on the region ban list"); 569 remote_client.SendAlertMessage("User is not on the region ban list");
543 } 570 }
544 571
545 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 572 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
546 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 573 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
547 } 574 }
548 else 575 else
@@ -701,7 +728,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
701 ScenePresence s = Scene.GetScenePresence(prey); 728 ScenePresence s = Scene.GetScenePresence(prey);
702 if (s != null) 729 if (s != null)
703 { 730 {
704 Scene.TeleportClientHome(prey, s.ControllingClient); 731 if (!Scene.TeleportClientHome(prey, s.ControllingClient))
732 {
733 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
734 s.ControllingClient.Close();
735 }
705 } 736 }
706 } 737 }
707 } 738 }
@@ -719,7 +750,13 @@ namespace OpenSim.Region.CoreModules.World.Estate
719 // Also make sure they are actually in the region 750 // Also make sure they are actually in the region
720 ScenePresence p; 751 ScenePresence p;
721 if(Scene.TryGetScenePresence(client.AgentId, out p)) 752 if(Scene.TryGetScenePresence(client.AgentId, out p))
722 Scene.TeleportClientHome(p.UUID, p.ControllingClient); 753 {
754 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
755 {
756 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
757 p.ControllingClient.Close();
758 }
759 }
723 } 760 }
724 }); 761 });
725 } 762 }
@@ -1082,6 +1119,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1082 1119
1083 public void AddRegion(Scene scene) 1120 public void AddRegion(Scene scene)
1084 { 1121 {
1122 m_regionChangeTimer.AutoReset = false;
1123 m_regionChangeTimer.Interval = 2000;
1124 m_regionChangeTimer.Elapsed += RaiseRegionInfoChange;
1125
1085 Scene = scene; 1126 Scene = scene;
1086 Scene.RegisterModuleInterface<IEstateModule>(this); 1127 Scene.RegisterModuleInterface<IEstateModule>(this);
1087 Scene.EventManager.OnNewClient += EventManager_OnNewClient; 1128 Scene.EventManager.OnNewClient += EventManager_OnNewClient;
@@ -1132,7 +1173,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1132 1173
1133 private void EventManager_OnNewClient(IClientAPI client) 1174 private void EventManager_OnNewClient(IClientAPI client)
1134 { 1175 {
1135 client.OnDetailedEstateDataRequest += sendDetailedEstateData; 1176 client.OnDetailedEstateDataRequest += clientSendDetailedEstateData;
1136 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler; 1177 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler;
1137// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture; 1178// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture;
1138 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture; 1179 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture;
@@ -1184,6 +1225,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1184 flags |= RegionFlags.AllowParcelChanges; 1225 flags |= RegionFlags.AllowParcelChanges;
1185 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1226 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1186 flags |= RegionFlags.BlockParcelSearch; 1227 flags |= RegionFlags.BlockParcelSearch;
1228 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1229 flags |= (RegionFlags)(1 << 11);
1230 if (Scene.RegionInfo.RegionSettings.Casino)
1231 flags |= (RegionFlags)(1 << 10);
1187 1232
1188 if (Scene.RegionInfo.RegionSettings.FixedSun) 1233 if (Scene.RegionInfo.RegionSettings.FixedSun)
1189 flags |= RegionFlags.SunFixed; 1234 flags |= RegionFlags.SunFixed;
@@ -1191,11 +1236,15 @@ namespace OpenSim.Region.CoreModules.World.Estate
1191 flags |= RegionFlags.Sandbox; 1236 flags |= RegionFlags.Sandbox;
1192 if (Scene.RegionInfo.EstateSettings.AllowVoice) 1237 if (Scene.RegionInfo.EstateSettings.AllowVoice)
1193 flags |= RegionFlags.AllowVoice; 1238 flags |= RegionFlags.AllowVoice;
1239 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1240 flags |= RegionFlags.AllowLandmark;
1241 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1242 flags |= RegionFlags.AllowSetHome;
1243 if (Scene.RegionInfo.EstateSettings.BlockDwell)
1244 flags |= RegionFlags.BlockDwell;
1245 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
1246 flags |= RegionFlags.ResetHomeOnTeleport;
1194 1247
1195 // Fudge these to always on, so the menu options activate
1196 //
1197 flags |= RegionFlags.AllowLandmark;
1198 flags |= RegionFlags.AllowSetHome;
1199 1248
1200 // TODO: SkipUpdateInterestList 1249 // TODO: SkipUpdateInterestList
1201 1250
@@ -1236,6 +1285,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1236 flags |= RegionFlags.ResetHomeOnTeleport; 1285 flags |= RegionFlags.ResetHomeOnTeleport;
1237 if (Scene.RegionInfo.EstateSettings.TaxFree) 1286 if (Scene.RegionInfo.EstateSettings.TaxFree)
1238 flags |= RegionFlags.TaxFree; 1287 flags |= RegionFlags.TaxFree;
1288 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1289 flags |= RegionFlags.AllowLandmark;
1290 if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
1291 flags |= RegionFlags.AllowParcelChanges;
1292 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1293 flags |= RegionFlags.AllowSetHome;
1239 if (Scene.RegionInfo.EstateSettings.DenyMinors) 1294 if (Scene.RegionInfo.EstateSettings.DenyMinors)
1240 flags |= (RegionFlags)(1 << 30); 1295 flags |= (RegionFlags)(1 << 30);
1241 1296
@@ -1256,6 +1311,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1256 1311
1257 public void TriggerRegionInfoChange() 1312 public void TriggerRegionInfoChange()
1258 { 1313 {
1314 m_regionChangeTimer.Stop();
1315 m_regionChangeTimer.Start();
1316 }
1317
1318 protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e)
1319 {
1259 ChangeDelegate change = OnRegionInfoChange; 1320 ChangeDelegate change = OnRegionInfoChange;
1260 1321
1261 if (change != null) 1322 if (change != null)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 8b7406d..aae6603 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -86,19 +86,21 @@ namespace OpenSim.Region.CoreModules.World.Land
86 /// <value> 86 /// <value>
87 /// Land objects keyed by local id 87 /// Land objects keyed by local id
88 /// </value> 88 /// </value>
89 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>(); 89// private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
90
91 //ubit: removed the readonly so i can move it around
92 private Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
90 93
91 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 94 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
92 95
93 private bool m_allowedForcefulBans = true; 96 private bool m_allowedForcefulBans = true;
97 private UUID DefaultGodParcelGroup;
98 private string DefaultGodParcelName;
94 99
95 // caches ExtendedLandData 100 // caches ExtendedLandData
96 private Cache parcelInfoCache; 101 private Cache parcelInfoCache;
97 102 private Dictionary<UUID, Vector3> forcedPosition =
98 /// <summary> 103 new Dictionary<UUID, Vector3>();
99 /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions.
100 /// </summary>
101 private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>();
102 104
103 #region INonSharedRegionModule Members 105 #region INonSharedRegionModule Members
104 106
@@ -109,6 +111,12 @@ namespace OpenSim.Region.CoreModules.World.Land
109 111
110 public void Initialise(IConfigSource source) 112 public void Initialise(IConfigSource source)
111 { 113 {
114 IConfig cnf = source.Configs["LandManagement"];
115 if (cnf != null)
116 {
117 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
118 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
119 }
112 } 120 }
113 121
114 public void AddRegion(Scene scene) 122 public void AddRegion(Scene scene)
@@ -160,13 +168,6 @@ namespace OpenSim.Region.CoreModules.World.Land
160 m_scene.UnregisterModuleCommander(m_commander.Name); 168 m_scene.UnregisterModuleCommander(m_commander.Name);
161 } 169 }
162 170
163// private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason)
164// {
165// ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y);
166// reason = "You are not allowed to enter this sim.";
167// return nearestParcel != null;
168// }
169
170 /// <summary> 171 /// <summary>
171 /// Processes commandline input. Do not call directly. 172 /// Processes commandline input. Do not call directly.
172 /// </summary> 173 /// </summary>
@@ -207,6 +208,8 @@ namespace OpenSim.Region.CoreModules.World.Land
207 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 208 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
208 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 209 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
209 client.OnPreAgentUpdate += ClientOnPreAgentUpdate; 210 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
211 client.OnParcelEjectUser += ClientOnParcelEjectUser;
212 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
210 213
211 EntityBase presenceEntity; 214 EntityBase presenceEntity;
212 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 215 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -218,48 +221,6 @@ namespace OpenSim.Region.CoreModules.World.Land
218 221
219 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 222 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
220 { 223 {
221 //If we are forcing a position for them to go
222 if (forcedPosition.ContainsKey(remoteClient.AgentId))
223 {
224 ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId);
225
226 //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND
227 //When the avatar walks into a ban line on the ground, it prevents getting stuck
228 agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
229
230 //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines
231 if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2)
232 {
233// m_log.DebugFormat(
234// "[LAND MANAGEMENT MODULE]: Stopping force position of {0} because {1} is close enough to {2}",
235// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
236
237 forcedPosition.Remove(remoteClient.AgentId);
238 }
239 //if we are far away, teleport
240 else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3)
241 {
242 Vector3 forcePosition = forcedPosition[remoteClient.AgentId];
243// m_log.DebugFormat(
244// "[LAND MANAGEMENT MODULE]: Teleporting out {0} because {1} is too far from avatar position {2}",
245// clientAvatar.Name, clientAvatar.AbsolutePosition, forcePosition);
246
247 m_scene.RequestTeleportLocation(remoteClient, m_scene.RegionInfo.RegionHandle,
248 forcePosition, clientAvatar.Lookat, (uint)Constants.TeleportFlags.ForceRedirect);
249
250 forcedPosition.Remove(remoteClient.AgentId);
251 }
252 else
253 {
254// m_log.DebugFormat(
255// "[LAND MANAGEMENT MODULE]: Forcing {0} from {1} to {2}",
256// clientAvatar.Name, clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]);
257
258 //Forces them toward the forced position we want if they aren't there yet
259 agentData.UseClientAgentPosition = true;
260 agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId];
261 }
262 }
263 } 224 }
264 225
265 public void Close() 226 public void Close()
@@ -284,15 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Land
284 { 245 {
285 LandData newData = data.Copy(); 246 LandData newData = data.Copy();
286 newData.LocalID = local_id; 247 newData.LocalID = local_id;
248 ILandObject landobj = null;
287 249
288 lock (m_landList) 250 lock (m_landList)
289 { 251 {
290 if (m_landList.ContainsKey(local_id)) 252 if (m_landList.ContainsKey(local_id))
291 { 253 {
292 m_landList[local_id].LandData = newData; 254 m_landList[local_id].LandData = newData;
293 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); 255 landobj = m_landList[local_id];
256// m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]);
294 } 257 }
295 } 258 }
259 if(landobj != null)
260 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj);
296 } 261 }
297 262
298 public bool AllowedForcefulBans 263 public bool AllowedForcefulBans
@@ -322,14 +287,14 @@ namespace OpenSim.Region.CoreModules.World.Land
322 protected ILandObject CreateDefaultParcel() 287 protected ILandObject CreateDefaultParcel()
323 { 288 {
324 m_log.DebugFormat( 289 m_log.DebugFormat(
325 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); 290 "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName);
326 291
327 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 292 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
328 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); 293 fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize));
329 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 294 fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
330 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 295 fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
331 296
332 return AddLandObject(fullSimParcel); 297 return AddLandObject(fullSimParcel);
333 } 298 }
334 299
335 public List<ILandObject> AllParcels() 300 public List<ILandObject> AllParcels()
@@ -378,10 +343,16 @@ namespace OpenSim.Region.CoreModules.World.Land
378 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 343 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
379 { 344 {
380 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 345 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
381 if (position.HasValue) 346
382 { 347 if (!position.HasValue)
383 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 348 return;
384 } 349
350 bool isFlying = avatar.PhysicsActor.Flying;
351 avatar.RemoveFromPhysicalScene();
352
353 avatar.AbsolutePosition = (Vector3)position;
354
355 avatar.AddToPhysicalScene(isFlying);
385 } 356 }
386 357
387 public void SendYouAreRestrictedNotice(ScenePresence avatar) 358 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -401,29 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Land
401 } 372 }
402 373
403 if (parcelAvatarIsEntering != null) 374 if (parcelAvatarIsEntering != null)
404 { 375 EnforceBans(parcelAvatarIsEntering, avatar);
405 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
406 {
407 if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID))
408 {
409 SendYouAreBannedNotice(avatar);
410 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
411 }
412 else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID))
413 {
414 SendYouAreRestrictedNotice(avatar);
415 ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar));
416 }
417 else
418 {
419 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
420 }
421 }
422 else
423 {
424 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
425 }
426 }
427 } 376 }
428 } 377 }
429 378
@@ -452,30 +401,51 @@ namespace OpenSim.Region.CoreModules.World.Land
452 401
453 public void SendLandUpdate(ScenePresence avatar, bool force) 402 public void SendLandUpdate(ScenePresence avatar, bool force)
454 { 403 {
404
405 /* stop sendind same data twice
406 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
407 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
408
409 if (over != null)
410 {
411
412 if (force)
413 {
414 if (!avatar.IsChildAgent)
415 {
416 over.SendLandUpdateToClient(avatar.ControllingClient);
417 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
418 m_scene.RegionInfo.RegionID);
419 }
420 }
421
422 if (avatar.currentParcelUUID != over.LandData.GlobalID)
423 {
424 if (!avatar.IsChildAgent)
425 {
426 over.SendLandUpdateToClient(avatar.ControllingClient);
427 avatar.currentParcelUUID = over.LandData.GlobalID;
428 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
429 m_scene.RegionInfo.RegionID);
430 }
431 }
432 */
433 if (avatar.IsChildAgent)
434 return;
435
455 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 436 ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
456 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 437 (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
457 438
458 if (over != null) 439 if (over != null)
459 { 440 {
460 if (force) 441 bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID);
442 if (force || NotsameID)
461 { 443 {
462 if (!avatar.IsChildAgent) 444 over.SendLandUpdateToClient(avatar.ControllingClient);
463 { 445 if (NotsameID)
464 over.SendLandUpdateToClient(avatar.ControllingClient);
465 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
466 m_scene.RegionInfo.RegionID);
467 }
468 }
469
470 if (avatar.currentParcelUUID != over.LandData.GlobalID)
471 {
472 if (!avatar.IsChildAgent)
473 {
474 over.SendLandUpdateToClient(avatar.ControllingClient);
475 avatar.currentParcelUUID = over.LandData.GlobalID; 446 avatar.currentParcelUUID = over.LandData.GlobalID;
476 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, 447 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID,
477 m_scene.RegionInfo.RegionID); 448 m_scene.RegionInfo.RegionID);
478 }
479 } 449 }
480 } 450 }
481 } 451 }
@@ -527,6 +497,7 @@ namespace OpenSim.Region.CoreModules.World.Land
527 //when we are finally in a safe place, lets release the forced position lock 497 //when we are finally in a safe place, lets release the forced position lock
528 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 498 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
529 } 499 }
500 EnforceBans(parcel, clientAvatar);
530 } 501 }
531 } 502 }
532 503
@@ -674,21 +645,28 @@ namespace OpenSim.Region.CoreModules.World.Land
674 /// </summary> 645 /// </summary>
675 public void Clear(bool setupDefaultParcel) 646 public void Clear(bool setupDefaultParcel)
676 { 647 {
648 Dictionary<int, ILandObject> landworkList;
649 // move to work pointer since we are deleting it all
677 lock (m_landList) 650 lock (m_landList)
678 { 651 {
679 foreach (ILandObject lo in m_landList.Values) 652 landworkList = m_landList;
680 { 653 m_landList = new Dictionary<int, ILandObject>();
681 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); 654 }
682 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
683 }
684 655
685 m_landList.Clear(); 656 // this 2 methods have locks (now)
657 ResetSimLandObjects();
686 658
687 ResetSimLandObjects(); 659 if (setupDefaultParcel)
660 CreateDefaultParcel();
688 661
689 if (setupDefaultParcel) 662 // fire outside events unlocked
690 CreateDefaultParcel(); 663 foreach (ILandObject lo in landworkList.Values)
664 {
665 //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID);
666 m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID);
691 } 667 }
668 landworkList.Clear();
669
692 } 670 }
693 671
694 private void performFinalLandJoin(ILandObject master, ILandObject slave) 672 private void performFinalLandJoin(ILandObject master, ILandObject slave)
@@ -735,7 +713,7 @@ namespace OpenSim.Region.CoreModules.World.Land
735 int x; 713 int x;
736 int y; 714 int y;
737 715
738 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 716 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
739 return null; 717 return null;
740 718
741 try 719 try
@@ -785,14 +763,13 @@ namespace OpenSim.Region.CoreModules.World.Land
785 { 763 {
786 try 764 try
787 { 765 {
788 return m_landList[m_landIDList[x / 4, y / 4]]; 766 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
767 return m_landList[m_landIDList[x / 4, y / 4]];
768 //else
769 // return null;
789 } 770 }
790 catch (IndexOutOfRangeException) 771 catch (IndexOutOfRangeException)
791 { 772 {
792// m_log.WarnFormat(
793// "[LAND MANAGEMENT MODULE]: Tried to retrieve land object from out of bounds co-ordinate ({0},{1}) in {2}",
794// x, y, m_scene.RegionInfo.RegionName);
795
796 return null; 773 return null;
797 } 774 }
798 } 775 }
@@ -1075,6 +1052,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1075 //Owner Flag 1052 //Owner Flag
1076 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1053 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1077 } 1054 }
1055 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1056 {
1057 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1058 }
1078 else if (currentParcelBlock.LandData.SalePrice > 0 && 1059 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1079 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1060 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1080 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1061 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1155,8 +1136,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1155 { 1136 {
1156 if (!temp.Contains(currentParcel)) 1137 if (!temp.Contains(currentParcel))
1157 { 1138 {
1158 currentParcel.ForceUpdateLandInfo(); 1139 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1159 temp.Add(currentParcel); 1140 {
1141 currentParcel.ForceUpdateLandInfo();
1142 temp.Add(currentParcel);
1143 }
1160 } 1144 }
1161 } 1145 }
1162 } 1146 }
@@ -1375,6 +1359,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1375 1359
1376 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1360 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1377 { 1361 {
1362 Dictionary<int, ILandObject> landworkList;
1363 // move to work pointer since we are deleting it all
1364 lock (m_landList)
1365 {
1366 landworkList = m_landList;
1367 m_landList = new Dictionary<int, ILandObject>();
1368 }
1369
1370 //Remove all the land objects in the sim and then process our new data
1371 foreach (int n in landworkList.Keys)
1372 {
1373 m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID);
1374 }
1375 landworkList.Clear();
1376
1377 lock (m_landList)
1378 {
1379 m_landIDList.Initialize();
1380 m_landList.Clear();
1381 }
1382
1378 for (int i = 0; i < data.Count; i++) 1383 for (int i = 0; i < data.Count; i++)
1379 { 1384 {
1380 IncomingLandObjectFromStorage(data[i]); 1385 IncomingLandObjectFromStorage(data[i]);
@@ -1383,10 +1388,12 @@ namespace OpenSim.Region.CoreModules.World.Land
1383 1388
1384 public void IncomingLandObjectFromStorage(LandData data) 1389 public void IncomingLandObjectFromStorage(LandData data)
1385 { 1390 {
1391
1386 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1392 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1387 new_land.LandData = data.Copy(); 1393 new_land.LandData = data.Copy();
1388 new_land.SetLandBitmapFromByteArray(); 1394 new_land.SetLandBitmapFromByteArray();
1389 AddLandObject(new_land); 1395 AddLandObject(new_land);
1396 new_land.SendLandUpdateToAvatarsOverMe();
1390 } 1397 }
1391 1398
1392 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1399 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1404,7 +1411,8 @@ namespace OpenSim.Region.CoreModules.World.Land
1404 1411
1405 public void EventManagerOnNoLandDataFromStorage() 1412 public void EventManagerOnNoLandDataFromStorage()
1406 { 1413 {
1407 lock (m_landList) 1414 // called methods already have locks
1415// lock (m_landList)
1408 { 1416 {
1409 ResetSimLandObjects(); 1417 ResetSimLandObjects();
1410 CreateDefaultParcel(); 1418 CreateDefaultParcel();
@@ -1669,6 +1677,168 @@ namespace OpenSim.Region.CoreModules.World.Land
1669 1677
1670 UpdateLandObject(localID, land.LandData); 1678 UpdateLandObject(localID, land.LandData);
1671 } 1679 }
1680
1681 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1682 {
1683 ILandObject land = null;
1684 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1685 foreach (ILandObject landObject in Land)
1686 {
1687 if (landObject.LandData.LocalID == landID)
1688 {
1689 land = landObject;
1690 }
1691 }
1692 land.DeedToGroup(DefaultGodParcelGroup);
1693 land.LandData.Name = DefaultGodParcelName;
1694 land.SendLandUpdateToAvatarsOverMe();
1695 }
1696
1697 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1698 {
1699 ScenePresence SP;
1700 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1701 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1702 if (SP.UserLevel != 0)
1703 {
1704 if (flags == 0) //All parcels, scripted or not
1705 {
1706 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1707 {
1708 if (e.OwnerID == targetID)
1709 {
1710 returns.Add(e);
1711 }
1712 }
1713 );
1714 }
1715 if (flags == 4) //All parcels, scripted object
1716 {
1717 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1718 {
1719 if (e.OwnerID == targetID)
1720 {
1721 if (e.ContainsScripts())
1722 {
1723 returns.Add(e);
1724 }
1725 }
1726 }
1727 );
1728 }
1729 if (flags == 4) //not target parcel, scripted object
1730 {
1731 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1732 {
1733 if (e.OwnerID == targetID)
1734 {
1735 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1736 if (landobject.LandData.OwnerID != e.OwnerID)
1737 {
1738 if (e.ContainsScripts())
1739 {
1740 returns.Add(e);
1741 }
1742 }
1743 }
1744 }
1745 );
1746 }
1747 foreach (SceneObjectGroup ol in returns)
1748 {
1749 ReturnObject(ol, client);
1750 }
1751 }
1752 }
1753 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1754 {
1755 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1756 objs[0] = obj;
1757 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1758 }
1759
1760 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1761
1762 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1763 {
1764 ScenePresence targetAvatar = null;
1765 ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar);
1766 ScenePresence parcelManager = null;
1767 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1768 System.Threading.Timer Timer;
1769
1770 if (targetAvatar.UserLevel == 0)
1771 {
1772 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1773 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze))
1774 return;
1775 if (flags == 0)
1776 {
1777 targetAvatar.AllowMovement = false;
1778 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
1779 parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen.");
1780 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
1781 Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0);
1782 Timers.Add(targetAvatar.UUID, Timer);
1783 }
1784 else
1785 {
1786 targetAvatar.AllowMovement = true;
1787 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you.");
1788 parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen.");
1789 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1790 Timers.Remove(targetAvatar.UUID);
1791 Timer.Dispose();
1792 }
1793 }
1794 }
1795 private void OnEndParcelFrozen(object avatar)
1796 {
1797 ScenePresence targetAvatar = (ScenePresence)avatar;
1798 targetAvatar.AllowMovement = true;
1799 System.Threading.Timer Timer;
1800 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1801 Timers.Remove(targetAvatar.UUID);
1802 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1803 }
1804
1805
1806 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1807 {
1808 ScenePresence targetAvatar = null;
1809 ScenePresence parcelManager = null;
1810
1811 // Must have presences
1812 if (!m_scene.TryGetScenePresence(target, out targetAvatar) ||
1813 !m_scene.TryGetScenePresence(client.AgentId, out parcelManager))
1814 return;
1815
1816 // Cannot eject estate managers or gods
1817 if (m_scene.Permissions.IsAdministrator(target))
1818 return;
1819
1820 // Check if you even have permission to do this
1821 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1822 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1823 !m_scene.Permissions.IsAdministrator(client.AgentId))
1824 return;
1825
1826 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1827
1828 targetAvatar.TeleportWithMomentum(pos, null);
1829 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1830 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1831
1832 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1833 {
1834 LandAccessEntry entry = new LandAccessEntry();
1835 entry.AgentID = targetAvatar.UUID;
1836 entry.Flags = AccessList.Ban;
1837 entry.Expires = 0; // Perm
1838
1839 land.LandData.ParcelAccessList.Add(entry);
1840 }
1841 }
1672 1842
1673 protected void InstallInterfaces() 1843 protected void InstallInterfaces()
1674 { 1844 {
@@ -1731,5 +1901,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1731 1901
1732 MainConsole.Instance.Output(report.ToString()); 1902 MainConsole.Instance.Output(report.ToString());
1733 } 1903 }
1904
1905 public void EnforceBans(ILandObject land, ScenePresence avatar)
1906 {
1907 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
1908 return;
1909
1910 if (land.IsEitherBannedOrRestricted(avatar.UUID))
1911 {
1912 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
1913 {
1914 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
1915 if (pos == null)
1916 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
1917 else
1918 ForceAvatarToPosition(avatar, (Vector3)pos);
1919 }
1920 else
1921 {
1922 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
1923 }
1924 }
1925 }
1734 } 1926 }
1735} 1927}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 8829f27..d5b2adb 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))
@@ -1182,6 +1203,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1182 1203
1183 #endregion 1204 #endregion
1184 1205
1206 private void OnFrame()
1207 {
1208 m_expiryCounter++;
1209
1210 if (m_expiryCounter >= 50)
1211 {
1212 ExpireAccessList();
1213 m_expiryCounter = 0;
1214 }
1215 }
1216
1185 private void ExpireAccessList() 1217 private void ExpireAccessList()
1186 { 1218 {
1187 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1219 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1192,7 +1224,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1192 delete.Add(entry); 1224 delete.Add(entry);
1193 } 1225 }
1194 foreach (LandAccessEntry entry in delete) 1226 foreach (LandAccessEntry entry in delete)
1227 {
1195 LandData.ParcelAccessList.Remove(entry); 1228 LandData.ParcelAccessList.Remove(entry);
1229 ScenePresence presence;
1230
1231 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1232 {
1233 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1234 if (land.LandData.LocalID == LandData.LocalID)
1235 {
1236 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1237 presence.TeleportWithMomentum(pos, null);
1238 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1239 }
1240 }
1241 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1242 }
1196 1243
1197 if (delete.Count > 0) 1244 if (delete.Count > 0)
1198 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1245 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 665875f..cbb3abe 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.World.Land
205 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) 205 if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts))
206 { 206 {
207 UUID landOwner = landData.OwnerID; 207 UUID landOwner = landData.OwnerID;
208 int partCount = obj.Parts.Length; 208 int partCount = obj.GetPartCount();
209 209
210 m_SimwideCounts[landOwner] += partCount; 210 m_SimwideCounts[landOwner] += partCount;
211 if (parcelCounts.Users.ContainsKey(obj.OwnerID)) 211 if (parcelCounts.Users.ContainsKey(obj.OwnerID))
@@ -592,4 +592,4 @@ namespace OpenSim.Region.CoreModules.World.Land
592 } 592 }
593 } 593 }
594 } 594 }
595} \ No newline at end of file 595}
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/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 7a8a57c..f3d38bc 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -368,7 +368,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
368 368
369 public string Name 369 public string Name
370 { 370 {
371 get { return "PermissionsModule"; } 371 get { return "DefaultPermissionsModule"; }
372 } 372 }
373 373
374 public bool IsSharedModule 374 public bool IsSharedModule
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index fea4de0..287738a 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -28,6 +28,8 @@
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Timers; 30using System.Timers;
31using System.IO;
32using System.Diagnostics;
31using System.Threading; 33using System.Threading;
32using System.Collections.Generic; 34using System.Collections.Generic;
33using log4net; 35using log4net;
@@ -56,13 +58,24 @@ namespace OpenSim.Region.CoreModules.World.Region
56 protected UUID m_Initiator; 58 protected UUID m_Initiator;
57 protected bool m_Notice = false; 59 protected bool m_Notice = false;
58 protected IDialogModule m_DialogModule = null; 60 protected IDialogModule m_DialogModule = null;
61 protected string m_MarkerPath = String.Empty;
62 private int[] m_CurrentAlerts = null;
59 63
60 public void Initialise(IConfigSource config) 64 public void Initialise(IConfigSource config)
61 { 65 {
66 IConfig restartConfig = config.Configs["RestartModule"];
67 if (restartConfig != null)
68 {
69 m_MarkerPath = restartConfig.GetString("MarkerPath", String.Empty);
70 }
62 } 71 }
63 72
64 public void AddRegion(Scene scene) 73 public void AddRegion(Scene scene)
65 { 74 {
75 if (m_MarkerPath != String.Empty)
76 File.Delete(Path.Combine(m_MarkerPath,
77 scene.RegionInfo.RegionID.ToString()));
78
66 m_Scene = scene; 79 m_Scene = scene;
67 80
68 scene.RegisterModuleInterface<IRestartModule>(this); 81 scene.RegisterModuleInterface<IRestartModule>(this);
@@ -121,6 +134,7 @@ namespace OpenSim.Region.CoreModules.World.Region
121 134
122 if (alerts == null) 135 if (alerts == null)
123 { 136 {
137 CreateMarkerFile();
124 m_Scene.RestartNow(); 138 m_Scene.RestartNow();
125 return; 139 return;
126 } 140 }
@@ -128,25 +142,28 @@ namespace OpenSim.Region.CoreModules.World.Region
128 m_Message = message; 142 m_Message = message;
129 m_Initiator = initiator; 143 m_Initiator = initiator;
130 m_Notice = notice; 144 m_Notice = notice;
145 m_CurrentAlerts = alerts;
131 m_Alerts = new List<int>(alerts); 146 m_Alerts = new List<int>(alerts);
132 m_Alerts.Sort(); 147 m_Alerts.Sort();
133 m_Alerts.Reverse(); 148 m_Alerts.Reverse();
134 149
135 if (m_Alerts[0] == 0) 150 if (m_Alerts[0] == 0)
136 { 151 {
152 CreateMarkerFile();
137 m_Scene.RestartNow(); 153 m_Scene.RestartNow();
138 return; 154 return;
139 } 155 }
140 156
141 int nextInterval = DoOneNotice(); 157 int nextInterval = DoOneNotice(true);
142 158
143 SetTimer(nextInterval); 159 SetTimer(nextInterval);
144 } 160 }
145 161
146 public int DoOneNotice() 162 public int DoOneNotice(bool sendOut)
147 { 163 {
148 if (m_Alerts.Count == 0 || m_Alerts[0] == 0) 164 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
149 { 165 {
166 CreateMarkerFile();
150 m_Scene.RestartNow(); 167 m_Scene.RestartNow();
151 return 0; 168 return 0;
152 } 169 }
@@ -167,34 +184,37 @@ namespace OpenSim.Region.CoreModules.World.Region
167 184
168 m_Alerts.RemoveAt(0); 185 m_Alerts.RemoveAt(0);
169 186
170 int minutes = currentAlert / 60; 187 if (sendOut)
171 string currentAlertString = String.Empty;
172 if (minutes > 0)
173 { 188 {
174 if (minutes == 1) 189 int minutes = currentAlert / 60;
175 currentAlertString += "1 minute"; 190 string currentAlertString = String.Empty;
176 else 191 if (minutes > 0)
177 currentAlertString += String.Format("{0} minutes", minutes); 192 {
193 if (minutes == 1)
194 currentAlertString += "1 minute";
195 else
196 currentAlertString += String.Format("{0} minutes", minutes);
197 if ((currentAlert % 60) != 0)
198 currentAlertString += " and ";
199 }
178 if ((currentAlert % 60) != 0) 200 if ((currentAlert % 60) != 0)
179 currentAlertString += " and "; 201 {
180 } 202 int seconds = currentAlert % 60;
181 if ((currentAlert % 60) != 0) 203 if (seconds == 1)
182 { 204 currentAlertString += "1 second";
183 int seconds = currentAlert % 60; 205 else
184 if (seconds == 1) 206 currentAlertString += String.Format("{0} seconds", seconds);
185 currentAlertString += "1 second"; 207 }
186 else
187 currentAlertString += String.Format("{0} seconds", seconds);
188 }
189 208
190 string msg = String.Format(m_Message, currentAlertString); 209 string msg = String.Format(m_Message, currentAlertString);
191 210
192 if (m_DialogModule != null && msg != String.Empty) 211 if (m_DialogModule != null && msg != String.Empty)
193 { 212 {
194 if (m_Notice) 213 if (m_Notice)
195 m_DialogModule.SendGeneralAlert(msg); 214 m_DialogModule.SendGeneralAlert(msg);
196 else 215 else
197 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg); 216 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
217 }
198 } 218 }
199 219
200 return currentAlert - nextAlert; 220 return currentAlert - nextAlert;
@@ -211,7 +231,25 @@ namespace OpenSim.Region.CoreModules.World.Region
211 231
212 private void OnTimer(object source, ElapsedEventArgs e) 232 private void OnTimer(object source, ElapsedEventArgs e)
213 { 233 {
214 int nextInterval = DoOneNotice(); 234 int nextInterval = DoOneNotice(true);
235
236 SetTimer(nextInterval);
237 }
238
239 public void DelayRestart(int seconds, string message)
240 {
241 if (m_CountdownTimer == null)
242 return;
243
244 m_CountdownTimer.Stop();
245 m_CountdownTimer = null;
246
247 m_Alerts = new List<int>(m_CurrentAlerts);
248 m_Alerts.Add(seconds);
249 m_Alerts.Sort();
250 m_Alerts.Reverse();
251
252 int nextInterval = DoOneNotice(false);
215 253
216 SetTimer(nextInterval); 254 SetTimer(nextInterval);
217 } 255 }
@@ -225,6 +263,9 @@ namespace OpenSim.Region.CoreModules.World.Region
225 if (m_DialogModule != null && message != String.Empty) 263 if (m_DialogModule != null && message != String.Empty)
226 m_DialogModule.SendGeneralAlert(message); 264 m_DialogModule.SendGeneralAlert(message);
227 } 265 }
266 if (m_MarkerPath != String.Empty)
267 File.Delete(Path.Combine(m_MarkerPath,
268 m_Scene.RegionInfo.RegionID.ToString()));
228 } 269 }
229 270
230 private void HandleRegionRestart(string module, string[] args) 271 private void HandleRegionRestart(string module, string[] args)
@@ -266,5 +307,25 @@ namespace OpenSim.Region.CoreModules.World.Region
266 307
267 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 308 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
268 } 309 }
310
311 protected void CreateMarkerFile()
312 {
313 if (m_MarkerPath == String.Empty)
314 return;
315
316 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
317 try
318 {
319 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
320 FileStream fs = File.Create(path);
321 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
322 Byte[] buf = enc.GetBytes(pidstring);
323 fs.Write(buf, 0, buf.Length);
324 fs.Close();
325 }
326 catch (Exception)
327 {
328 }
329 }
269 } 330 }
270} 331}
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 4694b14..d99567c 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -642,6 +642,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
642 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); 642 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
643 m_scene.SaveTerrain(); 643 m_scene.SaveTerrain();
644 644
645 m_scene.EventManager.TriggerTerrainUpdate();
646
645 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. 647 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out.
646 //m_scene.CreateTerrainTexture(true); 648 //m_scene.CreateTerrainTexture(true);
647 } 649 }
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 2d762fb..33f6c3f 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -63,6 +63,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
63 private bool m_useAntiAliasing = false; // TODO: Make this a config option 63 private bool m_useAntiAliasing = false; // TODO: Make this a config option
64 private bool m_Enabled = false; 64 private bool m_Enabled = false;
65 65
66 private Bitmap lastImage = null;
67 private DateTime lastImageTime = DateTime.MinValue;
68
66 #region IRegionModule Members 69 #region IRegionModule Members
67 70
68 public void Initialise(IConfigSource source) 71 public void Initialise(IConfigSource source)
@@ -85,14 +88,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
85 88
86 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 89 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
87 if (renderers.Count > 0) 90 if (renderers.Count > 0)
88 { 91 m_log.Info("[MAPTILE]: Loaded prim mesher " + renderers[0]);
89 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
90 m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher);
91 }
92 else 92 else
93 { 93 m_log.Info("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
94 m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled");
95 }
96 94
97 m_scene.RegisterModuleInterface<IMapImageGenerator>(this); 95 m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
98 } 96 }
@@ -125,9 +123,25 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
125 123
126 public Bitmap CreateMapTile() 124 public Bitmap CreateMapTile()
127 { 125 {
126 if ((DateTime.Now - lastImageTime).TotalSeconds < 3600)
127 {
128 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
129 }
130
131 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory());
132 if (renderers.Count > 0)
133 {
134 m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
135 }
136
128 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f); 137 Vector3 camPos = new Vector3(127.5f, 127.5f, 221.7025033688163f);
129 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize); 138 Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, (int)Constants.RegionSize, (int)Constants.RegionSize, (float)Constants.RegionSize, (float)Constants.RegionSize);
130 return CreateMapTile(viewport, false); 139 Bitmap tile = CreateMapTile(viewport, false);
140 m_primMesher = null;
141
142 lastImage = tile;
143 lastImageTime = DateTime.Now;
144 return lastImage.Clone(new Rectangle(0, 0, 256, 256), lastImage.PixelFormat);
131 } 145 }
132 146
133 public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) 147 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 f37dd94..2417b1a 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -86,90 +86,93 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
86 86
87 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 87 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
88 { 88 {
89 if (mapName.Length < 3) 89 Util.FireAndForget(x =>
90 { 90 {
91 remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); 91 if (mapName.Length < 2)
92 return; 92 {
93 } 93 remoteClient.SendAlertMessage("Use a search string with at least 2 characters");
94 return;
95 }
94 96
95 //m_log.DebugFormat("MAP NAME=({0})", mapName); 97 //m_log.DebugFormat("MAP NAME=({0})", mapName);
96 98
97 // Hack to get around the fact that ll V3 now drops the port from the 99 // Hack to get around the fact that ll V3 now drops the port from the
98 // map name. See https://jira.secondlife.com/browse/VWR-28570 100 // map name. See https://jira.secondlife.com/browse/VWR-28570
99 // 101 //
100 // Caller, use this magic form instead: 102 // Caller, use this magic form instead:
101 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 103 // secondlife://http|!!mygrid.com|8002|Region+Name/128/128
102 // or url encode if possible. 104 // or url encode if possible.
103 // the hacks we do with this viewer... 105 // the hacks we do with this viewer...
104 // 106 //
105 string mapNameOrig = mapName; 107 string mapNameOrig = mapName;
106 if (mapName.Contains("|")) 108 if (mapName.Contains("|"))
107 mapName = mapName.Replace('|', ':'); 109 mapName = mapName.Replace('|', ':');
108 if (mapName.Contains("+")) 110 if (mapName.Contains("+"))
109 mapName = mapName.Replace('+', ' '); 111 mapName = mapName.Replace('+', ' ');
110 if (mapName.Contains("!")) 112 if (mapName.Contains("!"))
111 mapName = mapName.Replace('!', '/'); 113 mapName = mapName.Replace('!', '/');
112 114
113 // try to fetch from GridServer 115 // try to fetch from GridServer
114 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 116 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
115 if (regionInfos.Count == 0) 117 // if (regionInfos.Count == 0)
116 remoteClient.SendAlertMessage("Hyperlink could not be established."); 118 // remoteClient.SendAlertMessage("Hyperlink could not be established.");
117 119
118 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); 120 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
119 List<MapBlockData> blocks = new List<MapBlockData>(); 121 List<MapBlockData> blocks = new List<MapBlockData>();
120 122
121 MapBlockData data; 123 MapBlockData data;
122 if (regionInfos.Count > 0) 124 if (regionInfos.Count > 0)
123 {
124 foreach (GridRegion info in regionInfos)
125 { 125 {
126 data = new MapBlockData(); 126 foreach (GridRegion info in regionInfos)
127 data.Agents = 0; 127 {
128 data.Access = info.Access; 128 data = new MapBlockData();
129 if (flags == 2) // V2 sends this 129 data.Agents = 0;
130 data.MapImageId = UUID.Zero; 130 data.Access = info.Access;
131 else 131 if (flags == 2) // V2 sends this
132 data.MapImageId = info.TerrainImage; 132 data.MapImageId = UUID.Zero;
133 // ugh! V2-3 is very sensitive about the result being 133 else
134 // exactly the same as the requested name 134 data.MapImageId = info.TerrainImage;
135 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) 135 // ugh! V2-3 is very sensitive about the result being
136 data.Name = mapNameOrig; 136 // exactly the same as the requested name
137 else 137 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
138 data.Name = info.RegionName; 138 data.Name = mapNameOrig;
139 data.RegionFlags = 0; // TODO not used? 139 else
140 data.WaterHeight = 0; // not used 140 data.Name = info.RegionName;
141 data.X = (ushort)(info.RegionLocX / Constants.RegionSize); 141 data.RegionFlags = 0; // TODO not used?
142 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); 142 data.WaterHeight = 0; // not used
143 blocks.Add(data); 143 data.X = (ushort)(info.RegionLocX / Constants.RegionSize);
144 data.Y = (ushort)(info.RegionLocY / Constants.RegionSize);
145 blocks.Add(data);
146 }
144 } 147 }
145 }
146 148
147 // final block, closing the search result 149 // final block, closing the search result
148 data = new MapBlockData(); 150 data = new MapBlockData();
149 data.Agents = 0; 151 data.Agents = 0;
150 data.Access = 255; 152 data.Access = 255;
151 data.MapImageId = UUID.Zero; 153 data.MapImageId = UUID.Zero;
152 data.Name = ""; // mapName; 154 data.Name = mapName;
153 data.RegionFlags = 0; 155 data.RegionFlags = 0;
154 data.WaterHeight = 0; // not used 156 data.WaterHeight = 0; // not used
155 data.X = 0; 157 data.X = 0;
156 data.Y = 0; 158 data.Y = 0;
157 blocks.Add(data); 159 blocks.Add(data);
158 160
159 // flags are agent flags sent from the viewer. 161 // flags are agent flags sent from the viewer.
160 // they have different values depending on different viewers, apparently 162 // they have different values depending on different viewers, apparently
161 remoteClient.SendMapBlock(blocks, flags); 163 remoteClient.SendMapBlock(blocks, flags);
162 164
163 // send extra user messages for V3 165 // send extra user messages for V3
164 // because the UI is very confusing 166 // because the UI is very confusing
165 // while we don't fix the hard-coded urls 167 // while we don't fix the hard-coded urls
166 if (flags == 2) 168 if (flags == 2)
167 { 169 {
168 if (regionInfos.Count == 0) 170 if (regionInfos.Count == 0)
169 remoteClient.SendAgentAlertMessage("No regions found with that name.", true); 171 remoteClient.SendAgentAlertMessage("No regions found with that name.", true);
170 else if (regionInfos.Count == 1) 172 else if (regionInfos.Count == 1)
171 remoteClient.SendAgentAlertMessage("Region found!", false); 173 remoteClient.SendAgentAlertMessage("Region found!", false);
172 } 174 }
175 });
173 } 176 }
174 177
175// private Scene GetClientScene(IClientAPI client) 178// private Scene GetClientScene(IClientAPI client)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index dfba3ff..26b406e 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -64,7 +64,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
64 private static readonly UUID STOP_UUID = UUID.Random(); 64 private static readonly UUID STOP_UUID = UUID.Random();
65 private static readonly string m_mapLayerPath = "0001/"; 65 private static readonly string m_mapLayerPath = "0001/";
66 66
67 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 67 private ManualResetEvent queueEvent = new ManualResetEvent(false);
68 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
69
70 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
71 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
68 72
69 protected Scene m_scene; 73 protected Scene m_scene;
70 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 74 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
@@ -72,7 +76,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
72 private int blacklistTimeout = 10*60*1000; // 10 minutes 76 private int blacklistTimeout = 10*60*1000; // 10 minutes
73 private byte[] myMapImageJPEG; 77 private byte[] myMapImageJPEG;
74 protected volatile bool m_Enabled = false; 78 protected volatile bool m_Enabled = false;
75 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
76 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 79 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
77 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 80 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
78 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 81 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
@@ -229,54 +232,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
229 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 232 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
230 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 233 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
231 234
232 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 235 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
233 { 236 //{
234 ScenePresence avatarPresence = null; 237 // ScenePresence avatarPresence = null;
235 238
236 m_scene.TryGetScenePresence(agentID, out avatarPresence); 239 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
237 240
238 if (avatarPresence != null) 241 // if (avatarPresence != null)
239 { 242 // {
240 bool lookup = false; 243 // bool lookup = false;
241 244
242 lock (cachedMapBlocks) 245 // lock (cachedMapBlocks)
243 { 246 // {
244 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 247 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
245 { 248 // {
246 List<MapBlockData> mapBlocks; 249 // List<MapBlockData> mapBlocks;
247 250
248 mapBlocks = cachedMapBlocks; 251 // mapBlocks = cachedMapBlocks;
249 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 252 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
250 } 253 // }
251 else 254 // else
252 { 255 // {
253 lookup = true; 256 // lookup = true;
254 } 257 // }
255 } 258 // }
256 if (lookup) 259 // if (lookup)
257 { 260 // {
258 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 261 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
259 262
260 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 263 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
261 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 264 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
262 (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize, 265 // (int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
263 (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize, 266 // (int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
264 (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize); 267 // (int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
265 foreach (GridRegion r in regions) 268 // foreach (GridRegion r in regions)
266 { 269 // {
267 MapBlockData block = new MapBlockData(); 270 // MapBlockData block = new MapBlockData();
268 MapBlockFromGridRegion(block, r, 0); 271 // MapBlockFromGridRegion(block, r, 0);
269 mapBlocks.Add(block); 272 // mapBlocks.Add(block);
270 } 273 // }
271 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 274 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
272 275
273 lock (cachedMapBlocks) 276 // lock (cachedMapBlocks)
274 cachedMapBlocks = mapBlocks; 277 // cachedMapBlocks = mapBlocks;
275 278
276 cachedTime = Util.UnixTimeSinceEpoch(); 279 // cachedTime = Util.UnixTimeSinceEpoch();
277 } 280 // }
278 } 281 // }
279 } 282 //}
280 283
281 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 284 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
282 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 285 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -303,8 +306,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
303 protected static OSDMapLayer GetOSDMapLayerResponse() 306 protected static OSDMapLayer GetOSDMapLayerResponse()
304 { 307 {
305 OSDMapLayer mapLayer = new OSDMapLayer(); 308 OSDMapLayer mapLayer = new OSDMapLayer();
306 mapLayer.Right = 5000; 309 mapLayer.Right = 2048;
307 mapLayer.Top = 5000; 310 mapLayer.Top = 2048;
308 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 311 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
309 312
310 return mapLayer; 313 return mapLayer;
@@ -333,6 +336,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
333 { 336 {
334 m_rootAgents.Remove(AgentId); 337 m_rootAgents.Remove(AgentId);
335 } 338 }
339 lock (m_mapBlockRequestEvent)
340 {
341 if (m_mapBlockRequests.ContainsKey(AgentId))
342 m_mapBlockRequests.Remove(AgentId);
343 }
336 } 344 }
337 #endregion 345 #endregion
338 346
@@ -355,6 +363,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
355 ThreadPriority.BelowNormal, 363 ThreadPriority.BelowNormal,
356 true, 364 true,
357 true); 365 true);
366 Watchdog.StartThread(
367 MapBlockSendThread,
368 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
369 ThreadPriority.BelowNormal,
370 true,
371 true);
358 } 372 }
359 373
360 /// <summary> 374 /// <summary>
@@ -370,7 +384,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
370 st.itemtype=0; 384 st.itemtype=0;
371 st.regionhandle=0; 385 st.regionhandle=0;
372 386
373 requests.Enqueue(st); 387 lock (requests)
388 {
389 queueEvent.Set();
390 requests.Enqueue(st);
391 }
392
393 MapBlockRequestData req = new MapBlockRequestData();
394
395 req.client = null;
396 req.minX = 0;
397 req.maxX = 0;
398 req.minY = 0;
399 req.maxY = 0;
400 req.flags = 0;
401
402 lock (m_mapBlockRequestEvent)
403 {
404 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
405 m_mapBlockRequests[UUID.Zero].Enqueue(req);
406 m_mapBlockRequestEvent.Set();
407 }
374 } 408 }
375 409
376 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 410 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -526,7 +560,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
526 { 560 {
527 while (true) 561 while (true)
528 { 562 {
529 MapRequestState st = requests.Dequeue(1000); 563 MapRequestState st = new MapRequestState();
564 bool valid = false;
565 queueEvent.WaitOne();
566 lock (requests)
567 {
568 if (requests.Count > 0)
569 {
570 st = requests.Dequeue();
571 valid = true;
572 }
573 if (requests.Count == 0)
574 queueEvent.Reset();
575 }
576 if (!valid)
577 continue;
530 578
531 // end gracefully 579 // end gracefully
532 if (st.agentID == STOP_UUID) 580 if (st.agentID == STOP_UUID)
@@ -544,13 +592,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
544 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 592 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
545 { 593 {
546 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 594 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
547 Thread.Sleep(80); 595 Thread.Sleep(100);
548 596
549 RequestMapItemsDelegate d = RequestMapItemsAsync;
550 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
551 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
552 //RequestMapItemsCompleted(response);
553 Interlocked.Increment(ref nAsyncRequests); 597 Interlocked.Increment(ref nAsyncRequests);
598 Util.FireAndForget(x =>
599 {
600 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
601 });
554 } 602 }
555 } 603 }
556 604
@@ -572,110 +620,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
572 /// <param name="state"></param> 620 /// <param name="state"></param>
573 public void EnqueueMapItemRequest(MapRequestState state) 621 public void EnqueueMapItemRequest(MapRequestState state)
574 { 622 {
575 requests.Enqueue(state); 623 lock (requests)
576 }
577
578 /// <summary>
579 /// Sends the mapitem response to the IClientAPI
580 /// </summary>
581 /// <param name="response">The OSDMap Response for the mapitem</param>
582 private void RequestMapItemsCompleted(IAsyncResult iar)
583 {
584 AsyncResult result = (AsyncResult)iar;
585 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
586
587 OSDMap response = (OSDMap)icon.EndInvoke(iar);
588
589 Interlocked.Decrement(ref nAsyncRequests);
590
591 if (!response.ContainsKey("requestID"))
592 return;
593
594 UUID requestID = response["requestID"].AsUUID();
595
596 if (requestID != UUID.Zero)
597 { 624 {
598 MapRequestState mrs = new MapRequestState(); 625 queueEvent.Set();
599 mrs.agentID = UUID.Zero; 626 requests.Enqueue(state);
600 lock (m_openRequests)
601 {
602 if (m_openRequests.ContainsKey(requestID))
603 {
604 mrs = m_openRequests[requestID];
605 m_openRequests.Remove(requestID);
606 }
607 }
608
609 if (mrs.agentID != UUID.Zero)
610 {
611 ScenePresence av = null;
612 m_scene.TryGetScenePresence(mrs.agentID, out av);
613 if (av != null)
614 {
615 if (response.ContainsKey(mrs.itemtype.ToString()))
616 {
617 List<mapItemReply> returnitems = new List<mapItemReply>();
618 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
619 for (int i = 0; i < itemarray.Count; i++)
620 {
621 OSDMap mapitem = (OSDMap)itemarray[i];
622 mapItemReply mi = new mapItemReply();
623 mi.x = (uint)mapitem["X"].AsInteger();
624 mi.y = (uint)mapitem["Y"].AsInteger();
625 mi.id = mapitem["ID"].AsUUID();
626 mi.Extra = mapitem["Extra"].AsInteger();
627 mi.Extra2 = mapitem["Extra2"].AsInteger();
628 mi.name = mapitem["Name"].AsString();
629 returnitems.Add(mi);
630 }
631 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
632 }
633
634 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
635 uint itemtype = 7;
636
637 if (response.ContainsKey(itemtype.ToString()))
638 {
639 List<mapItemReply> returnitems = new List<mapItemReply>();
640 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
641 for (int i = 0; i < itemarray.Count; i++)
642 {
643 OSDMap mapitem = (OSDMap)itemarray[i];
644 mapItemReply mi = new mapItemReply();
645 mi.x = (uint)mapitem["X"].AsInteger();
646 mi.y = (uint)mapitem["Y"].AsInteger();
647 mi.id = mapitem["ID"].AsUUID();
648 mi.Extra = mapitem["Extra"].AsInteger();
649 mi.Extra2 = mapitem["Extra2"].AsInteger();
650 mi.name = mapitem["Name"].AsString();
651 returnitems.Add(mi);
652 }
653 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
654 }
655
656 // Service 1 (MAP_ITEM_TELEHUB)
657 itemtype = 1;
658
659 if (response.ContainsKey(itemtype.ToString()))
660 {
661 List<mapItemReply> returnitems = new List<mapItemReply>();
662 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
663 for (int i = 0; i < itemarray.Count; i++)
664 {
665 OSDMap mapitem = (OSDMap)itemarray[i];
666 mapItemReply mi = new mapItemReply();
667 mi.x = (uint)mapitem["X"].AsInteger();
668 mi.y = (uint)mapitem["Y"].AsInteger();
669 mi.id = mapitem["ID"].AsUUID();
670 mi.Extra = mapitem["Extra"].AsInteger();
671 mi.Extra2 = mapitem["Extra2"].AsInteger();
672 mi.name = mapitem["Name"].AsString();
673 returnitems.Add(mi);
674 }
675 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
676 }
677 }
678 }
679 } 627 }
680 } 628 }
681 629
@@ -702,8 +650,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
702 EnqueueMapItemRequest(st); 650 EnqueueMapItemRequest(st);
703 } 651 }
704 652
705 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
706 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
707 /// <summary> 653 /// <summary>
708 /// Does the actual remote mapitem request 654 /// Does the actual remote mapitem request
709 /// This should be called from an asynchronous thread 655 /// This should be called from an asynchronous thread
@@ -718,7 +664,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
718 /// <param name="itemtype">passed in from packet</param> 664 /// <param name="itemtype">passed in from packet</param>
719 /// <param name="regionhandle">Region we're looking up</param> 665 /// <param name="regionhandle">Region we're looking up</param>
720 /// <returns></returns> 666 /// <returns></returns>
721 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 667 private void RequestMapItemsAsync(UUID id, uint flags,
722 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 668 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
723 { 669 {
724// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 670// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -741,7 +687,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
741 } 687 }
742 688
743 if (blacklisted) 689 if (blacklisted)
744 return new OSDMap(); 690 {
691 Interlocked.Decrement(ref nAsyncRequests);
692 return;
693 }
745 694
746 UUID requestID = UUID.Random(); 695 UUID requestID = UUID.Random();
747 lock (m_cachedRegionMapItemsAddress) 696 lock (m_cachedRegionMapItemsAddress)
@@ -749,6 +698,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
749 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 698 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
750 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 699 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
751 } 700 }
701
752 if (httpserver.Length == 0) 702 if (httpserver.Length == 0)
753 { 703 {
754 uint x = 0, y = 0; 704 uint x = 0, y = 0;
@@ -793,18 +743,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
793 743
794 // Can't find the http server 744 // Can't find the http server
795 if (httpserver.Length == 0 || blacklisted) 745 if (httpserver.Length == 0 || blacklisted)
796 return new OSDMap(); 746 {
797 747 Interlocked.Decrement(ref nAsyncRequests);
798 MapRequestState mrs = new MapRequestState(); 748 return;
799 mrs.agentID = id; 749 }
800 mrs.EstateID = EstateID;
801 mrs.flags = flags;
802 mrs.godlike = godlike;
803 mrs.itemtype=itemtype;
804 mrs.regionhandle = regionhandle;
805
806 lock (m_openRequests)
807 m_openRequests.Add(requestID, mrs);
808 750
809 WebRequest mapitemsrequest = null; 751 WebRequest mapitemsrequest = null;
810 try 752 try
@@ -814,7 +756,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
814 catch (Exception e) 756 catch (Exception e)
815 { 757 {
816 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 758 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
817 return new OSDMap(); 759 Interlocked.Decrement(ref nAsyncRequests);
760 return;
818 } 761 }
819 762
820 mapitemsrequest.Method = "POST"; 763 mapitemsrequest.Method = "POST";
@@ -839,7 +782,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
839 catch (WebException ex) 782 catch (WebException ex)
840 { 783 {
841 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 784 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
842 responseMap["connect"] = OSD.FromBoolean(false);
843 lock (m_blacklistedurls) 785 lock (m_blacklistedurls)
844 { 786 {
845 if (!m_blacklistedurls.ContainsKey(httpserver)) 787 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -848,13 +790,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
848 790
849 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 791 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
850 792
851 return responseMap; 793 Interlocked.Decrement(ref nAsyncRequests);
794 return;
852 } 795 }
853 catch 796 catch
854 { 797 {
855 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 798 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
856 responseMap["connect"] = OSD.FromBoolean(false); 799 Interlocked.Decrement(ref nAsyncRequests);
857 return responseMap; 800 return;
858 } 801 }
859 finally 802 finally
860 { 803 {
@@ -875,12 +818,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
875 } 818 }
876 else 819 else
877 { 820 {
878 return new OSDMap(); 821 Interlocked.Decrement(ref nAsyncRequests);
822 return;
879 } 823 }
880 } 824 }
881 catch (WebException) 825 catch (WebException)
882 { 826 {
883 responseMap["connect"] = OSD.FromBoolean(false);
884 lock (m_blacklistedurls) 827 lock (m_blacklistedurls)
885 { 828 {
886 if (!m_blacklistedurls.ContainsKey(httpserver)) 829 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -889,19 +832,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
889 832
890 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 833 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
891 834
892 return responseMap; 835 Interlocked.Decrement(ref nAsyncRequests);
836 return;
893 } 837 }
894 catch 838 catch
895 { 839 {
896 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 840 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
897 responseMap["connect"] = OSD.FromBoolean(false);
898 lock (m_blacklistedregions) 841 lock (m_blacklistedregions)
899 { 842 {
900 if (!m_blacklistedregions.ContainsKey(regionhandle)) 843 if (!m_blacklistedregions.ContainsKey(regionhandle))
901 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 844 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
902 } 845 }
903 846
904 return responseMap; 847 Interlocked.Decrement(ref nAsyncRequests);
848 return;
905 } 849 }
906 finally 850 finally
907 { 851 {
@@ -920,14 +864,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
920 catch (Exception ex) 864 catch (Exception ex)
921 { 865 {
922 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 866 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
923 responseMap["connect"] = OSD.FromBoolean(false);
924 lock (m_blacklistedregions) 867 lock (m_blacklistedregions)
925 { 868 {
926 if (!m_blacklistedregions.ContainsKey(regionhandle)) 869 if (!m_blacklistedregions.ContainsKey(regionhandle))
927 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 870 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
928 } 871 }
929 872
930 return responseMap; 873 Interlocked.Decrement(ref nAsyncRequests);
874 return;
931 } 875 }
932 } 876 }
933 877
@@ -941,7 +885,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
941 } 885 }
942 } 886 }
943 887
944 return responseMap; 888 Interlocked.Decrement(ref nAsyncRequests);
889
890 if (id != UUID.Zero)
891 {
892 ScenePresence av = null;
893 m_scene.TryGetScenePresence(id, out av);
894 if (av != null)
895 {
896 if (responseMap.ContainsKey(itemtype.ToString()))
897 {
898 List<mapItemReply> returnitems = new List<mapItemReply>();
899 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
900 for (int i = 0; i < itemarray.Count; i++)
901 {
902 OSDMap mapitem = (OSDMap)itemarray[i];
903 mapItemReply mi = new mapItemReply();
904 mi.x = (uint)mapitem["X"].AsInteger();
905 mi.y = (uint)mapitem["Y"].AsInteger();
906 mi.id = mapitem["ID"].AsUUID();
907 mi.Extra = mapitem["Extra"].AsInteger();
908 mi.Extra2 = mapitem["Extra2"].AsInteger();
909 mi.name = mapitem["Name"].AsString();
910 returnitems.Add(mi);
911 }
912 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
913 }
914
915 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
916 itemtype = 7;
917
918 if (responseMap.ContainsKey(itemtype.ToString()))
919 {
920 List<mapItemReply> returnitems = new List<mapItemReply>();
921 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
922 for (int i = 0; i < itemarray.Count; i++)
923 {
924 OSDMap mapitem = (OSDMap)itemarray[i];
925 mapItemReply mi = new mapItemReply();
926 mi.x = (uint)mapitem["X"].AsInteger();
927 mi.y = (uint)mapitem["Y"].AsInteger();
928 mi.id = mapitem["ID"].AsUUID();
929 mi.Extra = mapitem["Extra"].AsInteger();
930 mi.Extra2 = mapitem["Extra2"].AsInteger();
931 mi.name = mapitem["Name"].AsString();
932 returnitems.Add(mi);
933 }
934 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
935 }
936
937 // Service 1 (MAP_ITEM_TELEHUB)
938 itemtype = 1;
939
940 if (responseMap.ContainsKey(itemtype.ToString()))
941 {
942 List<mapItemReply> returnitems = new List<mapItemReply>();
943 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
944 for (int i = 0; i < itemarray.Count; i++)
945 {
946 OSDMap mapitem = (OSDMap)itemarray[i];
947 mapItemReply mi = new mapItemReply();
948 mi.x = (uint)mapitem["X"].AsInteger();
949 mi.y = (uint)mapitem["Y"].AsInteger();
950 mi.id = mapitem["ID"].AsUUID();
951 mi.Extra = mapitem["Extra"].AsInteger();
952 mi.Extra2 = mapitem["Extra2"].AsInteger();
953 mi.name = mapitem["Name"].AsString();
954 returnitems.Add(mi);
955 }
956 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
957 }
958 }
959 }
945 } 960 }
946 961
947 /// <summary> 962 /// <summary>
@@ -951,7 +966,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
951 /// <param name="minY"></param> 966 /// <param name="minY"></param>
952 /// <param name="maxX"></param> 967 /// <param name="maxX"></param>
953 /// <param name="maxY"></param> 968 /// <param name="maxY"></param>
954 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 969 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
955 { 970 {
956 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 971 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
957 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 972 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1004,21 +1019,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1004 1019
1005 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1020 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1006 { 1021 {
1022 MapBlockRequestData req = new MapBlockRequestData();
1023
1024 req.client = remoteClient;
1025 req.minX = minX;
1026 req.maxX = maxX;
1027 req.minY = minY;
1028 req.maxY = maxY;
1029 req.flags = flag;
1030
1031 lock (m_mapBlockRequestEvent)
1032 {
1033 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1034 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1035 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1036 m_mapBlockRequestEvent.Set();
1037 }
1038
1039 return new List<MapBlockData>();
1040 }
1041
1042 protected void MapBlockSendThread()
1043 {
1044 while (true)
1045 {
1046 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1047
1048 m_mapBlockRequestEvent.WaitOne();
1049 lock (m_mapBlockRequestEvent)
1050 {
1051 int total = 0;
1052 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1053 {
1054 if (q.Count > 0)
1055 thisRunData.Add(q.Dequeue());
1056
1057 total += q.Count;
1058 }
1059
1060 if (total == 0)
1061 m_mapBlockRequestEvent.Reset();
1062 }
1063
1064 foreach (MapBlockRequestData req in thisRunData)
1065 {
1066 // Null client stops thread
1067 if (req.client == null)
1068 return;
1069
1070 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1071 }
1072
1073 Thread.Sleep(50);
1074 }
1075 }
1076
1077 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1078 {
1079 List<MapBlockData> allBlocks = new List<MapBlockData>();
1007 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1080 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1008 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1081 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1009 (minX - 4) * (int)Constants.RegionSize, 1082 minX * (int)Constants.RegionSize,
1010 (maxX + 4) * (int)Constants.RegionSize, 1083 maxX * (int)Constants.RegionSize,
1011 (minY - 4) * (int)Constants.RegionSize, 1084 minY * (int)Constants.RegionSize,
1012 (maxY + 4) * (int)Constants.RegionSize); 1085 maxY * (int)Constants.RegionSize);
1086// (minX - 4) * (int)Constants.RegionSize,
1087// (maxX + 4) * (int)Constants.RegionSize,
1088// (minY - 4) * (int)Constants.RegionSize,
1089// (maxY + 4) * (int)Constants.RegionSize);
1013 foreach (GridRegion r in regions) 1090 foreach (GridRegion r in regions)
1014 { 1091 {
1015 MapBlockData block = new MapBlockData(); 1092 MapBlockData block = new MapBlockData();
1016 MapBlockFromGridRegion(block, r, flag); 1093 MapBlockFromGridRegion(block, r, flag);
1017 mapBlocks.Add(block); 1094 mapBlocks.Add(block);
1095 allBlocks.Add(block);
1096 if (mapBlocks.Count >= 10)
1097 {
1098 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1099 mapBlocks.Clear();
1100 Thread.Sleep(50);
1101 }
1018 } 1102 }
1019 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1103 if (mapBlocks.Count > 0)
1104 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1020 1105
1021 return mapBlocks; 1106 return allBlocks;
1022 } 1107 }
1023 1108
1024 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1109 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1242,7 +1327,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1242 } 1327 }
1243 else 1328 else
1244 { 1329 {
1245 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1330 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1246 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1331 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1247 { 1332 {
1248 OSDMap responsemapdata = new OSDMap(); 1333 OSDMap responsemapdata = new OSDMap();
@@ -1418,6 +1503,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1418 { 1503 {
1419 m_rootAgents.Remove(avatar.UUID); 1504 m_rootAgents.Remove(avatar.UUID);
1420 } 1505 }
1506
1507 lock (m_mapBlockRequestEvent)
1508 {
1509 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1510 m_mapBlockRequests.Remove(avatar.UUID);
1511 }
1421 } 1512 }
1422 1513
1423 public void OnRegionUp(GridRegion otherRegion) 1514 public void OnRegionUp(GridRegion otherRegion)
@@ -1462,9 +1553,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1462 Color background = Color.FromArgb(0, 0, 0, 0); 1553 Color background = Color.FromArgb(0, 0, 0, 0);
1463 SolidBrush transparent = new SolidBrush(background); 1554 SolidBrush transparent = new SolidBrush(background);
1464 Graphics g = Graphics.FromImage(overlay); 1555 Graphics g = Graphics.FromImage(overlay);
1465 g.FillRectangle(transparent, 0, 0, 256, 256); 1556 g.FillRectangle(transparent, 0, 0, 255, 255);
1466 1557
1467 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1558 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1559 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1468 1560
1469 foreach (ILandObject land in parcels) 1561 foreach (ILandObject land in parcels)
1470 { 1562 {
@@ -1472,8 +1564,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1472 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1564 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1473 { 1565 {
1474 landForSale = true; 1566 landForSale = true;
1567
1568 bool[,] landBitmap = land.GetLandBitmap();
1569
1570 for (int x = 0 ; x < 64 ; x++)
1571 {
1572 for (int y = 0 ; y < 64 ; y++)
1573 {
1574 if (landBitmap[x, y])
1575 {
1576 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1577
1578 if (x > 0)
1579 {
1580 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1581 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1582 }
1583 if (y > 0)
1584 {
1585 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1586 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1587 }
1588 if (x < 63)
1589 {
1590 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1591 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1592 }
1593 if (y < 63)
1594 {
1595 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1596 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1597 }
1598 }
1599 }
1600 }
1475 1601
1476 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1602 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1477 } 1603 }
1478 } 1604 }
1479 1605
@@ -1485,15 +1611,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1485 1611
1486 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1612 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1487 1613
1488 for (int x = 0 ; x < 64 ; x++)
1489 {
1490 for (int y = 0 ; y < 64 ; y++)
1491 {
1492 if (saleBitmap[x, y])
1493 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1494 }
1495 }
1496
1497 try 1614 try
1498 { 1615 {
1499 return OpenJPEG.EncodeFromImage(overlay, true); 1616 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1515,4 +1632,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1515 public uint itemtype; 1632 public uint itemtype;
1516 public ulong regionhandle; 1633 public ulong regionhandle;
1517 } 1634 }
1635
1636 public struct MapBlockRequestData
1637 {
1638 public IClientAPI client;
1639 public int minX;
1640 public int minY;
1641 public int maxX;
1642 public int maxY;
1643 public uint flags;
1644 }
1518} 1645}