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/AssetXferUploader.cs127
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs93
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs99
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs8
-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.cs202
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs97
-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/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.cs209
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs23
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs129
-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.cs388
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs75
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs12
-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.cs18
-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.cs328
-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.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs161
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs547
42 files changed, 2323 insertions, 1117 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index ec4dfd0..4cedfe6 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>
@@ -65,6 +73,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
65 private UUID TransactionID = UUID.Zero; 73 private UUID TransactionID = UUID.Zero;
66 private sbyte type = 0; 74 private sbyte type = 0;
67 private byte wearableType = 0; 75 private byte wearableType = 0;
76 private byte[] m_oldData = null;
68 public ulong XferID; 77 public ulong XferID;
69 private Scene m_Scene; 78 private Scene m_Scene;
70 79
@@ -302,6 +311,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
302 311
303 private void DoCreateItem(uint callbackID) 312 private void DoCreateItem(uint callbackID)
304 { 313 {
314 ValidateAssets();
305 m_Scene.AssetService.Store(m_asset); 315 m_Scene.AssetService.Store(m_asset);
306 316
307 InventoryItemBase item = new InventoryItemBase(); 317 InventoryItemBase item = new InventoryItemBase();
@@ -322,12 +332,84 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
322 item.Flags = (uint) wearableType; 332 item.Flags = (uint) wearableType;
323 item.CreationDate = Util.UnixTimeSinceEpoch(); 333 item.CreationDate = Util.UnixTimeSinceEpoch();
324 334
335 m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
336 item.ID, item.AssetID);
337
325 if (m_Scene.AddInventoryItem(item)) 338 if (m_Scene.AddInventoryItem(item))
326 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 339 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
327 else 340 else
328 ourClient.SendAlertMessage("Unable to create inventory item"); 341 ourClient.SendAlertMessage("Unable to create inventory item");
329 } 342 }
330 343
344 private void ValidateAssets()
345 {
346 if (m_asset.Type == (sbyte)AssetType.Clothing ||
347 m_asset.Type == (sbyte)AssetType.Bodypart)
348 {
349 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
350 string[] lines = content.Split(new char[] {'\n'});
351
352 List<string> validated = new List<string>();
353
354 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
355
356 int textures = 0;
357
358 foreach (string line in lines)
359 {
360 try
361 {
362 if (line.StartsWith("textures "))
363 {
364 textures = Convert.ToInt32(line.Substring(9));
365 validated.Add(line);
366 }
367 else if (textures > 0)
368 {
369 string[] parts = line.Split(new char[] {' '});
370
371 UUID tx = new UUID(parts[1]);
372 int id = Convert.ToInt32(parts[0]);
373
374 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
375 (allowed.ContainsKey(id) && allowed[id] == tx))
376 {
377 validated.Add(parts[0] + " " + tx.ToString());
378 }
379 else
380 {
381 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
382 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
383
384 if ((perms & full) != full)
385 {
386 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
387 validated.Add(parts[0] + " " + UUID.Zero.ToString());
388 }
389 else
390 {
391 validated.Add(line);
392 }
393 }
394 textures--;
395 }
396 else
397 {
398 validated.Add(line);
399 }
400 }
401 catch
402 {
403 // If it's malformed, skip it
404 }
405 }
406
407 string final = String.Join("\n", validated.ToArray());
408
409 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
410 }
411 }
412
331 /// <summary> 413 /// <summary>
332 /// Get the asset data uploaded in this transfer. 414 /// Get the asset data uploaded in this transfer.
333 /// </summary> 415 /// </summary>
@@ -336,10 +418,55 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
336 { 418 {
337 if (m_finished) 419 if (m_finished)
338 { 420 {
421 ValidateAssets();
339 return m_asset; 422 return m_asset;
340 } 423 }
341 424
342 return null; 425 return null;
343 } 426 }
427
428 public void SetOldData(byte[] d)
429 {
430 m_oldData = d;
431 }
432
433 private Dictionary<int,UUID> ExtractTexturesFromOldData()
434 {
435 Dictionary<int,UUID> result = new Dictionary<int,UUID>();
436 if (m_oldData == null)
437 return result;
438
439 string content = System.Text.Encoding.ASCII.GetString(m_oldData);
440 string[] lines = content.Split(new char[] {'\n'});
441
442 int textures = 0;
443
444 foreach (string line in lines)
445 {
446 try
447 {
448 if (line.StartsWith("textures "))
449 {
450 textures = Convert.ToInt32(line.Substring(9));
451 }
452 else if (textures > 0)
453 {
454 string[] parts = line.Split(new char[] {' '});
455
456 UUID tx = new UUID(parts[1]);
457 int id = Convert.ToInt32(parts[0]);
458 result[id] = tx;
459 textures--;
460 }
461 }
462 catch
463 {
464 // If it's malformed, skip it
465 }
466 }
467
468 return result;
469 }
344 } 470 }
345} 471}
472
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index fab489d..7d7176f 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -257,57 +257,70 @@ namespace Flotsam.RegionModules.AssetCache
257 257
258 private void UpdateFileCache(string key, AssetBase asset) 258 private void UpdateFileCache(string key, AssetBase asset)
259 { 259 {
260 string filename = GetFileName(asset.ID); 260 // TODO: Spawn this off to some seperate thread to do the actual writing
261 261 if (asset != null)
262 try
263 { 262 {
264 // If the file is already cached just update access time. 263 string filename = GetFileName(key);
265 if (File.Exists(filename)) 264
266 { 265 try
267 lock (m_CurrentlyWriting)
268 {
269 if (!m_CurrentlyWriting.Contains(filename))
270 File.SetLastAccessTime(filename, DateTime.Now);
271 }
272 }
273 else
274 { 266 {
275 // Once we start writing, make sure we flag that we're writing 267 // If the file is already cached, don't cache it, just touch it so access time is updated
276 // that object to the cache so that we don't try to write the 268 if (File.Exists(filename))
277 // same file multiple times.
278 lock (m_CurrentlyWriting)
279 { 269 {
280#if WAIT_ON_INPROGRESS_REQUESTS 270 // We don't really want to know about sharing
281 if (m_CurrentlyWriting.ContainsKey(filename)) 271 // violations here. If the file is locked, then
272 // the other thread has updated the time for us.
273 try
282 { 274 {
283 return; 275 lock (m_CurrentlyWriting)
276 {
277 if (!m_CurrentlyWriting.Contains(filename))
278 File.SetLastAccessTime(filename, DateTime.Now);
279 }
284 } 280 }
285 else 281 catch
286 {
287 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
288 }
289
290#else
291 if (m_CurrentlyWriting.Contains(filename))
292 { 282 {
293 return;
294 } 283 }
295 else 284 } else {
285
286 // Once we start writing, make sure we flag that we're writing
287 // that object to the cache so that we don't try to write the
288 // same file multiple times.
289 lock (m_CurrentlyWriting)
296 { 290 {
297 m_CurrentlyWriting.Add(filename); 291#if WAIT_ON_INPROGRESS_REQUESTS
298 } 292 if (m_CurrentlyWriting.ContainsKey(filename))
293 {
294 return;
295 }
296 else
297 {
298 m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
299 }
300
301#else
302 if (m_CurrentlyWriting.Contains(filename))
303 {
304 return;
305 }
306 else
307 {
308 m_CurrentlyWriting.Add(filename);
309 }
299#endif 310#endif
300 }
301 311
302 Util.FireAndForget( 312 }
303 delegate { WriteFileCache(filename, asset); }); 313
314 Util.FireAndForget(
315 delegate { WriteFileCache(filename, asset); });
316 }
317 }
318 catch (Exception e)
319 {
320 m_log.ErrorFormat(
321 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
322 asset.ID, e.Message, e.StackTrace);
304 } 323 }
305 }
306 catch (Exception e)
307 {
308 m_log.ErrorFormat(
309 "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
310 asset.ID, e.Message, e.StackTrace);
311 } 324 }
312 } 325 }
313 326
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index d34a8f6..c679a7b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Xml;
31using log4net; 32using log4net;
32using Mono.Addins; 33using Mono.Addins;
33using Nini.Config; 34using Nini.Config;
@@ -38,6 +39,7 @@ using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.Framework.Scenes.Serialization; 41using OpenSim.Region.Framework.Scenes.Serialization;
42using OpenSim.Services.Interfaces;
41 43
42namespace OpenSim.Region.CoreModules.Avatar.Attachments 44namespace OpenSim.Region.CoreModules.Avatar.Attachments
43{ 45{
@@ -167,6 +169,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
167 169
168// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name); 170// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0}", sp.Name);
169 171
172 XmlDocument doc = new XmlDocument();
173 string stateData = String.Empty;
174
175 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
176 if (attServ != null)
177 {
178 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
179 stateData = attServ.Get(sp.UUID.ToString());
180 if (stateData != String.Empty)
181 {
182 try
183 {
184 doc.LoadXml(stateData);
185 }
186 catch { }
187 }
188 }
189
190 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
191
192 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
193 if (nodes.Count > 0)
194 {
195 foreach (XmlNode n in nodes)
196 {
197 XmlElement elem = (XmlElement)n;
198 string itemID = elem.GetAttribute("ItemID");
199 string xml = elem.InnerXml;
200
201 itemData[new UUID(itemID)] = xml;
202 }
203 }
204
205
170 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 206 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
171 foreach (AvatarAttachment attach in attachments) 207 foreach (AvatarAttachment attach in attachments)
172 { 208 {
@@ -186,12 +222,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
186 222
187 try 223 try
188 { 224 {
225 string xmlData;
226 XmlDocument d = null;
227 UUID asset;
228 if (itemData.TryGetValue(attach.ItemID, out xmlData))
229 {
230 d = new XmlDocument();
231 d.LoadXml(xmlData);
232 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID);
233 }
234
189 // If we're an NPC then skip all the item checks and manipulations since we don't have an 235 // If we're an NPC then skip all the item checks and manipulations since we don't have an
190 // inventory right now. 236 // inventory right now.
191 if (sp.PresenceType == PresenceType.Npc) 237 if (sp.PresenceType == PresenceType.Npc)
192 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); 238 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null);
193 else 239 else
194 RezSingleAttachmentFromInventory(sp, attach.ItemID, p); 240 RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d);
195 } 241 }
196 catch (Exception e) 242 catch (Exception e)
197 { 243 {
@@ -248,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
248 sp.ClearAttachments(); 294 sp.ClearAttachments();
249 } 295 }
250 296
251 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) 297 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData)
252 { 298 {
253 lock (sp.AttachmentsSyncLock) 299 lock (sp.AttachmentsSyncLock)
254 { 300 {
@@ -303,6 +349,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
303 attachPos = Vector3.Zero; 349 attachPos = Vector3.Zero;
304 } 350 }
305 351
352 if (useAttachData)
353 {
354 group.RootPart.RotationOffset = group.RootPart.AttachRotation;
355 attachPos = group.RootPart.AttachOffset;
356 if (attachmentPt == 0)
357 {
358 attachmentPt = group.RootPart.AttachPoint;
359 if (attachmentPt == 0)
360 {
361 attachmentPt = (uint)AttachmentPoint.LeftHand;
362 attachPos = Vector3.Zero;
363 }
364 }
365 else if (group.RootPart.AttachPoint != attachmentPt)
366 {
367 attachPos = Vector3.Zero;
368 }
369 }
306 group.AttachmentPoint = attachmentPt; 370 group.AttachmentPoint = attachmentPt;
307 group.AbsolutePosition = attachPos; 371 group.AbsolutePosition = attachPos;
308 372
@@ -339,7 +403,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
339 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 403 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
340 } 404 }
341 405
342 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 406 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
407 {
408 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
409 }
410
411 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
343 { 412 {
344 if (!Enabled) 413 if (!Enabled)
345 return null; 414 return null;
@@ -378,7 +447,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
378 return null; 447 return null;
379 } 448 }
380 449
381 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 450 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
382 } 451 }
383 452
384 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 453 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -437,7 +506,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
437 so.AttachedAvatar = UUID.Zero; 506 so.AttachedAvatar = UUID.Zero;
438 rootPart.SetParentLocalId(0); 507 rootPart.SetParentLocalId(0);
439 so.ClearPartAttachmentData(); 508 so.ClearPartAttachmentData();
440 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 509 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
441 so.HasGroupChanged = true; 510 so.HasGroupChanged = true;
442 rootPart.Rezzed = DateTime.Now; 511 rootPart.Rezzed = DateTime.Now;
443 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 512 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -704,8 +773,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
704 so.RemoveScriptInstances(true); 773 so.RemoveScriptInstances(true);
705 } 774 }
706 775
707 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 776 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
708 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 777 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
709 { 778 {
710 if (m_invAccessModule == null) 779 if (m_invAccessModule == null)
711 return null; 780 return null;
@@ -743,7 +812,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
743 // This will throw if the attachment fails 812 // This will throw if the attachment fails
744 try 813 try
745 { 814 {
746 AttachObject(sp, objatt, attachmentPt, false); 815 AttachObject(sp, objatt, attachmentPt, false, false);
747 } 816 }
748 catch (Exception e) 817 catch (Exception e)
749 { 818 {
@@ -756,10 +825,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
756 m_scene.DeleteSceneObject(objatt, false); 825 m_scene.DeleteSceneObject(objatt, false);
757 return null; 826 return null;
758 } 827 }
759 828
760 if (tainted) 829 if (tainted)
761 objatt.HasGroupChanged = true; 830 objatt.HasGroupChanged = true;
762 831
832 if (doc != null)
833 {
834 objatt.LoadScriptState(doc);
835 objatt.ResetOwnerChangeFlag();
836 }
837
763 // Fire after attach, so we don't get messy perms dialogs 838 // Fire after attach, so we don't get messy perms dialogs
764 // 4 == AttachedRez 839 // 4 == AttachedRez
765 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 840 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
@@ -777,7 +852,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
777 itemID, sp.Name, attachmentPt); 852 itemID, sp.Name, attachmentPt);
778 } 853 }
779 } 854 }
780 855
781 return null; 856 return null;
782 } 857 }
783 858
@@ -897,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
897 AttachmentPt &= 0x7f; 972 AttachmentPt &= 0x7f;
898 973
899 // Calls attach with a Zero position 974 // Calls attach with a Zero position
900 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) 975 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true))
901 { 976 {
902// m_log.Debug( 977// m_log.Debug(
903// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 978// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index b021a47..cd1e1c1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
188 188
189 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 189 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
190 190
191 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); 191 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
192 192
193 // Check status on scene presence 193 // Check status on scene presence
194 Assert.That(sp.HasAttachments(), Is.True); 194 Assert.That(sp.HasAttachments(), Is.True);
@@ -242,7 +242,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
242 sp2.AbsolutePosition = new Vector3(0, 0, 0); 242 sp2.AbsolutePosition = new Vector3(0, 0, 0);
243 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 243 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
244 244
245 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); 245 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
246 246
247 Assert.That(sp.HasAttachments(), Is.False); 247 Assert.That(sp.HasAttachments(), Is.False);
248 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 248 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -387,7 +387,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
387 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 387 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
388 388
389 SceneObjectGroup soRezzed 389 SceneObjectGroup soRezzed
390 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 390 = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
391 391
392 // Wait for chat to signal rezzed script has been started. 392 // Wait for chat to signal rezzed script has been started.
393 m_chatEvent.WaitOne(60000); 393 m_chatEvent.WaitOne(60000);
@@ -604,4 +604,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
604// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); 604// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
605// } 605// }
606 } 606 }
607} \ No newline at end of file 607}
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 68a4cde..89cc4f6 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -566,12 +566,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
566 /// <param name="client"></param> 566 /// <param name="client"></param>
567 private void Client_OnRequestWearables(IClientAPI client) 567 private void Client_OnRequestWearables(IClientAPI client)
568 { 568 {
569 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 569 Util.FireAndForget(delegate(object x)
570 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 570 {
571 if (sp != null) 571 Thread.Sleep(4000);
572 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 572
573 else 573 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
574 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 574 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
575 if (sp != null)
576 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
577 else
578 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
579 });
575 } 580 }
576 581
577 /// <summary> 582 /// <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..1492302 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,85 @@ 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}),
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.Scene.IncomingCloseAgent(sp.UUID);
260 }
261
262 private void OnIncomingInstantMessage(GridInstantMessage msg)
263 {
264 if (msg.dialog == (uint)250) // Nonlocal kick
265 {
266 UUID agentID = new UUID(msg.toAgentID);
267 string reason = msg.message;
268 UUID godID = new UUID(msg.fromAgentID);
269 uint kickMode = (uint)msg.binaryBucket[0];
270
271 KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
180 } 272 }
181 } 273 }
182 } 274 }
183} \ No newline at end of file 275}
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..1406aae 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
@@ -247,6 +251,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
247 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 251 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
248 && requestData.ContainsKey("binary_bucket")) 252 && requestData.ContainsKey("binary_bucket"))
249 { 253 {
254 if (m_MessageKey != String.Empty)
255 {
256 XmlRpcResponse error_resp = new XmlRpcResponse();
257 Hashtable error_respdata = new Hashtable();
258 error_respdata["success"] = "FALSE";
259 error_resp.Value = error_respdata;
260
261 if (!requestData.Contains("message_key"))
262 return error_resp;
263 if (m_MessageKey != (string)requestData["message_key"])
264 return error_resp;
265 }
266
250 // Do the easy way of validating the UUIDs 267 // Do the easy way of validating the UUIDs
251 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 268 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
252 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 269 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -423,24 +440,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
423 return resp; 440 return resp;
424 } 441 }
425 442
426 /// <summary> 443 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 444
431 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 445 private class GIM {
432 { 446 public GridInstantMessage im;
433 GridInstantMessageDelegate icon = 447 public MessageResultNotification result;
434 (GridInstantMessageDelegate)iar.AsyncState; 448 };
435 icon.EndInvoke(iar);
436 }
437 449
450 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
451 private int numInstantMessageThreads = 0;
438 452
439 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 453 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
440 { 454 {
441 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 455 lock (pendingInstantMessages) {
456 if (numInstantMessageThreads >= 4) {
457 GIM gim = new GIM();
458 gim.im = im;
459 gim.result = result;
460 pendingInstantMessages.Enqueue(gim);
461 } else {
462 ++ numInstantMessageThreads;
463 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
464 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
465 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
466 }
467 }
468 }
442 469
443 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 470 private void GridInstantMessageCompleted(IAsyncResult iar)
471 {
472 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
473 d.EndInvoke(iar);
444 } 474 }
445 475
446 /// <summary> 476 /// <summary>
@@ -455,8 +485,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 485 /// Pass in 0 the first time this method is called. It will be called recursively with the last
456 /// regionhandle tried 486 /// regionhandle tried
457 /// </param> 487 /// </param>
458 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 488 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
459 { 489 {
490 GIM gim;
491 do {
492 try {
493 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
494 } catch (Exception e) {
495 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
496 }
497 lock (pendingInstantMessages) {
498 if (pendingInstantMessages.Count > 0) {
499 gim = pendingInstantMessages.Dequeue();
500 im = gim.im;
501 result = gim.result;
502 } else {
503 gim = null;
504 -- numInstantMessageThreads;
505 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
506 }
507 }
508 } while (gim != null);
509 }
510 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
511 {
512
460 UUID toAgentID = new UUID(im.toAgentID); 513 UUID toAgentID = new UUID(im.toAgentID);
461 514
462 PresenceInfo upd = null; 515 PresenceInfo upd = null;
@@ -523,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
523 576
524 if (upd != null) 577 if (upd != null)
525 { 578 {
526 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 579 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
527 upd.RegionID); 580 upd.RegionID);
528 if (reginfo != null) 581 if (reginfo != null)
529 { 582 {
@@ -672,6 +725,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
672 gim["position_z"] = msg.Position.Z.ToString(); 725 gim["position_z"] = msg.Position.Z.ToString();
673 gim["region_id"] = msg.RegionID.ToString(); 726 gim["region_id"] = msg.RegionID.ToString();
674 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 727 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
728 if (m_MessageKey != String.Empty)
729 gim["message_key"] = m_MessageKey;
675 return gim; 730 return gim;
676 } 731 }
677 732
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/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index f3af59a..81de29c 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 else if ( 316 else if (
@@ -335,6 +351,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
335 { 351 {
336 folder.ParentID = trashFolder.ID; 352 folder.ParentID = trashFolder.ID;
337 invService.MoveFolder(folder); 353 invService.MoveFolder(folder);
354 client.SendBulkUpdateInventory(folder);
338 } 355 }
339 } 356 }
340 357
@@ -435,22 +452,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
435 /// 452 ///
436 /// </summary> 453 /// </summary>
437 /// <param name="msg"></param> 454 /// <param name="msg"></param>
438 private void OnGridInstantMessage(GridInstantMessage msg) 455 private void OnGridInstantMessage(GridInstantMessage im)
439 { 456 {
440 // Check if this is ours to handle 457 // Check if this is ours to handle
441 // 458 //
442 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 459 Scene scene = FindClientScene(new UUID(im.toAgentID));
443 460
444 if (scene == null) 461 if (scene == null)
445 return; 462 return;
446 463
447 // Find agent to deliver to 464 // Find agent to deliver to
448 // 465 //
449 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 466 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
467 if (user == null)
468 return;
469
470 // This requires a little bit of processing because we have to make the
471 // new item visible in the recipient's inventory here
472 //
473 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
474 {
475 if (im.binaryBucket.Length < 17) // Invalid
476 return;
477
478 UUID recipientID = new UUID(im.toAgentID);
479
480 // First byte is the asset type
481 AssetType assetType = (AssetType)im.binaryBucket[0];
482
483 if (AssetType.Folder == assetType)
484 {
485 UUID folderID = new UUID(im.binaryBucket, 1);
450 486
451 // Just forward to local handling 487 InventoryFolderBase given =
452 OnInstantMessage(user.ControllingClient, msg); 488 new InventoryFolderBase(folderID, recipientID);
489 InventoryFolderBase folder =
490 scene.InventoryService.GetFolder(given);
453 491
492 if (folder != null)
493 user.ControllingClient.SendBulkUpdateInventory(folder);
494 }
495 else
496 {
497 UUID itemID = new UUID(im.binaryBucket, 1);
498
499 InventoryItemBase given =
500 new InventoryItemBase(itemID, recipientID);
501 InventoryItemBase item =
502 scene.InventoryService.GetItem(given);
503
504 if (item != null)
505 {
506 user.ControllingClient.SendBulkUpdateInventory(item);
507 }
508 }
509 user.ControllingClient.SendInstantMessage(im);
510 }
511 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
512 {
513 if (im.binaryBucket.Length < 1) // Invalid
514 return;
515
516 UUID recipientID = new UUID(im.toAgentID);
517
518 // Bucket is the asset type
519 AssetType assetType = (AssetType)im.binaryBucket[0];
520
521 if (AssetType.Folder == assetType)
522 {
523 UUID folderID = new UUID(im.imSessionID);
524
525 InventoryFolderBase given =
526 new InventoryFolderBase(folderID, recipientID);
527 InventoryFolderBase folder =
528 scene.InventoryService.GetFolder(given);
529
530 if (folder != null)
531 user.ControllingClient.SendBulkUpdateInventory(folder);
532 }
533 else
534 {
535 UUID itemID = new UUID(im.imSessionID);
536
537 InventoryItemBase given =
538 new InventoryItemBase(itemID, recipientID);
539 InventoryItemBase item =
540 scene.InventoryService.GetItem(given);
541
542 if (item != null)
543 {
544 user.ControllingClient.SendBulkUpdateInventory(item);
545 }
546 }
547
548 // Fix up binary bucket since this may be 17 chars long here
549 Byte[] bucket = new Byte[1];
550 bucket[0] = im.binaryBucket[0];
551 im.binaryBucket = bucket;
552
553 user.ControllingClient.SendInstantMessage(im);
554 }
555 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
556 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
557 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
558 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
559 {
560 user.ControllingClient.SendInstantMessage(im);
561 }
454 } 562 }
455 } 563 }
456} 564}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 2d4cffd..a889984 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]);
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]);
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]);
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 46738f6..560f807 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
@@ -269,6 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
269 sp.ControllingClient.SendTeleportStart(teleportFlags); 269 sp.ControllingClient.SendTeleportStart(teleportFlags);
270 270
271 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 271 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
272 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
272 sp.Velocity = Vector3.Zero; 273 sp.Velocity = Vector3.Zero;
273 sp.Teleport(position); 274 sp.Teleport(position);
274 275
@@ -429,8 +430,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
429 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, 430 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
430 // it's actually doing a lot of work. 431 // it's actually doing a lot of work.
431 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 432 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
432 433 if (endPoint == null || endPoint.Address == null)
433 if (endPoint.Address == null)
434 { 434 {
435 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 435 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
436 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 436 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
@@ -781,7 +781,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
781 781
782 #region Teleport Home 782 #region Teleport Home
783 783
784 public virtual void TeleportHome(UUID id, IClientAPI client) 784 public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
785 {
786 TeleportHome(id, client);
787 }
788
789 public virtual bool TeleportHome(UUID id, IClientAPI client)
785 { 790 {
786 m_log.DebugFormat( 791 m_log.DebugFormat(
787 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 792 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -791,12 +796,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
791 796
792 if (uinfo != null) 797 if (uinfo != null)
793 { 798 {
799 if (uinfo.HomeRegionID == UUID.Zero)
800 {
801 // can't find the Home region: Tell viewer and abort
802 client.SendTeleportFailed("You don't have a home position set.");
803 return false;
804 }
794 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); 805 GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID);
795 if (regionInfo == null) 806 if (regionInfo == null)
796 { 807 {
797 // can't find the Home region: Tell viewer and abort 808 // can't find the Home region: Tell viewer and abort
798 client.SendTeleportFailed("Your home region could not be found."); 809 client.SendTeleportFailed("Your home region could not be found.");
799 return; 810 return false;
800 } 811 }
801 812
802 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 813 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
@@ -809,10 +820,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
809 } 820 }
810 else 821 else
811 { 822 {
812 m_log.ErrorFormat( 823 // can't find the Home region: Tell viewer and abort
813 "[ENTITY TRANSFER MODULE]: No grid user information found for {0} {1}. Cannot send home.", 824 client.SendTeleportFailed("Your home region could not be found.");
814 client.Name, client.AgentId); 825 return false;
815 } 826 }
827 return true;
816 } 828 }
817 829
818 #endregion 830 #endregion
@@ -820,11 +832,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
820 832
821 #region Agent Crossings 833 #region Agent Crossings
822 834
823 public bool Cross(ScenePresence agent, bool isFlying) 835 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
824 { 836 {
825 Scene scene = agent.Scene; 837 version = String.Empty;
826 Vector3 pos = agent.AbsolutePosition; 838 newpos = new Vector3(pos.X, pos.Y, pos.Z);
827 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
828 uint neighbourx = scene.RegionInfo.RegionLocX; 839 uint neighbourx = scene.RegionInfo.RegionLocX;
829 uint neighboury = scene.RegionInfo.RegionLocY; 840 uint neighboury = scene.RegionInfo.RegionLocY;
830 const float boundaryDistance = 1.7f; 841 const float boundaryDistance = 1.7f;
@@ -845,52 +856,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
845 } 856 }
846 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 857 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
847 { 858 {
848 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 859 neighboury--;
849 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 860 newpos.Y = Constants.RegionSize - enterDistance;
850 {
851 neighboury--;
852 newpos.Y = Constants.RegionSize - enterDistance;
853 }
854 else
855 {
856 agent.IsInTransit = true;
857
858 neighboury = b.TriggerRegionY;
859 neighbourx = b.TriggerRegionX;
860
861 Vector3 newposition = pos;
862 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
863 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
864 agent.ControllingClient.SendAgentAlertMessage(
865 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
866 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
867 return true;
868 }
869 }
870
871 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
872 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
873 {
874 neighbourx--;
875 newpos.X = Constants.RegionSize - enterDistance;
876 }
877 else
878 {
879 agent.IsInTransit = true;
880
881 neighboury = ba.TriggerRegionY;
882 neighbourx = ba.TriggerRegionX;
883
884 Vector3 newposition = pos;
885 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
886 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
887 agent.ControllingClient.SendAgentAlertMessage(
888 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
889 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
890
891 return true;
892 } 861 }
893 862
863 neighbourx--;
864 newpos.X = Constants.RegionSize - enterDistance;
894 } 865 }
895 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 866 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
896 { 867 {
@@ -900,26 +871,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
900 871
901 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 872 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
902 { 873 {
903 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 874 neighboury--;
904 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 875 newpos.Y = Constants.RegionSize - enterDistance;
905 {
906 neighboury--;
907 newpos.Y = Constants.RegionSize - enterDistance;
908 }
909 else
910 {
911 agent.IsInTransit = true;
912
913 neighboury = ba.TriggerRegionY;
914 neighbourx = ba.TriggerRegionX;
915 Vector3 newposition = pos;
916 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
917 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
918 agent.ControllingClient.SendAgentAlertMessage(
919 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
920 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
921 return true;
922 }
923 } 876 }
924 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 877 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
925 { 878 {
@@ -931,25 +884,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
931 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 884 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
932 { 885 {
933 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 886 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
934 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 887 neighboury--;
935 { 888 newpos.Y = Constants.RegionSize - enterDistance;
936 neighboury--;
937 newpos.Y = Constants.RegionSize - enterDistance;
938 }
939 else
940 {
941 agent.IsInTransit = true;
942
943 neighboury = b.TriggerRegionY;
944 neighbourx = b.TriggerRegionX;
945 Vector3 newposition = pos;
946 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
947 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
948 agent.ControllingClient.SendAgentAlertMessage(
949 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
950 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
951 return true;
952 }
953 } 889 }
954 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 890 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
955 { 891 {
@@ -983,19 +919,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
983 } 919 }
984 */ 920 */
985 921
986 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 922 xDest = neighbourx;
923 yDest = neighboury;
987 924
988 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 925 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
989 926
927 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
928
990 ExpiringCache<ulong, DateTime> r; 929 ExpiringCache<ulong, DateTime> r;
991 DateTime banUntil; 930 DateTime banUntil;
992 931
993 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 932 if (m_bannedRegions.TryGetValue(agentID, out r))
994 { 933 {
995 if (r.TryGetValue(neighbourHandle, out banUntil)) 934 if (r.TryGetValue(neighbourHandle, out banUntil))
996 { 935 {
997 if (DateTime.Now < banUntil) 936 if (DateTime.Now < banUntil)
998 return false; 937 return null;
999 r.Remove(neighbourHandle); 938 r.Remove(neighbourHandle);
1000 } 939 }
1001 } 940 }
@@ -1007,28 +946,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1007 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 946 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1008 947
1009 string reason; 948 string reason;
1010 string version; 949 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1011 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
1012 { 950 {
1013 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1014 if (r == null) 951 if (r == null)
1015 { 952 {
1016 r = new ExpiringCache<ulong, DateTime>(); 953 r = new ExpiringCache<ulong, DateTime>();
1017 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 954 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1018 955
1019 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 956 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
1020 } 957 }
1021 else 958 else
1022 { 959 {
1023 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 960 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
1024 } 961 }
962 return null;
963 }
964
965 return neighbourRegion;
966 }
967
968 public bool Cross(ScenePresence agent, bool isFlying)
969 {
970 uint x;
971 uint y;
972 Vector3 newpos;
973 string version;
974
975 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
976 if (neighbourRegion == null)
977 {
978 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
1025 return false; 979 return false;
1026 } 980 }
1027 981
1028 agent.IsInTransit = true; 982 agent.IsInTransit = true;
1029 983
1030 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 984 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1031 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 985 d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1032 986
1033 return true; 987 return true;
1034 } 988 }
@@ -1085,13 +1039,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1085 icon.EndInvoke(iar); 1039 icon.EndInvoke(iar);
1086 } 1040 }
1087 1041
1088 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
1089
1090 /// <summary> 1042 /// <summary>
1091 /// This Closes child agents on neighbouring regions 1043 /// This Closes child agents on neighbouring regions
1092 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1044 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1093 /// </summary> 1045 /// </summary>
1094 protected ScenePresence CrossAgentToNewRegionAsync( 1046 public ScenePresence CrossAgentToNewRegionAsync(
1095 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 1047 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
1096 bool isFlying, string version) 1048 bool isFlying, string version)
1097 { 1049 {
@@ -1298,10 +1250,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1298 agent.Id0 = currentAgentCircuit.Id0; 1250 agent.Id0 = currentAgentCircuit.Id0;
1299 } 1251 }
1300 1252
1301 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 1253 IPEndPoint external = region.ExternalEndPoint;
1302 d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, 1254 if (external != null)
1255 {
1256 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1257 d.BeginInvoke(sp, agent, region, external, true,
1303 InformClientOfNeighbourCompleted, 1258 InformClientOfNeighbourCompleted,
1304 d); 1259 d);
1260 }
1305 } 1261 }
1306 #endregion 1262 #endregion
1307 1263
@@ -1882,27 +1838,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1882 Utils.LongToUInts(newRegionHandle, out x, out y); 1838 Utils.LongToUInts(newRegionHandle, out x, out y);
1883 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1839 GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1884 1840
1885 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 1841 if (destination != null)
1886 { 1842 {
1887 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 1843 if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
1844 return; // we did it
1845 }
1888 1846
1889 // We are going to move the object back to the old position so long as the old position 1847 // no one or failed lets go back and tell physics to go on
1890 // is in the region 1848 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
1891 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 1849 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
1892 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 1850 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
1893 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
1894 1851
1895 grp.RootPart.GroupPosition = oldGroupPosition; 1852 grp.AbsolutePosition = oldGroupPosition;
1853 grp.Velocity = Vector3.Zero;
1896 1854
1897 // Need to turn off the physics flags, otherwise the object will continue to attempt to 1855 if (grp.RootPart.PhysActor != null)
1898 // move out of the region creating an infinite loop of failed attempts to cross 1856 grp.RootPart.PhysActor.CrossingFailure();
1899 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1900 1857
1901 grp.ScheduleGroupForFullUpdate(); 1858 grp.ScheduleGroupForFullUpdate();
1902 }
1903 } 1859 }
1904 1860
1905 1861
1862
1906 /// <summary> 1863 /// <summary>
1907 /// Move the given scene object into a new region 1864 /// Move the given scene object into a new region
1908 /// </summary> 1865 /// </summary>
@@ -1959,7 +1916,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1959 { 1916 {
1960 PhysicsActor pa = grp.RootPart.PhysActor; 1917 PhysicsActor pa = grp.RootPart.PhysActor;
1961 if (pa != null) 1918 if (pa != null)
1919 {
1962 pa.CrossingFailure(); 1920 pa.CrossingFailure();
1921 if (grp.RootPart.KeyframeMotion != null)
1922 {
1923 grp.RootPart.Velocity = Vector3.Zero;
1924 grp.RootPart.KeyframeMotion.CrossingFailure();
1925 grp.SendGroupRootTerseUpdate();
1926 }
1927 }
1963 } 1928 }
1964 1929
1965 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); 1930 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
@@ -2048,4 +2013,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2048 #endregion 2013 #endregion
2049 2014
2050 } 2015 }
2051} \ No newline at end of file 2016}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 08863c2..3010b59 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -90,7 +90,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
90 90
91 protected override void OnNewClient(IClientAPI client) 91 protected override void OnNewClient(IClientAPI client)
92 { 92 {
93 client.OnTeleportHomeRequest += TeleportHome; 93 client.OnTeleportHomeRequest += TriggerTeleportHome;
94 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 94 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
95 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed); 95 client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
96 } 96 }
@@ -195,7 +195,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
195 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 195 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
196 } 196 }
197 197
198 public override void TeleportHome(UUID id, IClientAPI client) 198 public void TriggerTeleportHome(UUID id, IClientAPI client)
199 {
200 TeleportHome(id, client);
201 }
202
203 public override bool TeleportHome(UUID id, IClientAPI client)
199 { 204 {
200 m_log.DebugFormat( 205 m_log.DebugFormat(
201 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); 206 "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
@@ -206,8 +211,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
206 { 211 {
207 // local grid user 212 // local grid user
208 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); 213 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local");
209 base.TeleportHome(id, client); 214 return base.TeleportHome(id, client);
210 return;
211 } 215 }
212 216
213 // Foreign user wants to go home 217 // Foreign user wants to go home
@@ -217,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
217 { 221 {
218 client.SendTeleportFailed("Your information has been lost"); 222 client.SendTeleportFailed("Your information has been lost");
219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); 223 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information");
220 return; 224 return false;
221 } 225 }
222 226
223 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); 227 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString());
@@ -227,7 +231,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
227 { 231 {
228 client.SendTeleportFailed("Your home region could not be found"); 232 client.SendTeleportFailed("Your home region could not be found");
229 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); 233 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found");
230 return; 234 return false;
231 } 235 }
232 236
233 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); 237 ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId);
@@ -235,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
235 { 239 {
236 client.SendTeleportFailed("Internal error"); 240 client.SendTeleportFailed("Internal error");
237 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); 241 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be");
238 return; 242 return false;
239 } 243 }
240 244
241 GridRegion homeGatekeeper = MakeRegion(aCircuit); 245 GridRegion homeGatekeeper = MakeRegion(aCircuit);
@@ -243,9 +247,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
243 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 247 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
244 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 248 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
245 249
246 DoTeleport( 250 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
247 sp, homeGatekeeper, finalDestination, 251 return true;
248 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
249 } 252 }
250 253
251 /// <summary> 254 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 7d51eed..d30c2e2 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -359,6 +359,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
359 359
360 foreach (SceneObjectGroup objectGroup in objlist) 360 foreach (SceneObjectGroup objectGroup in objlist)
361 { 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
362 Vector3 inventoryStoredPosition = new Vector3 368 Vector3 inventoryStoredPosition = new Vector3
363 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 369 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
364 ? 250 370 ? 250
@@ -369,9 +375,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
369 : objectGroup.AbsolutePosition.Y, 375 : objectGroup.AbsolutePosition.Y,
370 objectGroup.AbsolutePosition.Z); 376 objectGroup.AbsolutePosition.Z);
371 377
378 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
372 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 379 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
373 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
374 objectGroup.AbsolutePosition = inventoryStoredPosition; 389 objectGroup.AbsolutePosition = inventoryStoredPosition;
390 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
375 391
376 // Make sure all bits but the ones we want are clear 392 // Make sure all bits but the ones we want are clear
377 // on take. 393 // on take.
@@ -489,8 +505,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
489 IClientAPI remoteClient) 505 IClientAPI remoteClient)
490 { 506 {
491 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.
492 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 511 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
493 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 }
494 effectivePerms |= (uint)PermissionMask.Move; 519 effectivePerms |= (uint)PermissionMask.Move;
495 520
496 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())
@@ -669,7 +694,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
669 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) 694 if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
670 { 695 {
671 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 696 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
672 folder = m_Scene.InventoryService.GetFolder(f); 697 if (f != null)
698 folder = m_Scene.InventoryService.GetFolder(f);
673 } 699 }
674 } 700 }
675 701
@@ -699,16 +725,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
699 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 725 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
700 { 726 {
701// 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);
702
703 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 728 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
704 item = m_Scene.InventoryService.GetItem(item); 729 item = m_Scene.InventoryService.GetItem(item);
705 730
706 if (item == null) 731 if (item == null)
707 { 732 {
708 m_log.WarnFormat(
709 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
710 itemID, remoteClient.Name);
711
712 return null; 733 return null;
713 } 734 }
714 735
@@ -759,6 +780,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
759 if (e == null || attachment) // Single 780 if (e == null || attachment) // Single
760 { 781 {
761 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 }
762 790
763 objlist.Add(g); 791 objlist.Add(g);
764 veclist.Add(new Vector3(0, 0, 0)); 792 veclist.Add(new Vector3(0, 0, 0));
@@ -788,6 +816,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
788 foreach (XmlNode n in groups) 816 foreach (XmlNode n in groups)
789 { 817 {
790 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;
791 823
792 objlist.Add(g); 824 objlist.Add(g);
793 XmlElement el = (XmlElement)n; 825 XmlElement el = (XmlElement)n;
@@ -807,12 +839,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
807 } 839 }
808 } 840 }
809 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
810 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) 864 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
811 return null; 865 return null;
812 866
813 for (int i = 0; i < objlist.Count; i++) 867 for (int i = 0; i < objlist.Count; i++)
814 { 868 {
815 group = objlist[i]; 869 group = objlist[i];
870 SceneObjectPart rootPart = group.RootPart;
816 871
817// m_log.DebugFormat( 872// m_log.DebugFormat(
818// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 873// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -873,8 +928,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
873 928
874 if (!attachment) 929 if (!attachment)
875 { 930 {
876 SceneObjectPart rootPart = group.RootPart;
877
878 if (rootPart.Shape.PCode == (byte)PCode.Prim) 931 if (rootPart.Shape.PCode == (byte)PCode.Prim)
879 group.ClearPartAttachmentData(); 932 group.ClearPartAttachmentData();
880 933
@@ -892,6 +945,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
892// remoteClient.Name); 945// remoteClient.Name);
893 } 946 }
894 947
948 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
949
895 if (item != null) 950 if (item != null)
896 DoPostRezWhenFromItem(item, attachment); 951 DoPostRezWhenFromItem(item, attachment);
897 952
@@ -970,8 +1025,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
970 { 1025 {
971 rootPart.Name = item.Name; 1026 rootPart.Name = item.Name;
972 rootPart.Description = item.Description; 1027 rootPart.Description = item.Description;
973 rootPart.ObjectSaleType = item.SaleType; 1028 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
974 rootPart.SalePrice = item.SalePrice; 1029 {
1030 rootPart.ObjectSaleType = item.SaleType;
1031 rootPart.SalePrice = item.SalePrice;
1032 }
975 } 1033 }
976 1034
977 so.FromFolderID = item.Folder; 1035 so.FromFolderID = item.Folder;
@@ -981,7 +1039,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
981// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1039// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
982 1040
983 if ((rootPart.OwnerID != item.Owner) || 1041 if ((rootPart.OwnerID != item.Owner) ||
984 (item.CurrentPermissions & 16) != 0) 1042 (item.CurrentPermissions & 16) != 0 ||
1043 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
985 { 1044 {
986 //Need to kill the for sale here 1045 //Need to kill the for sale here
987 rootPart.ObjectSaleType = 0; 1046 rootPart.ObjectSaleType = 0;
@@ -991,31 +1050,43 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
991 { 1050 {
992 foreach (SceneObjectPart part in so.Parts) 1051 foreach (SceneObjectPart part in so.Parts)
993 { 1052 {
994 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
995 {
996 part.EveryoneMask = item.EveryOnePermissions;
997 part.NextOwnerMask = item.NextPermissions;
998 }
999 part.GroupMask = 0; // DO NOT propagate here 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);
1000 } 1058 }
1001 1059
1002 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 }
1003 } 1075 }
1004 } 1076 }
1005 1077 else
1006 foreach (SceneObjectPart part in so.Parts)
1007 { 1078 {
1008 part.FromUserInventoryItemID = fromUserInventoryItemId; 1079 foreach (SceneObjectPart part in so.Parts)
1009
1010 if ((part.OwnerID != item.Owner) ||
1011 (item.CurrentPermissions & 16) != 0)
1012 { 1080 {
1013 part.Inventory.ChangeInventoryOwner(item.Owner); 1081 part.FromUserInventoryItemID = fromUserInventoryItemId;
1014 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;
1015 } 1089 }
1016
1017 part.EveryoneMask = item.EveryOnePermissions;
1018 part.NextOwnerMask = item.NextPermissions;
1019 } 1090 }
1020 1091
1021 rootPart.TrimPermissions(); 1092 rootPart.TrimPermissions();
@@ -1153,4 +1224,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1153 1224
1154 #endregion 1225 #endregion
1155 } 1226 }
1156} \ 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 05d54f0..f4a89bd 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
@@ -87,37 +61,26 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
87 //public ManualResetEvent ev; 61 //public ManualResetEvent ev;
88 public bool requestDone; 62 public bool requestDone;
89 public int startTime; 63 public int startTime;
64 public bool responseSent;
90 public string uri; 65 public string uri;
91 } 66 }
92 67
93 /// <summary>
94 /// This module provides external URLs for in-world scripts.
95 /// </summary>
96 public class UrlModule : ISharedRegionModule, IUrlModule 68 public class UrlModule : ISharedRegionModule, IUrlModule
97 { 69 {
98 private static readonly ILog m_log = 70 private static readonly ILog m_log =
99 LogManager.GetLogger( 71 LogManager.GetLogger(
100 MethodBase.GetCurrentMethod().DeclaringType); 72 MethodBase.GetCurrentMethod().DeclaringType);
101 73
102 /// <summary> 74 private Dictionary<UUID, UrlData> m_RequestMap =
103 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID 75 new Dictionary<UUID, UrlData>();
104 /// randomly generated when a request is received for this URL.
105 /// </summary>
106 /// <remarks>
107 /// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
108 /// m_UrlMap
109 /// </remarks>
110 private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
111 76
112 /// <summary> 77 private Dictionary<string, UrlData> m_UrlMap =
113 /// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL 78 new Dictionary<string, UrlData>();
114 /// </summary>
115 private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
116 79
117 /// <summary> 80 /// <summary>
118 /// Maximum number of external urls that can be set up by this module. 81 /// Maximum number of external urls that can be set up by this module.
119 /// </summary> 82 /// </summary>
120 private int m_TotalUrls = 100; 83 private int m_TotalUrls = 5000;
121 84
122 private uint https_port = 0; 85 private uint https_port = 0;
123 private IHttpServer m_HttpServer = null; 86 private IHttpServer m_HttpServer = null;
@@ -143,9 +106,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
143 { 106 {
144 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 107 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
145 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false); 108 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
146
147 if (ssl_enabled) 109 if (ssl_enabled)
110 {
148 https_port = (uint) config.Configs["Network"].GetInt("https_port",0); 111 https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
112 }
149 113
150 IConfig llFunctionsConfig = config.Configs["LL-Functions"]; 114 IConfig llFunctionsConfig = config.Configs["LL-Functions"];
151 115
@@ -206,7 +170,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
206 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 170 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
207 return urlcode; 171 return urlcode;
208 } 172 }
209 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; 173 string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString();
210 174
211 UrlData urlData = new UrlData(); 175 UrlData urlData = new UrlData();
212 urlData.hostID = host.UUID; 176 urlData.hostID = host.UUID;
@@ -215,14 +179,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
215 urlData.url = url; 179 urlData.url = url;
216 urlData.urlcode = urlcode; 180 urlData.urlcode = urlcode;
217 urlData.requests = new Dictionary<UUID, RequestData>(); 181 urlData.requests = new Dictionary<UUID, RequestData>();
218 182
219 m_UrlMap[url] = urlData; 183 m_UrlMap[url] = urlData;
220 184
221 string uri = "/lslhttp/" + urlcode.ToString() + "/"; 185 string uri = "/lslhttp/" + urlcode.ToString();
222 186
223 m_HttpServer.AddPollServiceHTTPHandler( 187 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
224 uri, 188 args.Type = PollServiceEventArgs.EventType.LslHttp;
225 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 189 m_HttpServer.AddPollServiceHTTPHandler(uri, args);
226 190
227 m_log.DebugFormat( 191 m_log.DebugFormat(
228 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", 192 "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}",
@@ -251,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
251 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 215 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
252 return urlcode; 216 return urlcode;
253 } 217 }
254 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; 218 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString();
255 219
256 UrlData urlData = new UrlData(); 220 UrlData urlData = new UrlData();
257 urlData.hostID = host.UUID; 221 urlData.hostID = host.UUID;
@@ -261,13 +225,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
261 urlData.urlcode = urlcode; 225 urlData.urlcode = urlcode;
262 urlData.requests = new Dictionary<UUID, RequestData>(); 226 urlData.requests = new Dictionary<UUID, RequestData>();
263 227
228
264 m_UrlMap[url] = urlData; 229 m_UrlMap[url] = urlData;
265 230
266 string uri = "/lslhttps/" + urlcode.ToString() + "/"; 231 string uri = "/lslhttps/" + urlcode.ToString();
267 232
268 m_HttpsServer.AddPollServiceHTTPHandler( 233 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000);
269 uri, 234 args.Type = PollServiceEventArgs.EventType.LslHttp;
270 new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode)); 235 m_HttpsServer.AddPollServiceHTTPHandler(uri, args);
271 236
272 m_log.DebugFormat( 237 m_log.DebugFormat(
273 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", 238 "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}",
@@ -290,12 +255,15 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
290 return; 255 return;
291 } 256 }
292 257
293 foreach (UUID req in data.requests.Keys) 258 lock (m_RequestMap)
294 m_RequestMap.Remove(req); 259 {
295 260 foreach (UUID req in data.requests.Keys)
296 m_log.DebugFormat( 261 m_RequestMap.Remove(req);
297 "[URL MODULE]: Releasing url {0} for {1} in {2}", 262 }
298 url, data.itemID, data.hostID); 263
264// m_log.DebugFormat(
265// "[URL MODULE]: Releasing url {0} for {1} in {2}",
266// url, data.itemID, data.hostID);
299 267
300 RemoveUrl(data); 268 RemoveUrl(data);
301 m_UrlMap.Remove(url); 269 m_UrlMap.Remove(url);
@@ -304,15 +272,19 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
304 272
305 public void HttpResponse(UUID request, int status, string body) 273 public void HttpResponse(UUID request, int status, string body)
306 { 274 {
307 lock (m_UrlMap) 275 lock (m_RequestMap)
308 { 276 {
309 if (m_RequestMap.ContainsKey(request)) 277 if (m_RequestMap.ContainsKey(request))
310 { 278 {
311 UrlData urlData = m_RequestMap[request]; 279 UrlData urlData = m_RequestMap[request];
312 urlData.requests[request].responseCode = status; 280 if (!urlData.requests[request].responseSent)
313 urlData.requests[request].responseBody = body; 281 {
314 //urlData.requests[request].ev.Set(); 282 urlData.requests[request].responseCode = status;
315 urlData.requests[request].requestDone =true; 283 urlData.requests[request].responseBody = body;
284 //urlData.requests[request].ev.Set();
285 urlData.requests[request].requestDone = true;
286 urlData.requests[request].responseSent = true;
287 }
316 } 288 }
317 else 289 else
318 { 290 {
@@ -323,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
323 295
324 public string GetHttpHeader(UUID requestId, string header) 296 public string GetHttpHeader(UUID requestId, string header)
325 { 297 {
326 lock (m_UrlMap) 298 lock (m_RequestMap)
327 { 299 {
328 if (m_RequestMap.ContainsKey(requestId)) 300 if (m_RequestMap.ContainsKey(requestId))
329 { 301 {
@@ -337,14 +309,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
337 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId); 309 m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
338 } 310 }
339 } 311 }
340
341 return String.Empty; 312 return String.Empty;
342 } 313 }
343 314
344 public int GetFreeUrls() 315 public int GetFreeUrls()
345 { 316 {
346 lock (m_UrlMap) 317 return m_TotalUrls - m_UrlMap.Count;
347 return m_TotalUrls - m_UrlMap.Count;
348 } 318 }
349 319
350 public void ScriptRemoved(UUID itemID) 320 public void ScriptRemoved(UUID itemID)
@@ -361,8 +331,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
361 { 331 {
362 RemoveUrl(url.Value); 332 RemoveUrl(url.Value);
363 removeURLs.Add(url.Key); 333 removeURLs.Add(url.Key);
364 foreach (UUID req in url.Value.requests.Keys) 334 lock (m_RequestMap)
365 m_RequestMap.Remove(req); 335 {
336 foreach (UUID req in url.Value.requests.Keys)
337 m_RequestMap.Remove(req);
338 }
366 } 339 }
367 } 340 }
368 341
@@ -383,9 +356,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
383 { 356 {
384 RemoveUrl(url.Value); 357 RemoveUrl(url.Value);
385 removeURLs.Add(url.Key); 358 removeURLs.Add(url.Key);
386 359 lock (m_RequestMap)
387 foreach (UUID req in url.Value.requests.Keys) 360 {
388 m_RequestMap.Remove(req); 361 foreach (UUID req in url.Value.requests.Keys)
362 m_RequestMap.Remove(req);
363 }
389 } 364 }
390 } 365 }
391 366
@@ -394,122 +369,125 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
394 } 369 }
395 } 370 }
396 371
372
397 private void RemoveUrl(UrlData data) 373 private void RemoveUrl(UrlData data)
398 { 374 {
399 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/"); 375 m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
400 } 376 }
401 377
402 private Hashtable NoEvents(UUID requestID, UUID sessionID) 378 private Hashtable NoEvents(UUID requestID, UUID sessionID)
403 { 379 {
404 Hashtable response = new Hashtable(); 380 Hashtable response = new Hashtable();
405 UrlData urlData; 381 UrlData url;
406 382 int startTime = 0;
407 lock (m_UrlMap) 383 lock (m_RequestMap)
408 { 384 {
409 // We need to return a 404 here in case the request URL was removed at exactly the same time that a
410 // request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
411 // for the request ID.
412 if (!m_RequestMap.ContainsKey(requestID)) 385 if (!m_RequestMap.ContainsKey(requestID))
413 {
414 response["int_response_code"] = 404;
415 response["str_response_string"] = "";
416 response["keepalive"] = false;
417 response["reusecontext"] = false;
418
419 return response; 386 return response;
420 } 387 url = m_RequestMap[requestID];
388 startTime = url.requests[requestID].startTime;
389 }
421 390
422 urlData = m_RequestMap[requestID]; 391 if (System.Environment.TickCount - startTime > 25000)
392 {
393 response["int_response_code"] = 500;
394 response["str_response_string"] = "Script timeout";
395 response["content_type"] = "text/plain";
396 response["keepalive"] = false;
397 response["reusecontext"] = false;
423 398
424 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000) 399 //remove from map
400 lock (url.requests)
401 {
402 url.requests.Remove(requestID);
403 }
404 lock (m_RequestMap)
425 { 405 {
426 response["int_response_code"] = 500;
427 response["str_response_string"] = "Script timeout";
428 response["content_type"] = "text/plain";
429 response["keepalive"] = false;
430 response["reusecontext"] = false;
431
432 //remove from map
433 urlData.requests.Remove(requestID);
434 m_RequestMap.Remove(requestID); 406 m_RequestMap.Remove(requestID);
435
436 return response;
437 } 407 }
408
409 return response;
438 } 410 }
439 411
412
440 return response; 413 return response;
441 } 414 }
442 415
443 private bool HasEvents(UUID requestID, UUID sessionID) 416 private bool HasEvents(UUID requestID, UUID sessionID)
444 { 417 {
445 lock (m_UrlMap) 418 UrlData url=null;
419
420 lock (m_RequestMap)
446 { 421 {
447 // We return true here because an external URL request that happened at the same time as an llRemoveURL()
448 // can still make it through to HttpRequestHandler(). That will return without setting up a request
449 // when it detects that the URL has been removed. The poller, however, will continue to ask for
450 // events for that request, so here we will signal that there are events and in GetEvents we will
451 // return a 404.
452 if (!m_RequestMap.ContainsKey(requestID)) 422 if (!m_RequestMap.ContainsKey(requestID))
453 { 423 {
454 return true; 424 return false;
455 } 425 }
456 426 url = m_RequestMap[requestID];
457 UrlData urlData = m_RequestMap[requestID]; 427 }
458 428 lock (url.requests)
459 if (!urlData.requests.ContainsKey(requestID)) 429 {
430 if (!url.requests.ContainsKey(requestID))
460 { 431 {
461 return true; 432 return false;
462 } 433 }
463 434 else
464 // Trigger return of timeout response.
465 if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
466 { 435 {
467 return true; 436 if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
437 {
438 return true;
439 }
440 if (url.requests[requestID].requestDone)
441 return true;
442 else
443 return false;
468 } 444 }
469
470 return urlData.requests[requestID].requestDone;
471 } 445 }
472 } 446 }
473
474 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) 447 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
475 { 448 {
476 Hashtable response; 449 UrlData url = null;
450 RequestData requestData = null;
477 451
478 lock (m_UrlMap) 452 lock (m_RequestMap)
479 { 453 {
480 UrlData url = null;
481 RequestData requestData = null;
482
483 if (!m_RequestMap.ContainsKey(requestID)) 454 if (!m_RequestMap.ContainsKey(requestID))
484 return NoEvents(requestID, sessionID); 455 return NoEvents(requestID,sessionID);
485
486 url = m_RequestMap[requestID]; 456 url = m_RequestMap[requestID];
457 }
458 lock (url.requests)
459 {
487 requestData = url.requests[requestID]; 460 requestData = url.requests[requestID];
461 }
462
463 if (!requestData.requestDone)
464 return NoEvents(requestID,sessionID);
465
466 Hashtable response = new Hashtable();
488 467
489 if (!requestData.requestDone) 468 if (System.Environment.TickCount - requestData.startTime > 25000)
490 return NoEvents(requestID, sessionID); 469 {
491 470 response["int_response_code"] = 500;
492 response = new Hashtable(); 471 response["str_response_string"] = "Script timeout";
493
494 if (System.Environment.TickCount - requestData.startTime > 25000)
495 {
496 response["int_response_code"] = 500;
497 response["str_response_string"] = "Script timeout";
498 response["content_type"] = "text/plain";
499 response["keepalive"] = false;
500 response["reusecontext"] = false;
501 return response;
502 }
503
504 //put response
505 response["int_response_code"] = requestData.responseCode;
506 response["str_response_string"] = requestData.responseBody;
507 response["content_type"] = "text/plain"; 472 response["content_type"] = "text/plain";
508 response["keepalive"] = false; 473 response["keepalive"] = false;
509 response["reusecontext"] = false; 474 response["reusecontext"] = false;
510 475 return response;
511 //remove from map 476 }
477 //put response
478 response["int_response_code"] = requestData.responseCode;
479 response["str_response_string"] = requestData.responseBody;
480 response["content_type"] = "text/plain";
481 response["keepalive"] = false;
482 response["reusecontext"] = false;
483
484 //remove from map
485 lock (url.requests)
486 {
512 url.requests.Remove(requestID); 487 url.requests.Remove(requestID);
488 }
489 lock (m_RequestMap)
490 {
513 m_RequestMap.Remove(requestID); 491 m_RequestMap.Remove(requestID);
514 } 492 }
515 493
@@ -518,41 +496,45 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
518 496
519 public void HttpRequestHandler(UUID requestID, Hashtable request) 497 public void HttpRequestHandler(UUID requestID, Hashtable request)
520 { 498 {
521 string uri = request["uri"].ToString(); 499 lock (request)
522 bool is_ssl = uri.Contains("lslhttps");
523
524 try
525 { 500 {
526 Hashtable headers = (Hashtable)request["headers"]; 501 string uri = request["uri"].ToString();
527 502 bool is_ssl = uri.Contains("lslhttps");
528// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
529 503
530 int pos1 = uri.IndexOf("/");// /lslhttp 504 try
531 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
532 int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
533 string uri_tmp = uri.Substring(0, pos3 + 1);
534 //HTTP server code doesn't provide us with QueryStrings
535 string pathInfo;
536 string queryString;
537 queryString = "";
538
539 pathInfo = uri.Substring(pos3);
540
541 UrlData urlData = null;
542
543 lock (m_UrlMap)
544 { 505 {
545 string url; 506 Hashtable headers = (Hashtable)request["headers"];
507
508// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
546 509
547 if (is_ssl) 510 int pos1 = uri.IndexOf("/");// /lslhttp
548 url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp; 511 int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
512 int pos3 = pos2 + 37; // /lslhttp/urlcode
513 string uri_tmp = uri.Substring(0, pos3);
514 //HTTP server code doesn't provide us with QueryStrings
515 string pathInfo;
516 string queryString;
517 queryString = "";
518
519 pathInfo = uri.Substring(pos3);
520
521 UrlData url = null;
522 string urlkey;
523 if (!is_ssl)
524 urlkey = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
525 //m_UrlMap[];
549 else 526 else
550 url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp; 527 urlkey = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
551 528
552 // Avoid a race - the request URL may have been released via llRequestUrl() whilst this 529 if (m_UrlMap.ContainsKey(urlkey))
553 // request was being processed. 530 {
554 if (!m_UrlMap.TryGetValue(url, out urlData)) 531 url = m_UrlMap[urlkey];
532 }
533 else
534 {
535 //m_log.Warn("[HttpRequestHandler]: http-in request failed; no such url: "+urlkey.ToString());
555 return; 536 return;
537 }
556 538
557 //for llGetHttpHeader support we need to store original URI here 539 //for llGetHttpHeader support we need to store original URI here
558 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 540 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
@@ -572,7 +554,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
572 string value = (string)header.Value; 554 string value = (string)header.Value;
573 requestData.headers.Add(key, value); 555 requestData.headers.Add(key, value);
574 } 556 }
575
576 foreach (DictionaryEntry de in request) 557 foreach (DictionaryEntry de in request)
577 { 558 {
578 if (de.Key.ToString() == "querystringkeys") 559 if (de.Key.ToString() == "querystringkeys")
@@ -583,13 +564,21 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
583 if (request.ContainsKey(key)) 564 if (request.ContainsKey(key))
584 { 565 {
585 string val = (String)request[key]; 566 string val = (String)request[key];
586 queryString = queryString + key + "=" + val + "&"; 567 if (key != "")
568 {
569 queryString = queryString + key + "=" + val + "&";
570 }
571 else
572 {
573 queryString = queryString + val + "&";
574 }
587 } 575 }
588 } 576 }
589
590 if (queryString.Length > 1) 577 if (queryString.Length > 1)
591 queryString = queryString.Substring(0, queryString.Length - 1); 578 queryString = queryString.Substring(0, queryString.Length - 1);
579
592 } 580 }
581
593 } 582 }
594 583
595 //if this machine is behind DNAT/port forwarding, currently this is being 584 //if this machine is behind DNAT/port forwarding, currently this is being
@@ -597,23 +586,34 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
597 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"]; 586 requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
598 requestData.headers["x-path-info"] = pathInfo; 587 requestData.headers["x-path-info"] = pathInfo;
599 requestData.headers["x-query-string"] = queryString; 588 requestData.headers["x-query-string"] = queryString;
600 requestData.headers["x-script-url"] = urlData.url; 589 requestData.headers["x-script-url"] = url.url;
601 590
602 urlData.requests.Add(requestID, requestData); 591 //requestData.ev = new ManualResetEvent(false);
603 m_RequestMap.Add(requestID, urlData); 592 lock (url.requests)
604 } 593 {
594 url.requests.Add(requestID, requestData);
595 }
596 lock (m_RequestMap)
597 {
598 //add to request map
599 m_RequestMap.Add(requestID, url);
600 }
605 601
606 urlData.engine.PostScriptEvent( 602 url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
607 urlData.itemID, 603
608 "http_request", 604 //send initial response?
609 new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() }); 605// Hashtable response = new Hashtable();
610 } 606
611 catch (Exception we) 607 return;
612 { 608
613 //Hashtable response = new Hashtable(); 609 }
614 m_log.Warn("[HttpRequestHandler]: http-in request failed"); 610 catch (Exception we)
615 m_log.Warn(we.Message); 611 {
616 m_log.Warn(we.StackTrace); 612 //Hashtable response = new Hashtable();
613 m_log.Warn("[HttpRequestHandler]: http-in request failed");
614 m_log.Warn(we.Message);
615 m_log.Warn(we.StackTrace);
616 }
617 } 617 }
618 } 618 }
619 619
@@ -622,4 +622,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
622 ScriptRemoved(itemID); 622 ScriptRemoved(itemID);
623 } 623 }
624 } 624 }
625} \ No newline at end of file 625}
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/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index 5641804..7ed1320 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;
@@ -232,4 +235,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
232 } 235 }
233 } 236 }
234 } 237 }
235} \ No newline at end of file 238}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 09a3bd6..6eb99ea 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)
@@ -308,14 +313,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
308 313
309 if (m_scenes.ContainsKey(destination.RegionID)) 314 if (m_scenes.ContainsKey(destination.RegionID))
310 { 315 {
311// m_log.DebugFormat(
312// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
313// s.RegionInfo.RegionName, destination.RegionHandle);
314
315 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); 316 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); });
316 return true; 317 return true;
317 } 318 }
318
319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
320 return false; 320 return false;
321 } 321 }
@@ -374,4 +374,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
374 374
375 #endregion 375 #endregion
376 } 376 }
377} \ No newline at end of file 377}
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 2b61800..619550c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -311,6 +311,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
311 // being no copy/no mod for everyone 311 // being no copy/no mod for everyone
312 lock (part.TaskInventory) 312 lock (part.TaskInventory)
313 { 313 {
314 if (!ResolveUserUuid(part.CreatorID))
315 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
316
317 if (!ResolveUserUuid(part.OwnerID))
318 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
319
320 if (!ResolveUserUuid(part.LastOwnerID))
321 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
322
323 // And zap any troublesome sit target information
324 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
325 part.SitTargetPosition = new Vector3(0, 0, 0);
326
327 // Fix ownership/creator of inventory items
328 // Not doing so results in inventory items
329 // being no copy/no mod for everyone
330 part.TaskInventory.LockItemsForRead(true);
314 TaskInventoryDictionary inv = part.TaskInventory; 331 TaskInventoryDictionary inv = part.TaskInventory;
315 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 332 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
316 { 333 {
@@ -326,6 +343,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
326 if (UserManager != null) 343 if (UserManager != null)
327 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); 344 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
328 } 345 }
346 part.TaskInventory.LockItemsForRead(false);
329 } 347 }
330 } 348 }
331 349
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 55110dc..1eb641d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -253,18 +253,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
253 253
254 if (asset != null) 254 if (asset != null)
255 { 255 {
256 if (m_options.ContainsKey("verbose")) 256// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
257 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
258
259 m_foundAssetUuids.Add(asset.FullID); 257 m_foundAssetUuids.Add(asset.FullID);
260 258
261 m_assetsArchiver.WriteAsset(PostProcess(asset)); 259 m_assetsArchiver.WriteAsset(PostProcess(asset));
262 } 260 }
263 else 261 else
264 { 262 {
265 if (m_options.ContainsKey("verbose")) 263// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id);
266 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
267
268 m_notFoundAssetUuids.Add(new UUID(id)); 264 m_notFoundAssetUuids.Add(new UUID(id));
269 } 265 }
270 266
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 58bbd24..fdef9d8 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;
@@ -47,6 +48,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
47 { 48 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
51 private Timer m_regionChangeTimer = new Timer();
50 public Scene Scene { get; private set; } 52 public Scene Scene { get; private set; }
51 public IUserManagement UserManager { get; private set; } 53 public IUserManagement UserManager { get; private set; }
52 54
@@ -59,8 +61,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
59 public event ChangeDelegate OnEstateInfoChange; 61 public event ChangeDelegate OnEstateInfoChange;
60 public event MessageDelegate OnEstateMessage; 62 public event MessageDelegate OnEstateMessage;
61 63
64 private int m_delayCount = 0;
65
62 #region Packet Data Responders 66 #region Packet Data Responders
63 67
68 private void clientSendDetailedEstateData(IClientAPI remote_client, UUID invoice)
69 {
70 sendDetailedEstateData(remote_client, invoice);
71 sendEstateLists(remote_client, invoice);
72 }
73
64 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) 74 private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice)
65 { 75 {
66 uint sun = 0; 76 uint sun = 0;
@@ -83,7 +93,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
83 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime, 93 (uint) Scene.RegionInfo.RegionSettings.CovenantChangedDateTime,
84 Scene.RegionInfo.EstateSettings.AbuseEmail, 94 Scene.RegionInfo.EstateSettings.AbuseEmail,
85 estateOwner); 95 estateOwner);
96 }
86 97
98 private void sendEstateLists(IClientAPI remote_client, UUID invoice)
99 {
87 remote_client.SendEstateList(invoice, 100 remote_client.SendEstateList(invoice,
88 (int)Constants.EstateAccessCodex.EstateManagers, 101 (int)Constants.EstateAccessCodex.EstateManagers,
89 Scene.RegionInfo.EstateSettings.EstateManagers, 102 Scene.RegionInfo.EstateSettings.EstateManagers,
@@ -257,6 +270,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
257 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); 270 IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>();
258 if (restartModule != null) 271 if (restartModule != null)
259 { 272 {
273 if (timeInSeconds == -1)
274 {
275 m_delayCount++;
276 if (m_delayCount > 3)
277 return;
278
279 restartModule.DelayRestart(3600, "Restart delayed by region manager");
280 return;
281 }
282
260 List<int> times = new List<int>(); 283 List<int> times = new List<int>();
261 while (timeInSeconds > 0) 284 while (timeInSeconds > 0)
262 { 285 {
@@ -269,7 +292,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
269 timeInSeconds -= 15; 292 timeInSeconds -= 15;
270 } 293 }
271 294
272 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); 295 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false);
273 } 296 }
274 } 297 }
275 298
@@ -477,7 +500,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
477 { 500 {
478 if (!s.IsChildAgent) 501 if (!s.IsChildAgent)
479 { 502 {
480 Scene.TeleportClientHome(user, s.ControllingClient); 503 if (!Scene.TeleportClientHome(user, s.ControllingClient))
504 {
505 s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out.");
506 s.ControllingClient.Close();
507 }
481 } 508 }
482 } 509 }
483 510
@@ -486,7 +513,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
486 { 513 {
487 remote_client.SendAlertMessage("User is already on the region ban list"); 514 remote_client.SendAlertMessage("User is already on the region ban list");
488 } 515 }
489 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 516 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
490 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 517 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
491 } 518 }
492 else 519 else
@@ -541,7 +568,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
541 remote_client.SendAlertMessage("User is not on the region ban list"); 568 remote_client.SendAlertMessage("User is not on the region ban list");
542 } 569 }
543 570
544 //m_scene.RegionInfo.regionBanlist.Add(Manager(user); 571 //Scene.RegionInfo.regionBanlist.Add(Manager(user);
545 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); 572 remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID);
546 } 573 }
547 else 574 else
@@ -700,7 +727,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
700 ScenePresence s = Scene.GetScenePresence(prey); 727 ScenePresence s = Scene.GetScenePresence(prey);
701 if (s != null) 728 if (s != null)
702 { 729 {
703 Scene.TeleportClientHome(prey, s.ControllingClient); 730 if (!Scene.TeleportClientHome(prey, s.ControllingClient))
731 {
732 s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
733 s.ControllingClient.Close();
734 }
704 } 735 }
705 } 736 }
706 } 737 }
@@ -718,7 +749,13 @@ namespace OpenSim.Region.CoreModules.World.Estate
718 // Also make sure they are actually in the region 749 // Also make sure they are actually in the region
719 ScenePresence p; 750 ScenePresence p;
720 if(Scene.TryGetScenePresence(client.AgentId, out p)) 751 if(Scene.TryGetScenePresence(client.AgentId, out p))
721 Scene.TeleportClientHome(p.UUID, p.ControllingClient); 752 {
753 if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient))
754 {
755 p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out.");
756 p.ControllingClient.Close();
757 }
758 }
722 } 759 }
723 }); 760 });
724 } 761 }
@@ -1081,6 +1118,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1081 1118
1082 public void AddRegion(Scene scene) 1119 public void AddRegion(Scene scene)
1083 { 1120 {
1121 m_regionChangeTimer.AutoReset = false;
1122 m_regionChangeTimer.Interval = 2000;
1123 m_regionChangeTimer.Elapsed += RaiseRegionInfoChange;
1124
1084 Scene = scene; 1125 Scene = scene;
1085 Scene.RegisterModuleInterface<IEstateModule>(this); 1126 Scene.RegisterModuleInterface<IEstateModule>(this);
1086 Scene.EventManager.OnNewClient += EventManager_OnNewClient; 1127 Scene.EventManager.OnNewClient += EventManager_OnNewClient;
@@ -1131,7 +1172,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1131 1172
1132 private void EventManager_OnNewClient(IClientAPI client) 1173 private void EventManager_OnNewClient(IClientAPI client)
1133 { 1174 {
1134 client.OnDetailedEstateDataRequest += sendDetailedEstateData; 1175 client.OnDetailedEstateDataRequest += clientSendDetailedEstateData;
1135 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler; 1176 client.OnSetEstateFlagsRequest += estateSetRegionInfoHandler;
1136// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture; 1177// client.OnSetEstateTerrainBaseTexture += setEstateTerrainBaseTexture;
1137 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture; 1178 client.OnSetEstateTerrainDetailTexture += setEstateTerrainBaseTexture;
@@ -1183,6 +1224,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
1183 flags |= RegionFlags.AllowParcelChanges; 1224 flags |= RegionFlags.AllowParcelChanges;
1184 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch) 1225 if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
1185 flags |= RegionFlags.BlockParcelSearch; 1226 flags |= RegionFlags.BlockParcelSearch;
1227 if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
1228 flags |= (RegionFlags)(1 << 11);
1229 if (Scene.RegionInfo.RegionSettings.Casino)
1230 flags |= (RegionFlags)(1 << 10);
1186 1231
1187 if (Scene.RegionInfo.RegionSettings.FixedSun) 1232 if (Scene.RegionInfo.RegionSettings.FixedSun)
1188 flags |= RegionFlags.SunFixed; 1233 flags |= RegionFlags.SunFixed;
@@ -1190,11 +1235,15 @@ namespace OpenSim.Region.CoreModules.World.Estate
1190 flags |= RegionFlags.Sandbox; 1235 flags |= RegionFlags.Sandbox;
1191 if (Scene.RegionInfo.EstateSettings.AllowVoice) 1236 if (Scene.RegionInfo.EstateSettings.AllowVoice)
1192 flags |= RegionFlags.AllowVoice; 1237 flags |= RegionFlags.AllowVoice;
1238 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1239 flags |= RegionFlags.AllowLandmark;
1240 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1241 flags |= RegionFlags.AllowSetHome;
1242 if (Scene.RegionInfo.EstateSettings.BlockDwell)
1243 flags |= RegionFlags.BlockDwell;
1244 if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
1245 flags |= RegionFlags.ResetHomeOnTeleport;
1193 1246
1194 // Fudge these to always on, so the menu options activate
1195 //
1196 flags |= RegionFlags.AllowLandmark;
1197 flags |= RegionFlags.AllowSetHome;
1198 1247
1199 // TODO: SkipUpdateInterestList 1248 // TODO: SkipUpdateInterestList
1200 1249
@@ -1235,6 +1284,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1235 flags |= RegionFlags.ResetHomeOnTeleport; 1284 flags |= RegionFlags.ResetHomeOnTeleport;
1236 if (Scene.RegionInfo.EstateSettings.TaxFree) 1285 if (Scene.RegionInfo.EstateSettings.TaxFree)
1237 flags |= RegionFlags.TaxFree; 1286 flags |= RegionFlags.TaxFree;
1287 if (Scene.RegionInfo.EstateSettings.AllowLandmark)
1288 flags |= RegionFlags.AllowLandmark;
1289 if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
1290 flags |= RegionFlags.AllowParcelChanges;
1291 if (Scene.RegionInfo.EstateSettings.AllowSetHome)
1292 flags |= RegionFlags.AllowSetHome;
1238 if (Scene.RegionInfo.EstateSettings.DenyMinors) 1293 if (Scene.RegionInfo.EstateSettings.DenyMinors)
1239 flags |= (RegionFlags)(1 << 30); 1294 flags |= (RegionFlags)(1 << 30);
1240 1295
@@ -1255,6 +1310,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
1255 1310
1256 public void TriggerRegionInfoChange() 1311 public void TriggerRegionInfoChange()
1257 { 1312 {
1313 m_regionChangeTimer.Stop();
1314 m_regionChangeTimer.Start();
1315 }
1316
1317 protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e)
1318 {
1258 ChangeDelegate change = OnRegionInfoChange; 1319 ChangeDelegate change = OnRegionInfoChange;
1259 1320
1260 if (change != null) 1321 if (change != null)
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 8b7406d..51dcb67 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -91,14 +91,13 @@ namespace OpenSim.Region.CoreModules.World.Land
91 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 91 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
92 92
93 private bool m_allowedForcefulBans = true; 93 private bool m_allowedForcefulBans = true;
94 private UUID DefaultGodParcelGroup;
95 private string DefaultGodParcelName;
94 96
95 // caches ExtendedLandData 97 // caches ExtendedLandData
96 private Cache parcelInfoCache; 98 private Cache parcelInfoCache;
97 99 private Dictionary<UUID, Vector3> forcedPosition =
98 /// <summary> 100 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 101
103 #region INonSharedRegionModule Members 102 #region INonSharedRegionModule Members
104 103
@@ -109,6 +108,12 @@ namespace OpenSim.Region.CoreModules.World.Land
109 108
110 public void Initialise(IConfigSource source) 109 public void Initialise(IConfigSource source)
111 { 110 {
111 IConfig cnf = source.Configs["LandManagement"];
112 if (cnf != null)
113 {
114 DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString()));
115 DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel");
116 }
112 } 117 }
113 118
114 public void AddRegion(Scene scene) 119 public void AddRegion(Scene scene)
@@ -160,13 +165,6 @@ namespace OpenSim.Region.CoreModules.World.Land
160 m_scene.UnregisterModuleCommander(m_commander.Name); 165 m_scene.UnregisterModuleCommander(m_commander.Name);
161 } 166 }
162 167
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> 168 /// <summary>
171 /// Processes commandline input. Do not call directly. 169 /// Processes commandline input. Do not call directly.
172 /// </summary> 170 /// </summary>
@@ -207,6 +205,8 @@ namespace OpenSim.Region.CoreModules.World.Land
207 client.OnParcelInfoRequest += ClientOnParcelInfoRequest; 205 client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
208 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; 206 client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
209 client.OnPreAgentUpdate += ClientOnPreAgentUpdate; 207 client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
208 client.OnParcelEjectUser += ClientOnParcelEjectUser;
209 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
210 210
211 EntityBase presenceEntity; 211 EntityBase presenceEntity;
212 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) 212 if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence)
@@ -218,48 +218,6 @@ namespace OpenSim.Region.CoreModules.World.Land
218 218
219 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 219 void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
220 { 220 {
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 } 221 }
264 222
265 public void Close() 223 public void Close()
@@ -378,10 +336,16 @@ namespace OpenSim.Region.CoreModules.World.Land
378 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) 336 private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position)
379 { 337 {
380 if (m_scene.Permissions.IsGod(avatar.UUID)) return; 338 if (m_scene.Permissions.IsGod(avatar.UUID)) return;
381 if (position.HasValue) 339
382 { 340 if (!position.HasValue)
383 forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; 341 return;
384 } 342
343 bool isFlying = avatar.PhysicsActor.Flying;
344 avatar.RemoveFromPhysicalScene();
345
346 avatar.AbsolutePosition = (Vector3)position;
347
348 avatar.AddToPhysicalScene(isFlying);
385 } 349 }
386 350
387 public void SendYouAreRestrictedNotice(ScenePresence avatar) 351 public void SendYouAreRestrictedNotice(ScenePresence avatar)
@@ -401,29 +365,7 @@ namespace OpenSim.Region.CoreModules.World.Land
401 } 365 }
402 366
403 if (parcelAvatarIsEntering != null) 367 if (parcelAvatarIsEntering != null)
404 { 368 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 } 369 }
428 } 370 }
429 371
@@ -527,6 +469,7 @@ namespace OpenSim.Region.CoreModules.World.Land
527 //when we are finally in a safe place, lets release the forced position lock 469 //when we are finally in a safe place, lets release the forced position lock
528 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); 470 forcedPosition.Remove(clientAvatar.ControllingClient.AgentId);
529 } 471 }
472 EnforceBans(parcel, clientAvatar);
530 } 473 }
531 } 474 }
532 475
@@ -735,7 +678,7 @@ namespace OpenSim.Region.CoreModules.World.Land
735 int x; 678 int x;
736 int y; 679 int y;
737 680
738 if (x_float >= Constants.RegionSize || x_float < 0 || y_float >= Constants.RegionSize || y_float < 0) 681 if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0)
739 return null; 682 return null;
740 683
741 try 684 try
@@ -785,14 +728,13 @@ namespace OpenSim.Region.CoreModules.World.Land
785 { 728 {
786 try 729 try
787 { 730 {
788 return m_landList[m_landIDList[x / 4, y / 4]]; 731 //if (m_landList.ContainsKey(m_landIDList[x / 4, y / 4]))
732 return m_landList[m_landIDList[x / 4, y / 4]];
733 //else
734 // return null;
789 } 735 }
790 catch (IndexOutOfRangeException) 736 catch (IndexOutOfRangeException)
791 { 737 {
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; 738 return null;
797 } 739 }
798 } 740 }
@@ -1075,6 +1017,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1075 //Owner Flag 1017 //Owner Flag
1076 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); 1018 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER);
1077 } 1019 }
1020 else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
1021 {
1022 tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP);
1023 }
1078 else if (currentParcelBlock.LandData.SalePrice > 0 && 1024 else if (currentParcelBlock.LandData.SalePrice > 0 &&
1079 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || 1025 (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
1080 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) 1026 currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
@@ -1155,8 +1101,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1155 { 1101 {
1156 if (!temp.Contains(currentParcel)) 1102 if (!temp.Contains(currentParcel))
1157 { 1103 {
1158 currentParcel.ForceUpdateLandInfo(); 1104 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId))
1159 temp.Add(currentParcel); 1105 {
1106 currentParcel.ForceUpdateLandInfo();
1107 temp.Add(currentParcel);
1108 }
1160 } 1109 }
1161 } 1110 }
1162 } 1111 }
@@ -1375,18 +1324,31 @@ namespace OpenSim.Region.CoreModules.World.Land
1375 1324
1376 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data) 1325 public void EventManagerOnIncomingLandDataFromStorage(List<LandData> data)
1377 { 1326 {
1378 for (int i = 0; i < data.Count; i++) 1327 lock (m_landList)
1379 { 1328 {
1380 IncomingLandObjectFromStorage(data[i]); 1329 //Remove all the land objects in the sim and then process our new data
1330 foreach (int n in m_landList.Keys)
1331 {
1332 m_scene.EventManager.TriggerLandObjectRemoved(m_landList[n].LandData.GlobalID);
1333 }
1334 m_landIDList.Initialize();
1335 m_landList.Clear();
1336
1337 for (int i = 0; i < data.Count; i++)
1338 {
1339 IncomingLandObjectFromStorage(data[i]);
1340 }
1381 } 1341 }
1382 } 1342 }
1383 1343
1384 public void IncomingLandObjectFromStorage(LandData data) 1344 public void IncomingLandObjectFromStorage(LandData data)
1385 { 1345 {
1346
1386 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); 1347 ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene);
1387 new_land.LandData = data.Copy(); 1348 new_land.LandData = data.Copy();
1388 new_land.SetLandBitmapFromByteArray(); 1349 new_land.SetLandBitmapFromByteArray();
1389 AddLandObject(new_land); 1350 AddLandObject(new_land);
1351 new_land.SendLandUpdateToAvatarsOverMe();
1390 } 1352 }
1391 1353
1392 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1354 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
@@ -1669,6 +1631,168 @@ namespace OpenSim.Region.CoreModules.World.Land
1669 1631
1670 UpdateLandObject(localID, land.LandData); 1632 UpdateLandObject(localID, land.LandData);
1671 } 1633 }
1634
1635 public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID)
1636 {
1637 ILandObject land = null;
1638 List<ILandObject> Land = ((Scene)client.Scene).LandChannel.AllParcels();
1639 foreach (ILandObject landObject in Land)
1640 {
1641 if (landObject.LandData.LocalID == landID)
1642 {
1643 land = landObject;
1644 }
1645 }
1646 land.DeedToGroup(DefaultGodParcelGroup);
1647 land.LandData.Name = DefaultGodParcelName;
1648 land.SendLandUpdateToAvatarsOverMe();
1649 }
1650
1651 private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID)
1652 {
1653 ScenePresence SP;
1654 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP);
1655 List<SceneObjectGroup> returns = new List<SceneObjectGroup>();
1656 if (SP.UserLevel != 0)
1657 {
1658 if (flags == 0) //All parcels, scripted or not
1659 {
1660 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1661 {
1662 if (e.OwnerID == targetID)
1663 {
1664 returns.Add(e);
1665 }
1666 }
1667 );
1668 }
1669 if (flags == 4) //All parcels, scripted object
1670 {
1671 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1672 {
1673 if (e.OwnerID == targetID)
1674 {
1675 if (e.ContainsScripts())
1676 {
1677 returns.Add(e);
1678 }
1679 }
1680 }
1681 );
1682 }
1683 if (flags == 4) //not target parcel, scripted object
1684 {
1685 ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e)
1686 {
1687 if (e.OwnerID == targetID)
1688 {
1689 ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y);
1690 if (landobject.LandData.OwnerID != e.OwnerID)
1691 {
1692 if (e.ContainsScripts())
1693 {
1694 returns.Add(e);
1695 }
1696 }
1697 }
1698 }
1699 );
1700 }
1701 foreach (SceneObjectGroup ol in returns)
1702 {
1703 ReturnObject(ol, client);
1704 }
1705 }
1706 }
1707 public void ReturnObject(SceneObjectGroup obj, IClientAPI client)
1708 {
1709 SceneObjectGroup[] objs = new SceneObjectGroup[1];
1710 objs[0] = obj;
1711 ((Scene)client.Scene).returnObjects(objs, client.AgentId);
1712 }
1713
1714 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
1715
1716 public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1717 {
1718 ScenePresence targetAvatar = null;
1719 ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar);
1720 ScenePresence parcelManager = null;
1721 ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager);
1722 System.Threading.Timer Timer;
1723
1724 if (targetAvatar.UserLevel == 0)
1725 {
1726 ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1727 if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze))
1728 return;
1729 if (flags == 0)
1730 {
1731 targetAvatar.AllowMovement = false;
1732 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world.");
1733 parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen.");
1734 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
1735 Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0);
1736 Timers.Add(targetAvatar.UUID, Timer);
1737 }
1738 else
1739 {
1740 targetAvatar.AllowMovement = true;
1741 targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you.");
1742 parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen.");
1743 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1744 Timers.Remove(targetAvatar.UUID);
1745 Timer.Dispose();
1746 }
1747 }
1748 }
1749 private void OnEndParcelFrozen(object avatar)
1750 {
1751 ScenePresence targetAvatar = (ScenePresence)avatar;
1752 targetAvatar.AllowMovement = true;
1753 System.Threading.Timer Timer;
1754 Timers.TryGetValue(targetAvatar.UUID, out Timer);
1755 Timers.Remove(targetAvatar.UUID);
1756 targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false);
1757 }
1758
1759
1760 public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
1761 {
1762 ScenePresence targetAvatar = null;
1763 ScenePresence parcelManager = null;
1764
1765 // Must have presences
1766 if (!m_scene.TryGetScenePresence(target, out targetAvatar) ||
1767 !m_scene.TryGetScenePresence(client.AgentId, out parcelManager))
1768 return;
1769
1770 // Cannot eject estate managers or gods
1771 if (m_scene.Permissions.IsAdministrator(target))
1772 return;
1773
1774 // Check if you even have permission to do this
1775 ILandObject land = m_scene.LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y);
1776 if (!m_scene.Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze) &&
1777 !m_scene.Permissions.IsAdministrator(client.AgentId))
1778 return;
1779
1780 Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land);
1781
1782 targetAvatar.TeleportWithMomentum(pos, null);
1783 targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname);
1784 parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected.");
1785
1786 if ((flags & 1) != 0) // Ban TODO: Remove magic number
1787 {
1788 LandAccessEntry entry = new LandAccessEntry();
1789 entry.AgentID = targetAvatar.UUID;
1790 entry.Flags = AccessList.Ban;
1791 entry.Expires = 0; // Perm
1792
1793 land.LandData.ParcelAccessList.Add(entry);
1794 }
1795 }
1672 1796
1673 protected void InstallInterfaces() 1797 protected void InstallInterfaces()
1674 { 1798 {
@@ -1731,5 +1855,27 @@ namespace OpenSim.Region.CoreModules.World.Land
1731 1855
1732 MainConsole.Instance.Output(report.ToString()); 1856 MainConsole.Instance.Output(report.ToString());
1733 } 1857 }
1858
1859 public void EnforceBans(ILandObject land, ScenePresence avatar)
1860 {
1861 if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT)
1862 return;
1863
1864 if (land.IsEitherBannedOrRestricted(avatar.UUID))
1865 {
1866 if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y)))
1867 {
1868 Vector3? pos = m_scene.GetNearestAllowedPosition(avatar);
1869 if (pos == null)
1870 m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient);
1871 else
1872 ForceAvatarToPosition(avatar, (Vector3)pos);
1873 }
1874 else
1875 {
1876 ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition);
1877 }
1878 }
1879 }
1734 } 1880 }
1735} 1881}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 0536f6e..4f06737 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Land
50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 private int m_expiryCounter = 0;
53 54
54 protected LandData m_landData = new LandData(); 55 protected LandData m_landData = new LandData();
55 protected Scene m_scene; 56 protected Scene m_scene;
@@ -135,6 +136,8 @@ namespace OpenSim.Region.CoreModules.World.Land
135 else 136 else
136 LandData.GroupID = UUID.Zero; 137 LandData.GroupID = UUID.Zero;
137 LandData.IsGroupOwned = is_group_owned; 138 LandData.IsGroupOwned = is_group_owned;
139
140 m_scene.EventManager.OnFrame += OnFrame;
138 } 141 }
139 142
140 #endregion 143 #endregion
@@ -193,10 +196,27 @@ namespace OpenSim.Region.CoreModules.World.Land
193 else 196 else
194 { 197 {
195 // Normal Calculations 198 // Normal Calculations
196 int parcelMax = (int)(((float)LandData.Area / 65536.0f) 199 int parcelMax = (int)((long)LandData.Area
197 * (float)m_scene.RegionInfo.ObjectCapacity 200 * (long)m_scene.RegionInfo.ObjectCapacity
198 * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 201 * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus
199 // TODO: The calculation of ObjectBonus should be refactored. It does still not work in the same manner as SL! 202 / 65536L);
203 //m_log.DebugFormat("Area: {0}, Capacity {1}, Bonus {2}, Parcel {3}", LandData.Area, m_scene.RegionInfo.ObjectCapacity, m_scene.RegionInfo.RegionSettings.ObjectBonus, parcelMax);
204 return parcelMax;
205 }
206 }
207
208 private int GetParcelBasePrimCount()
209 {
210 if (overrideParcelMaxPrimCount != null)
211 {
212 return overrideParcelMaxPrimCount(this);
213 }
214 else
215 {
216 // Normal Calculations
217 int parcelMax = (int)((long)LandData.Area
218 * (long)m_scene.RegionInfo.ObjectCapacity
219 / 65536L);
200 return parcelMax; 220 return parcelMax;
201 } 221 }
202 } 222 }
@@ -210,8 +230,9 @@ namespace OpenSim.Region.CoreModules.World.Land
210 else 230 else
211 { 231 {
212 //Normal Calculations 232 //Normal Calculations
213 int simMax = (int)(((float)LandData.SimwideArea / 65536.0f) 233 int simMax = (int)((long)LandData.SimwideArea
214 * (float)m_scene.RegionInfo.ObjectCapacity); 234 * (long)m_scene.RegionInfo.ObjectCapacity / 65536L);
235 // m_log.DebugFormat("Simwide Area: {0}, Capacity {1}, SimMax {2}", LandData.SimwideArea, m_scene.RegionInfo.ObjectCapacity, simMax);
215 return simMax; 236 return simMax;
216 } 237 }
217 } 238 }
@@ -248,7 +269,7 @@ namespace OpenSim.Region.CoreModules.World.Land
248 remote_client.SendLandProperties(seq_id, 269 remote_client.SendLandProperties(seq_id,
249 snap_selection, request_result, this, 270 snap_selection, request_result, this,
250 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 271 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
251 GetParcelMaxPrimCount(), 272 GetParcelBasePrimCount(),
252 GetSimulatorMaxPrimCount(), regionFlags); 273 GetSimulatorMaxPrimCount(), regionFlags);
253 } 274 }
254 275
@@ -308,7 +329,7 @@ namespace OpenSim.Region.CoreModules.World.Land
308 329
309 allowedDelta |= (uint)(ParcelFlags.ShowDirectory | 330 allowedDelta |= (uint)(ParcelFlags.ShowDirectory |
310 ParcelFlags.AllowPublish | 331 ParcelFlags.AllowPublish |
311 ParcelFlags.MaturePublish); 332 ParcelFlags.MaturePublish) | (uint)(1 << 23);
312 } 333 }
313 334
314 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) 335 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity))
@@ -1181,6 +1202,17 @@ namespace OpenSim.Region.CoreModules.World.Land
1181 1202
1182 #endregion 1203 #endregion
1183 1204
1205 private void OnFrame()
1206 {
1207 m_expiryCounter++;
1208
1209 if (m_expiryCounter >= 50)
1210 {
1211 ExpireAccessList();
1212 m_expiryCounter = 0;
1213 }
1214 }
1215
1184 private void ExpireAccessList() 1216 private void ExpireAccessList()
1185 { 1217 {
1186 List<LandAccessEntry> delete = new List<LandAccessEntry>(); 1218 List<LandAccessEntry> delete = new List<LandAccessEntry>();
@@ -1191,7 +1223,22 @@ namespace OpenSim.Region.CoreModules.World.Land
1191 delete.Add(entry); 1223 delete.Add(entry);
1192 } 1224 }
1193 foreach (LandAccessEntry entry in delete) 1225 foreach (LandAccessEntry entry in delete)
1226 {
1194 LandData.ParcelAccessList.Remove(entry); 1227 LandData.ParcelAccessList.Remove(entry);
1228 ScenePresence presence;
1229
1230 if (m_scene.TryGetScenePresence(entry.AgentID, out presence) && (!presence.IsChildAgent))
1231 {
1232 ILandObject land = m_scene.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
1233 if (land.LandData.LocalID == LandData.LocalID)
1234 {
1235 Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land);
1236 presence.TeleportWithMomentum(pos, null);
1237 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
1238 }
1239 }
1240 m_log.DebugFormat("[LAND]: Removing entry {0} because it has expired", entry.AgentID);
1241 }
1195 1242
1196 if (delete.Count > 0) 1243 if (delete.Count > 0)
1197 m_scene.EventManager.TriggerLandObjectUpdated((uint)LandData.LocalID, this); 1244 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 b2f71d1..102b4d7 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 3f848ed..402b9fb 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -636,6 +636,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
636 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); 636 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
637 m_scene.SaveTerrain(); 637 m_scene.SaveTerrain();
638 638
639 m_scene.EventManager.TriggerTerrainUpdate();
640
639 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. 641 // Clients who look at the map will never see changes after they looked at the map, so i've commented this out.
640 //m_scene.CreateTerrainTexture(true); 642 //m_scene.CreateTerrainTexture(true);
641 } 643 }
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 9002a9f..3c48d07 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)
@@ -673,4 +687,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
673 return result; 687 return result;
674 } 688 }
675 } 689 }
676} \ No newline at end of file 690}
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 724533b..309856f 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -63,7 +63,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
63 private static readonly UUID STOP_UUID = UUID.Random(); 63 private static readonly UUID STOP_UUID = UUID.Random();
64 private static readonly string m_mapLayerPath = "0001/"; 64 private static readonly string m_mapLayerPath = "0001/";
65 65
66 private OpenSim.Framework.BlockingQueue<MapRequestState> requests = new OpenSim.Framework.BlockingQueue<MapRequestState>(); 66 private ManualResetEvent queueEvent = new ManualResetEvent(false);
67 private Queue<MapRequestState> requests = new Queue<MapRequestState>();
68
69 private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false);
70 private Dictionary<UUID, Queue<MapBlockRequestData>> m_mapBlockRequests = new Dictionary<UUID, Queue<MapBlockRequestData>>();
67 71
68 protected Scene m_scene; 72 protected Scene m_scene;
69 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>(); 73 private List<MapBlockData> cachedMapBlocks = new List<MapBlockData>();
@@ -71,7 +75,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
71 private int blacklistTimeout = 10*60*1000; // 10 minutes 75 private int blacklistTimeout = 10*60*1000; // 10 minutes
72 private byte[] myMapImageJPEG; 76 private byte[] myMapImageJPEG;
73 protected volatile bool m_Enabled = false; 77 protected volatile bool m_Enabled = false;
74 private Dictionary<UUID, MapRequestState> m_openRequests = new Dictionary<UUID, MapRequestState>();
75 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>(); 78 private Dictionary<string, int> m_blacklistedurls = new Dictionary<string, int>();
76 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>(); 79 private Dictionary<ulong, int> m_blacklistedregions = new Dictionary<ulong, int>();
77 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>(); 80 private Dictionary<ulong, string> m_cachedRegionMapItemsAddress = new Dictionary<ulong, string>();
@@ -228,54 +231,54 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
228 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is 231 // 6/8/2011 -- I'm adding an explicit 2048 check, so that we never forget that there is
229 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks. 232 // a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
230 233
231 if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048) 234 //if (m_scene.RegionInfo.RegionLocX >= 2048 || m_scene.RegionInfo.RegionLocY >= 2048)
232 { 235 //{
233 ScenePresence avatarPresence = null; 236 // ScenePresence avatarPresence = null;
234 237
235 m_scene.TryGetScenePresence(agentID, out avatarPresence); 238 // m_scene.TryGetScenePresence(agentID, out avatarPresence);
236 239
237 if (avatarPresence != null) 240 // if (avatarPresence != null)
238 { 241 // {
239 bool lookup = false; 242 // bool lookup = false;
240 243
241 lock (cachedMapBlocks) 244 // lock (cachedMapBlocks)
242 { 245 // {
243 if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch())) 246 // if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
244 { 247 // {
245 List<MapBlockData> mapBlocks; 248 // List<MapBlockData> mapBlocks;
246 249
247 mapBlocks = cachedMapBlocks; 250 // mapBlocks = cachedMapBlocks;
248 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 251 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
249 } 252 // }
250 else 253 // else
251 { 254 // {
252 lookup = true; 255 // lookup = true;
253 } 256 // }
254 } 257 // }
255 if (lookup) 258 // if (lookup)
256 { 259 // {
257 List<MapBlockData> mapBlocks = new List<MapBlockData>(); ; 260 // List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
258 261
259 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 262 // List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
260 (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize, 263 // (int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
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.RegionLocY - 8) * (int)Constants.RegionSize, 265 // (int)(m_scene.RegionInfo.RegionLocY - 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 foreach (GridRegion r in regions) 267 // foreach (GridRegion r in regions)
265 { 268 // {
266 MapBlockData block = new MapBlockData(); 269 // MapBlockData block = new MapBlockData();
267 MapBlockFromGridRegion(block, r, 0); 270 // MapBlockFromGridRegion(block, r, 0);
268 mapBlocks.Add(block); 271 // mapBlocks.Add(block);
269 } 272 // }
270 avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); 273 // avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
271 274
272 lock (cachedMapBlocks) 275 // lock (cachedMapBlocks)
273 cachedMapBlocks = mapBlocks; 276 // cachedMapBlocks = mapBlocks;
274 277
275 cachedTime = Util.UnixTimeSinceEpoch(); 278 // cachedTime = Util.UnixTimeSinceEpoch();
276 } 279 // }
277 } 280 // }
278 } 281 //}
279 282
280 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); 283 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
281 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse()); 284 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
@@ -302,8 +305,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
302 protected static OSDMapLayer GetOSDMapLayerResponse() 305 protected static OSDMapLayer GetOSDMapLayerResponse()
303 { 306 {
304 OSDMapLayer mapLayer = new OSDMapLayer(); 307 OSDMapLayer mapLayer = new OSDMapLayer();
305 mapLayer.Right = 5000; 308 mapLayer.Right = 2048;
306 mapLayer.Top = 5000; 309 mapLayer.Top = 2048;
307 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006"); 310 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
308 311
309 return mapLayer; 312 return mapLayer;
@@ -332,6 +335,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
332 { 335 {
333 m_rootAgents.Remove(AgentId); 336 m_rootAgents.Remove(AgentId);
334 } 337 }
338 lock (m_mapBlockRequestEvent)
339 {
340 if (m_mapBlockRequests.ContainsKey(AgentId))
341 m_mapBlockRequests.Remove(AgentId);
342 }
335 } 343 }
336 #endregion 344 #endregion
337 345
@@ -354,6 +362,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
354 ThreadPriority.BelowNormal, 362 ThreadPriority.BelowNormal,
355 true, 363 true,
356 true); 364 true);
365 Watchdog.StartThread(
366 MapBlockSendThread,
367 string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
368 ThreadPriority.BelowNormal,
369 true,
370 true);
357 } 371 }
358 372
359 /// <summary> 373 /// <summary>
@@ -369,7 +383,27 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
369 st.itemtype=0; 383 st.itemtype=0;
370 st.regionhandle=0; 384 st.regionhandle=0;
371 385
372 requests.Enqueue(st); 386 lock (requests)
387 {
388 queueEvent.Set();
389 requests.Enqueue(st);
390 }
391
392 MapBlockRequestData req = new MapBlockRequestData();
393
394 req.client = null;
395 req.minX = 0;
396 req.maxX = 0;
397 req.minY = 0;
398 req.maxY = 0;
399 req.flags = 0;
400
401 lock (m_mapBlockRequestEvent)
402 {
403 m_mapBlockRequests[UUID.Zero] = new Queue<MapBlockRequestData>();
404 m_mapBlockRequests[UUID.Zero].Enqueue(req);
405 m_mapBlockRequestEvent.Set();
406 }
373 } 407 }
374 408
375 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, 409 public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
@@ -525,7 +559,21 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
525 { 559 {
526 while (true) 560 while (true)
527 { 561 {
528 MapRequestState st = requests.Dequeue(1000); 562 MapRequestState st = new MapRequestState();
563 bool valid = false;
564 queueEvent.WaitOne();
565 lock (requests)
566 {
567 if (requests.Count > 0)
568 {
569 st = requests.Dequeue();
570 valid = true;
571 }
572 if (requests.Count == 0)
573 queueEvent.Reset();
574 }
575 if (!valid)
576 continue;
529 577
530 // end gracefully 578 // end gracefully
531 if (st.agentID == STOP_UUID) 579 if (st.agentID == STOP_UUID)
@@ -543,13 +591,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
543 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle)) 591 if (dorequest && !m_blacklistedregions.ContainsKey(st.regionhandle))
544 { 592 {
545 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break 593 while (nAsyncRequests >= MAX_ASYNC_REQUESTS) // hit the break
546 Thread.Sleep(80); 594 Thread.Sleep(100);
547 595
548 RequestMapItemsDelegate d = RequestMapItemsAsync;
549 d.BeginInvoke(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle, RequestMapItemsCompleted, null);
550 //OSDMap response = RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
551 //RequestMapItemsCompleted(response);
552 Interlocked.Increment(ref nAsyncRequests); 596 Interlocked.Increment(ref nAsyncRequests);
597 Util.FireAndForget(x =>
598 {
599 RequestMapItemsAsync(st.agentID, st.flags, st.EstateID, st.godlike, st.itemtype, st.regionhandle);
600 });
553 } 601 }
554 } 602 }
555 603
@@ -571,110 +619,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
571 /// <param name="state"></param> 619 /// <param name="state"></param>
572 public void EnqueueMapItemRequest(MapRequestState state) 620 public void EnqueueMapItemRequest(MapRequestState state)
573 { 621 {
574 requests.Enqueue(state); 622 lock (requests)
575 }
576
577 /// <summary>
578 /// Sends the mapitem response to the IClientAPI
579 /// </summary>
580 /// <param name="response">The OSDMap Response for the mapitem</param>
581 private void RequestMapItemsCompleted(IAsyncResult iar)
582 {
583 AsyncResult result = (AsyncResult)iar;
584 RequestMapItemsDelegate icon = (RequestMapItemsDelegate)result.AsyncDelegate;
585
586 OSDMap response = (OSDMap)icon.EndInvoke(iar);
587
588 Interlocked.Decrement(ref nAsyncRequests);
589
590 if (!response.ContainsKey("requestID"))
591 return;
592
593 UUID requestID = response["requestID"].AsUUID();
594
595 if (requestID != UUID.Zero)
596 { 623 {
597 MapRequestState mrs = new MapRequestState(); 624 queueEvent.Set();
598 mrs.agentID = UUID.Zero; 625 requests.Enqueue(state);
599 lock (m_openRequests)
600 {
601 if (m_openRequests.ContainsKey(requestID))
602 {
603 mrs = m_openRequests[requestID];
604 m_openRequests.Remove(requestID);
605 }
606 }
607
608 if (mrs.agentID != UUID.Zero)
609 {
610 ScenePresence av = null;
611 m_scene.TryGetScenePresence(mrs.agentID, out av);
612 if (av != null)
613 {
614 if (response.ContainsKey(mrs.itemtype.ToString()))
615 {
616 List<mapItemReply> returnitems = new List<mapItemReply>();
617 OSDArray itemarray = (OSDArray)response[mrs.itemtype.ToString()];
618 for (int i = 0; i < itemarray.Count; i++)
619 {
620 OSDMap mapitem = (OSDMap)itemarray[i];
621 mapItemReply mi = new mapItemReply();
622 mi.x = (uint)mapitem["X"].AsInteger();
623 mi.y = (uint)mapitem["Y"].AsInteger();
624 mi.id = mapitem["ID"].AsUUID();
625 mi.Extra = mapitem["Extra"].AsInteger();
626 mi.Extra2 = mapitem["Extra2"].AsInteger();
627 mi.name = mapitem["Name"].AsString();
628 returnitems.Add(mi);
629 }
630 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), mrs.itemtype, mrs.flags);
631 }
632
633 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
634 uint itemtype = 7;
635
636 if (response.ContainsKey(itemtype.ToString()))
637 {
638 List<mapItemReply> returnitems = new List<mapItemReply>();
639 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
640 for (int i = 0; i < itemarray.Count; i++)
641 {
642 OSDMap mapitem = (OSDMap)itemarray[i];
643 mapItemReply mi = new mapItemReply();
644 mi.x = (uint)mapitem["X"].AsInteger();
645 mi.y = (uint)mapitem["Y"].AsInteger();
646 mi.id = mapitem["ID"].AsUUID();
647 mi.Extra = mapitem["Extra"].AsInteger();
648 mi.Extra2 = mapitem["Extra2"].AsInteger();
649 mi.name = mapitem["Name"].AsString();
650 returnitems.Add(mi);
651 }
652 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
653 }
654
655 // Service 1 (MAP_ITEM_TELEHUB)
656 itemtype = 1;
657
658 if (response.ContainsKey(itemtype.ToString()))
659 {
660 List<mapItemReply> returnitems = new List<mapItemReply>();
661 OSDArray itemarray = (OSDArray)response[itemtype.ToString()];
662 for (int i = 0; i < itemarray.Count; i++)
663 {
664 OSDMap mapitem = (OSDMap)itemarray[i];
665 mapItemReply mi = new mapItemReply();
666 mi.x = (uint)mapitem["X"].AsInteger();
667 mi.y = (uint)mapitem["Y"].AsInteger();
668 mi.id = mapitem["ID"].AsUUID();
669 mi.Extra = mapitem["Extra"].AsInteger();
670 mi.Extra2 = mapitem["Extra2"].AsInteger();
671 mi.name = mapitem["Name"].AsString();
672 returnitems.Add(mi);
673 }
674 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags);
675 }
676 }
677 }
678 } 626 }
679 } 627 }
680 628
@@ -701,8 +649,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
701 EnqueueMapItemRequest(st); 649 EnqueueMapItemRequest(st);
702 } 650 }
703 651
704 private delegate OSDMap RequestMapItemsDelegate(UUID id, uint flags,
705 uint EstateID, bool godlike, uint itemtype, ulong regionhandle);
706 /// <summary> 652 /// <summary>
707 /// Does the actual remote mapitem request 653 /// Does the actual remote mapitem request
708 /// This should be called from an asynchronous thread 654 /// This should be called from an asynchronous thread
@@ -717,7 +663,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
717 /// <param name="itemtype">passed in from packet</param> 663 /// <param name="itemtype">passed in from packet</param>
718 /// <param name="regionhandle">Region we're looking up</param> 664 /// <param name="regionhandle">Region we're looking up</param>
719 /// <returns></returns> 665 /// <returns></returns>
720 private OSDMap RequestMapItemsAsync(UUID id, uint flags, 666 private void RequestMapItemsAsync(UUID id, uint flags,
721 uint EstateID, bool godlike, uint itemtype, ulong regionhandle) 667 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
722 { 668 {
723// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype); 669// m_log.DebugFormat("[WORLDMAP]: RequestMapItemsAsync; region handle: {0} {1}", regionhandle, itemtype);
@@ -740,7 +686,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
740 } 686 }
741 687
742 if (blacklisted) 688 if (blacklisted)
743 return new OSDMap(); 689 {
690 Interlocked.Decrement(ref nAsyncRequests);
691 return;
692 }
744 693
745 UUID requestID = UUID.Random(); 694 UUID requestID = UUID.Random();
746 lock (m_cachedRegionMapItemsAddress) 695 lock (m_cachedRegionMapItemsAddress)
@@ -748,6 +697,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
748 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle)) 697 if (m_cachedRegionMapItemsAddress.ContainsKey(regionhandle))
749 httpserver = m_cachedRegionMapItemsAddress[regionhandle]; 698 httpserver = m_cachedRegionMapItemsAddress[regionhandle];
750 } 699 }
700
751 if (httpserver.Length == 0) 701 if (httpserver.Length == 0)
752 { 702 {
753 uint x = 0, y = 0; 703 uint x = 0, y = 0;
@@ -792,18 +742,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
792 742
793 // Can't find the http server 743 // Can't find the http server
794 if (httpserver.Length == 0 || blacklisted) 744 if (httpserver.Length == 0 || blacklisted)
795 return new OSDMap(); 745 {
796 746 Interlocked.Decrement(ref nAsyncRequests);
797 MapRequestState mrs = new MapRequestState(); 747 return;
798 mrs.agentID = id; 748 }
799 mrs.EstateID = EstateID;
800 mrs.flags = flags;
801 mrs.godlike = godlike;
802 mrs.itemtype=itemtype;
803 mrs.regionhandle = regionhandle;
804
805 lock (m_openRequests)
806 m_openRequests.Add(requestID, mrs);
807 749
808 WebRequest mapitemsrequest = null; 750 WebRequest mapitemsrequest = null;
809 try 751 try
@@ -813,7 +755,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
813 catch (Exception e) 755 catch (Exception e)
814 { 756 {
815 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e); 757 m_log.DebugFormat("[WORLD MAP]: Access to {0} failed with {1}", httpserver, e);
816 return new OSDMap(); 758 Interlocked.Decrement(ref nAsyncRequests);
759 return;
817 } 760 }
818 761
819 mapitemsrequest.Method = "POST"; 762 mapitemsrequest.Method = "POST";
@@ -838,7 +781,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
838 catch (WebException ex) 781 catch (WebException ex)
839 { 782 {
840 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message); 783 m_log.WarnFormat("[WORLD MAP]: Bad send on GetMapItems {0}", ex.Message);
841 responseMap["connect"] = OSD.FromBoolean(false);
842 lock (m_blacklistedurls) 784 lock (m_blacklistedurls)
843 { 785 {
844 if (!m_blacklistedurls.ContainsKey(httpserver)) 786 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -847,13 +789,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
847 789
848 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 790 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
849 791
850 return responseMap; 792 Interlocked.Decrement(ref nAsyncRequests);
793 return;
851 } 794 }
852 catch 795 catch
853 { 796 {
854 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 797 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
855 responseMap["connect"] = OSD.FromBoolean(false); 798 Interlocked.Decrement(ref nAsyncRequests);
856 return responseMap; 799 return;
857 } 800 }
858 finally 801 finally
859 { 802 {
@@ -874,12 +817,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
874 } 817 }
875 else 818 else
876 { 819 {
877 return new OSDMap(); 820 Interlocked.Decrement(ref nAsyncRequests);
821 return;
878 } 822 }
879 } 823 }
880 catch (WebException) 824 catch (WebException)
881 { 825 {
882 responseMap["connect"] = OSD.FromBoolean(false);
883 lock (m_blacklistedurls) 826 lock (m_blacklistedurls)
884 { 827 {
885 if (!m_blacklistedurls.ContainsKey(httpserver)) 828 if (!m_blacklistedurls.ContainsKey(httpserver))
@@ -888,19 +831,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
888 831
889 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver); 832 m_log.WarnFormat("[WORLD MAP]: Blacklisted {0}", httpserver);
890 833
891 return responseMap; 834 Interlocked.Decrement(ref nAsyncRequests);
835 return;
892 } 836 }
893 catch 837 catch
894 { 838 {
895 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver); 839 m_log.DebugFormat("[WORLD MAP]: RequestMapItems failed for {0}", httpserver);
896 responseMap["connect"] = OSD.FromBoolean(false);
897 lock (m_blacklistedregions) 840 lock (m_blacklistedregions)
898 { 841 {
899 if (!m_blacklistedregions.ContainsKey(regionhandle)) 842 if (!m_blacklistedregions.ContainsKey(regionhandle))
900 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 843 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
901 } 844 }
902 845
903 return responseMap; 846 Interlocked.Decrement(ref nAsyncRequests);
847 return;
904 } 848 }
905 finally 849 finally
906 { 850 {
@@ -919,14 +863,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
919 catch (Exception ex) 863 catch (Exception ex)
920 { 864 {
921 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message); 865 m_log.InfoFormat("[WORLD MAP]: exception on parse of RequestMapItems reply from {0}: {1}", httpserver, ex.Message);
922 responseMap["connect"] = OSD.FromBoolean(false);
923 lock (m_blacklistedregions) 866 lock (m_blacklistedregions)
924 { 867 {
925 if (!m_blacklistedregions.ContainsKey(regionhandle)) 868 if (!m_blacklistedregions.ContainsKey(regionhandle))
926 m_blacklistedregions.Add(regionhandle, Environment.TickCount); 869 m_blacklistedregions.Add(regionhandle, Environment.TickCount);
927 } 870 }
928 871
929 return responseMap; 872 Interlocked.Decrement(ref nAsyncRequests);
873 return;
930 } 874 }
931 } 875 }
932 876
@@ -940,7 +884,78 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
940 } 884 }
941 } 885 }
942 886
943 return responseMap; 887 Interlocked.Decrement(ref nAsyncRequests);
888
889 if (id != UUID.Zero)
890 {
891 ScenePresence av = null;
892 m_scene.TryGetScenePresence(id, out av);
893 if (av != null)
894 {
895 if (responseMap.ContainsKey(itemtype.ToString()))
896 {
897 List<mapItemReply> returnitems = new List<mapItemReply>();
898 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
899 for (int i = 0; i < itemarray.Count; i++)
900 {
901 OSDMap mapitem = (OSDMap)itemarray[i];
902 mapItemReply mi = new mapItemReply();
903 mi.x = (uint)mapitem["X"].AsInteger();
904 mi.y = (uint)mapitem["Y"].AsInteger();
905 mi.id = mapitem["ID"].AsUUID();
906 mi.Extra = mapitem["Extra"].AsInteger();
907 mi.Extra2 = mapitem["Extra2"].AsInteger();
908 mi.name = mapitem["Name"].AsString();
909 returnitems.Add(mi);
910 }
911 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
912 }
913
914 // Service 7 (MAP_ITEM_LAND_FOR_SALE)
915 itemtype = 7;
916
917 if (responseMap.ContainsKey(itemtype.ToString()))
918 {
919 List<mapItemReply> returnitems = new List<mapItemReply>();
920 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
921 for (int i = 0; i < itemarray.Count; i++)
922 {
923 OSDMap mapitem = (OSDMap)itemarray[i];
924 mapItemReply mi = new mapItemReply();
925 mi.x = (uint)mapitem["X"].AsInteger();
926 mi.y = (uint)mapitem["Y"].AsInteger();
927 mi.id = mapitem["ID"].AsUUID();
928 mi.Extra = mapitem["Extra"].AsInteger();
929 mi.Extra2 = mapitem["Extra2"].AsInteger();
930 mi.name = mapitem["Name"].AsString();
931 returnitems.Add(mi);
932 }
933 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
934 }
935
936 // Service 1 (MAP_ITEM_TELEHUB)
937 itemtype = 1;
938
939 if (responseMap.ContainsKey(itemtype.ToString()))
940 {
941 List<mapItemReply> returnitems = new List<mapItemReply>();
942 OSDArray itemarray = (OSDArray)responseMap[itemtype.ToString()];
943 for (int i = 0; i < itemarray.Count; i++)
944 {
945 OSDMap mapitem = (OSDMap)itemarray[i];
946 mapItemReply mi = new mapItemReply();
947 mi.x = (uint)mapitem["X"].AsInteger();
948 mi.y = (uint)mapitem["Y"].AsInteger();
949 mi.id = mapitem["ID"].AsUUID();
950 mi.Extra = mapitem["Extra"].AsInteger();
951 mi.Extra2 = mapitem["Extra2"].AsInteger();
952 mi.name = mapitem["Name"].AsString();
953 returnitems.Add(mi);
954 }
955 av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, flags);
956 }
957 }
958 }
944 } 959 }
945 960
946 /// <summary> 961 /// <summary>
@@ -950,7 +965,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
950 /// <param name="minY"></param> 965 /// <param name="minY"></param>
951 /// <param name="maxX"></param> 966 /// <param name="maxX"></param>
952 /// <param name="maxY"></param> 967 /// <param name="maxY"></param>
953 public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 968 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
954 { 969 {
955 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag); 970 //m_log.ErrorFormat("[YYY] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
956 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible 971 if ((flag & 0x10000) != 0) // user clicked on qthe map a tile that isn't visible
@@ -1003,21 +1018,91 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1003 1018
1004 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) 1019 protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1005 { 1020 {
1021 MapBlockRequestData req = new MapBlockRequestData();
1022
1023 req.client = remoteClient;
1024 req.minX = minX;
1025 req.maxX = maxX;
1026 req.minY = minY;
1027 req.maxY = maxY;
1028 req.flags = flag;
1029
1030 lock (m_mapBlockRequestEvent)
1031 {
1032 if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
1033 m_mapBlockRequests[remoteClient.AgentId] = new Queue<MapBlockRequestData>();
1034 m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
1035 m_mapBlockRequestEvent.Set();
1036 }
1037
1038 return new List<MapBlockData>();
1039 }
1040
1041 protected void MapBlockSendThread()
1042 {
1043 while (true)
1044 {
1045 List<MapBlockRequestData> thisRunData = new List<MapBlockRequestData>();
1046
1047 m_mapBlockRequestEvent.WaitOne();
1048 lock (m_mapBlockRequestEvent)
1049 {
1050 int total = 0;
1051 foreach (Queue<MapBlockRequestData> q in m_mapBlockRequests.Values)
1052 {
1053 if (q.Count > 0)
1054 thisRunData.Add(q.Dequeue());
1055
1056 total += q.Count;
1057 }
1058
1059 if (total == 0)
1060 m_mapBlockRequestEvent.Reset();
1061 }
1062
1063 foreach (MapBlockRequestData req in thisRunData)
1064 {
1065 // Null client stops thread
1066 if (req.client == null)
1067 return;
1068
1069 GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
1070 }
1071
1072 Thread.Sleep(50);
1073 }
1074 }
1075
1076 protected virtual List<MapBlockData> GetAndSendBlocksInternal(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
1077 {
1078 List<MapBlockData> allBlocks = new List<MapBlockData>();
1006 List<MapBlockData> mapBlocks = new List<MapBlockData>(); 1079 List<MapBlockData> mapBlocks = new List<MapBlockData>();
1007 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, 1080 List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
1008 (minX - 4) * (int)Constants.RegionSize, 1081 minX * (int)Constants.RegionSize,
1009 (maxX + 4) * (int)Constants.RegionSize, 1082 maxX * (int)Constants.RegionSize,
1010 (minY - 4) * (int)Constants.RegionSize, 1083 minY * (int)Constants.RegionSize,
1011 (maxY + 4) * (int)Constants.RegionSize); 1084 maxY * (int)Constants.RegionSize);
1085// (minX - 4) * (int)Constants.RegionSize,
1086// (maxX + 4) * (int)Constants.RegionSize,
1087// (minY - 4) * (int)Constants.RegionSize,
1088// (maxY + 4) * (int)Constants.RegionSize);
1012 foreach (GridRegion r in regions) 1089 foreach (GridRegion r in regions)
1013 { 1090 {
1014 MapBlockData block = new MapBlockData(); 1091 MapBlockData block = new MapBlockData();
1015 MapBlockFromGridRegion(block, r, flag); 1092 MapBlockFromGridRegion(block, r, flag);
1016 mapBlocks.Add(block); 1093 mapBlocks.Add(block);
1094 allBlocks.Add(block);
1095 if (mapBlocks.Count >= 10)
1096 {
1097 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1098 mapBlocks.Clear();
1099 Thread.Sleep(50);
1100 }
1017 } 1101 }
1018 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); 1102 if (mapBlocks.Count > 0)
1103 remoteClient.SendMapBlock(mapBlocks, flag & 0xffff);
1019 1104
1020 return mapBlocks; 1105 return allBlocks;
1021 } 1106 }
1022 1107
1023 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) 1108 protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag)
@@ -1241,7 +1326,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1241 } 1326 }
1242 else 1327 else
1243 { 1328 {
1244 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1329 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1245 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1330 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1246 { 1331 {
1247 OSDMap responsemapdata = new OSDMap(); 1332 OSDMap responsemapdata = new OSDMap();
@@ -1417,6 +1502,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1417 { 1502 {
1418 m_rootAgents.Remove(avatar.UUID); 1503 m_rootAgents.Remove(avatar.UUID);
1419 } 1504 }
1505
1506 lock (m_mapBlockRequestEvent)
1507 {
1508 if (m_mapBlockRequests.ContainsKey(avatar.UUID))
1509 m_mapBlockRequests.Remove(avatar.UUID);
1510 }
1420 } 1511 }
1421 1512
1422 public void OnRegionUp(GridRegion otherRegion) 1513 public void OnRegionUp(GridRegion otherRegion)
@@ -1461,9 +1552,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1461 Color background = Color.FromArgb(0, 0, 0, 0); 1552 Color background = Color.FromArgb(0, 0, 0, 0);
1462 SolidBrush transparent = new SolidBrush(background); 1553 SolidBrush transparent = new SolidBrush(background);
1463 Graphics g = Graphics.FromImage(overlay); 1554 Graphics g = Graphics.FromImage(overlay);
1464 g.FillRectangle(transparent, 0, 0, 256, 256); 1555 g.FillRectangle(transparent, 0, 0, 255, 255);
1465 1556
1466 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1557 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1558 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1467 1559
1468 foreach (ILandObject land in parcels) 1560 foreach (ILandObject land in parcels)
1469 { 1561 {
@@ -1471,8 +1563,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1471 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1563 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1472 { 1564 {
1473 landForSale = true; 1565 landForSale = true;
1566
1567 bool[,] landBitmap = land.GetLandBitmap();
1568
1569 for (int x = 0 ; x < 64 ; x++)
1570 {
1571 for (int y = 0 ; y < 64 ; y++)
1572 {
1573 if (landBitmap[x, y])
1574 {
1575 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1576
1577 if (x > 0)
1578 {
1579 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1580 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1581 }
1582 if (y > 0)
1583 {
1584 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1585 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1586 }
1587 if (x < 63)
1588 {
1589 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1590 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1591 }
1592 if (y < 63)
1593 {
1594 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1595 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1596 }
1597 }
1598 }
1599 }
1474 1600
1475 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1601 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1476 } 1602 }
1477 } 1603 }
1478 1604
@@ -1484,15 +1610,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1484 1610
1485 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1611 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1486 1612
1487 for (int x = 0 ; x < 64 ; x++)
1488 {
1489 for (int y = 0 ; y < 64 ; y++)
1490 {
1491 if (saleBitmap[x, y])
1492 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1493 }
1494 }
1495
1496 try 1613 try
1497 { 1614 {
1498 return OpenJPEG.EncodeFromImage(overlay, true); 1615 return OpenJPEG.EncodeFromImage(overlay, true);
@@ -1514,4 +1631,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1514 public uint itemtype; 1631 public uint itemtype;
1515 public ulong regionhandle; 1632 public ulong regionhandle;
1516 } 1633 }
1634
1635 public struct MapBlockRequestData
1636 {
1637 public IClientAPI client;
1638 public int minX;
1639 public int minY;
1640 public int maxX;
1641 public int maxY;
1642 public uint flags;
1643 }
1517} 1644}