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.cs184
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs161
-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.cs171
-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/LightShare/LightShareModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs31
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs372
-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.cs12
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs50
41 files changed, 2014 insertions, 847 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 af30a8e..1fa5ec0 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, true, d);
195 } 241 }
196 catch (Exception e) 242 catch (Exception e)
197 { 243 {
@@ -244,7 +290,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
244 sp.ClearAttachments(); 290 sp.ClearAttachments();
245 } 291 }
246 292
247 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) 293 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData)
248 { 294 {
249 lock (sp.AttachmentsSyncLock) 295 lock (sp.AttachmentsSyncLock)
250 { 296 {
@@ -290,9 +336,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
290 attachPos = Vector3.Zero; 336 attachPos = Vector3.Zero;
291 } 337 }
292 338
339 if (useAttachData)
340 {
341 group.RootPart.RotationOffset = group.RootPart.AttachRotation;
342 attachPos = group.RootPart.AttachOffset;
343 if (attachmentPt == 0)
344 {
345 attachmentPt = group.RootPart.AttachPoint;
346 if (attachmentPt == 0)
347 {
348 attachmentPt = (uint)AttachmentPoint.LeftHand;
349 attachPos = Vector3.Zero;
350 }
351 }
352 else if (group.RootPart.AttachPoint != attachmentPt)
353 {
354 attachPos = Vector3.Zero;
355 }
356 }
293 group.AttachmentPoint = attachmentPt; 357 group.AttachmentPoint = attachmentPt;
294 group.AbsolutePosition = attachPos; 358 group.AbsolutePosition = attachPos;
295 359
296 // We also don't want to do any of the inventory operations for an NPC. 360 // We also don't want to do any of the inventory operations for an NPC.
297 if (sp.PresenceType != PresenceType.Npc) 361 if (sp.PresenceType != PresenceType.Npc)
298 { 362 {
@@ -325,6 +389,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
325 } 389 }
326 390
327 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 391 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
392 {
393 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, true, null);
394 }
395
396 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
328 { 397 {
329 if (!Enabled) 398 if (!Enabled)
330 return null; 399 return null;
@@ -363,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
363 return null; 432 return null;
364 } 433 }
365 434
366 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 435 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
367 } 436 }
368 437
369 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 438 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -422,7 +491,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
422 so.AttachedAvatar = UUID.Zero; 491 so.AttachedAvatar = UUID.Zero;
423 rootPart.SetParentLocalId(0); 492 rootPart.SetParentLocalId(0);
424 so.ClearPartAttachmentData(); 493 so.ClearPartAttachmentData();
425 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 494 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
426 so.HasGroupChanged = true; 495 so.HasGroupChanged = true;
427 rootPart.Rezzed = DateTime.Now; 496 rootPart.Rezzed = DateTime.Now;
428 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 497 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -652,16 +721,79 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
652 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", 721 // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
653 // grp.Name, grp.LocalId, remoteClient.Name); 722 // grp.Name, grp.LocalId, remoteClient.Name);
654 723
655 InventoryItemBase newItem = m_invAccessModule.CopyToInventory( 724// Vector3 inventoryStoredPosition = new Vector3
656 DeRezAction.TakeCopy, 725// (((grp.AbsolutePosition.X > (int)Constants.RegionSize)
657 m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, 726// ? (float)Constants.RegionSize - 6
658 new List<SceneObjectGroup> { grp }, 727// : grp.AbsolutePosition.X)
659 sp.ControllingClient, true)[0]; 728// ,
729// (grp.AbsolutePosition.Y > (int)Constants.RegionSize)
730// ? (float)Constants.RegionSize - 6
731// : grp.AbsolutePosition.Y,
732// grp.AbsolutePosition.Z);
733//
734// Vector3 originalPosition = grp.AbsolutePosition;
735//
736// grp.AbsolutePosition = inventoryStoredPosition;
737
738 // If we're being called from a script, then trying to serialize that same script's state will not complete
739 // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
740 // the client/server crashes rather than logging out normally, the attachment's scripts will resume
741 // without state on relog. Arguably, this is what we want anyway.
742 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
743
744// grp.AbsolutePosition = originalPosition;
745
746 AssetBase asset = m_scene.CreateAsset(
747 grp.GetPartName(grp.LocalId),
748 grp.GetPartDescription(grp.LocalId),
749 (sbyte)AssetType.Object,
750 Utils.StringToBytes(sceneObjectXml),
751 sp.UUID);
752
753 m_scene.AssetService.Store(asset);
754
755 InventoryItemBase item = new InventoryItemBase();
756 item.CreatorId = grp.RootPart.CreatorID.ToString();
757 item.CreatorData = grp.RootPart.CreatorData;
758 item.Owner = sp.UUID;
759 item.ID = UUID.Random();
760 item.AssetID = asset.FullID;
761 item.Description = asset.Description;
762 item.Name = asset.Name;
763 item.AssetType = asset.Type;
764 item.InvType = (int)InventoryType.Object;
765
766 InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
767 if (folder != null)
768 item.Folder = folder.ID;
769 else // oopsies
770 item.Folder = UUID.Zero;
771
772 // Nix the special bits we used to use for slam and the folded perms
773 uint allowablePermissionsMask = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move);
774
775 if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
776 {
777 item.BasePermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask;
778 item.CurrentPermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask;
779 item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask;
780 item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask;
781 item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask;
782 }
783 else
784 {
785 item.BasePermissions = grp.RootPart.BaseMask & allowablePermissionsMask;
786 item.CurrentPermissions = grp.RootPart.OwnerMask & allowablePermissionsMask;
787 item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask;
788 item.EveryOnePermissions = grp.RootPart.EveryoneMask & allowablePermissionsMask;
789 item.GroupPermissions = grp.RootPart.GroupMask & allowablePermissionsMask;
790 }
791 item.CreationDate = Util.UnixTimeSinceEpoch();
660 792
661 // sets itemID so client can show item as 'attached' in inventory 793 // sets itemID so client can show item as 'attached' in inventory
662 grp.FromItemID = newItem.ID; 794 grp.FromItemID = item.ID;
663 795
664 return newItem; 796 return item;
665 } 797 }
666 798
667 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) 799 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
@@ -681,8 +813,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
681 UpdateKnownItem(sp, so, true); 813 UpdateKnownItem(sp, so, true);
682 } 814 }
683 815
684 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 816 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
685 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 817 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
686 { 818 {
687 if (m_invAccessModule == null) 819 if (m_invAccessModule == null)
688 return null; 820 return null;
@@ -700,10 +832,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
700 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 832 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
701 false, false, sp.UUID, true); 833 false, false, sp.UUID, true);
702 834
703 // m_log.DebugFormat( 835// m_log.DebugFormat(
704 // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", 836// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
705 // objatt.Name, remoteClient.Name, AttachmentPt); 837// objatt.Name, remoteClient.Name, AttachmentPt);
706 838
707 if (objatt != null) 839 if (objatt != null)
708 { 840 {
709 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 841 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
@@ -715,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
715 // This will throw if the attachment fails 847 // This will throw if the attachment fails
716 try 848 try
717 { 849 {
718 AttachObject(sp, objatt, attachmentPt, false); 850 AttachObject(sp, objatt, attachmentPt, false, false);
719 } 851 }
720 catch (Exception e) 852 catch (Exception e)
721 { 853 {
@@ -728,10 +860,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
728 m_scene.DeleteSceneObject(objatt, false); 860 m_scene.DeleteSceneObject(objatt, false);
729 return null; 861 return null;
730 } 862 }
731 863
732 if (tainted) 864 if (tainted)
733 objatt.HasGroupChanged = true; 865 objatt.HasGroupChanged = true;
734 866
867 if (doc != null)
868 {
869 objatt.LoadScriptState(doc);
870 objatt.ResetOwnerChangeFlag();
871 }
872
735 // Fire after attach, so we don't get messy perms dialogs 873 // Fire after attach, so we don't get messy perms dialogs
736 // 4 == AttachedRez 874 // 4 == AttachedRez
737 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 875 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
@@ -749,7 +887,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
749 itemID, sp.Name, attachmentPt); 887 itemID, sp.Name, attachmentPt);
750 } 888 }
751 } 889 }
752 890
753 return null; 891 return null;
754 } 892 }
755 893
@@ -863,7 +1001,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
863 AttachmentPt &= 0x7f; 1001 AttachmentPt &= 0x7f;
864 1002
865 // Calls attach with a Zero position 1003 // Calls attach with a Zero position
866 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) 1004 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true))
867 { 1005 {
868// m_log.Debug( 1006// m_log.Debug(
869// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 1007// "[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 b0c087f..df99d0c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
124 124
125 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID).ParentGroup; 125 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID).ParentGroup;
126 126
127 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false); 127 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
128 128
129 // Check status on scene presence 129 // Check status on scene presence
130 Assert.That(sp.HasAttachments(), Is.True); 130 Assert.That(sp.HasAttachments(), Is.True);
@@ -435,4 +435,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
435// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects"); 435// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
436// } 436// }
437 } 437 }
438} \ No newline at end of file 438}
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..bc42fd1 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,10 +349,11 @@ 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 llRegionSay to child agents. Send normal chat because you
336 if (presence.IsChildAgent) return false; 355 // can't talk across sim borders if it's not done
356 if (type == ChatTypeEnum.Broadcast && presence.IsChildAgent) return false;
337 357
338 Vector3 fromRegionPos = fromPos + regionPos; 358 Vector3 fromRegionPos = fromPos + regionPos;
339 Vector3 toRegionPos = presence.AbsolutePosition + 359 Vector3 toRegionPos = presence.AbsolutePosition +
@@ -341,15 +361,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
341 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 361 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
342 362
343 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 363 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
344 364
345 if (!ignoreDistance) 365 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
366 type == ChatTypeEnum.Say && dis > m_saydistance ||
367 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
346 { 368 {
347 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 369 return false;
348 type == ChatTypeEnum.Say && dis > m_saydistance ||
349 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
350 {
351 return false;
352 }
353 } 370 }
354 371
355 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 372 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
@@ -358,5 +375,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
358 375
359 return true; 376 return true;
360 } 377 }
378
379 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
380 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
381 {
382 System.Threading.Timer Timer;
383 if (flags == 0)
384 {
385 FreezeCache.Add(target.ToString());
386 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
387 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
388 Timers.Add(target, Timer);
389 }
390 else
391 {
392 FreezeCache.Remove(target.ToString());
393 Timers.TryGetValue(target, out Timer);
394 Timers.Remove(target);
395 Timer.Dispose();
396 }
397 }
398
399 private void OnEndParcelFrozen(object avatar)
400 {
401 UUID target = (UUID)avatar;
402 FreezeCache.Remove(target.ToString());
403 System.Threading.Timer Timer;
404 Timers.TryGetValue(target, out Timer);
405 Timers.Remove(target);
406 Timer.Dispose();
407 }
361 } 408 }
362} 409}
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 0dad3c4..6064ddc 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
@@ -244,6 +248,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
244 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 248 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
245 && requestData.ContainsKey("binary_bucket")) 249 && requestData.ContainsKey("binary_bucket"))
246 { 250 {
251 if (m_MessageKey != String.Empty)
252 {
253 XmlRpcResponse error_resp = new XmlRpcResponse();
254 Hashtable error_respdata = new Hashtable();
255 error_respdata["success"] = "FALSE";
256 error_resp.Value = error_respdata;
257
258 if (!requestData.Contains("message_key"))
259 return error_resp;
260 if (m_MessageKey != (string)requestData["message_key"])
261 return error_resp;
262 }
263
247 // Do the easy way of validating the UUIDs 264 // Do the easy way of validating the UUIDs
248 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 265 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
249 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 266 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -420,24 +437,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
420 return resp; 437 return resp;
421 } 438 }
422 439
423 /// <summary> 440 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
424 /// delegate for sending a grid instant message asynchronously
425 /// </summary>
426 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
427 441
428 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 442 private class GIM {
429 { 443 public GridInstantMessage im;
430 GridInstantMessageDelegate icon = 444 public MessageResultNotification result;
431 (GridInstantMessageDelegate)iar.AsyncState; 445 };
432 icon.EndInvoke(iar);
433 }
434 446
447 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
448 private int numInstantMessageThreads = 0;
435 449
436 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 450 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
437 { 451 {
438 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 452 lock (pendingInstantMessages) {
453 if (numInstantMessageThreads >= 4) {
454 GIM gim = new GIM();
455 gim.im = im;
456 gim.result = result;
457 pendingInstantMessages.Enqueue(gim);
458 } else {
459 ++ numInstantMessageThreads;
460 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
461 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
462 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
463 }
464 }
465 }
439 466
440 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 467 private void GridInstantMessageCompleted(IAsyncResult iar)
468 {
469 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
470 d.EndInvoke(iar);
441 } 471 }
442 472
443 /// <summary> 473 /// <summary>
@@ -452,8 +482,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
452 /// Pass in 0 the first time this method is called. It will be called recursively with the last 482 /// Pass in 0 the first time this method is called. It will be called recursively with the last
453 /// regionhandle tried 483 /// regionhandle tried
454 /// </param> 484 /// </param>
455 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 485 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
456 { 486 {
487 GIM gim;
488 do {
489 try {
490 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
491 } catch (Exception e) {
492 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
493 }
494 lock (pendingInstantMessages) {
495 if (pendingInstantMessages.Count > 0) {
496 gim = pendingInstantMessages.Dequeue();
497 im = gim.im;
498 result = gim.result;
499 } else {
500 gim = null;
501 -- numInstantMessageThreads;
502 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
503 }
504 }
505 } while (gim != null);
506 }
507 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
508 {
509
457 UUID toAgentID = new UUID(im.toAgentID); 510 UUID toAgentID = new UUID(im.toAgentID);
458 511
459 PresenceInfo upd = null; 512 PresenceInfo upd = null;
@@ -520,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
520 573
521 if (upd != null) 574 if (upd != null)
522 { 575 {
523 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 576 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
524 upd.RegionID); 577 upd.RegionID);
525 if (reginfo != null) 578 if (reginfo != null)
526 { 579 {
@@ -669,6 +722,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
669 gim["position_z"] = msg.Position.Z.ToString(); 722 gim["position_z"] = msg.Position.Z.ToString();
670 gim["region_id"] = msg.RegionID.ToString(); 723 gim["region_id"] = msg.RegionID.ToString();
671 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 724 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
725 if (m_MessageKey != String.Empty)
726 gim["message_key"] = m_MessageKey;
672 return gim; 727 return gim;
673 } 728 }
674 729
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 19c774f..80554fb 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,30 +310,11 @@ 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 (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) 316 else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
317 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined)
301 { 318 {
302 // Here, the recipient is local and we can assume that the 319 // Here, the recipient is local and we can assume that the
303 // inventory is loaded. Courtesy of the above bulk update, 320 // inventory is loaded. Courtesy of the above bulk update,
@@ -333,6 +350,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
333 { 350 {
334 folder.ParentID = trashFolder.ID; 351 folder.ParentID = trashFolder.ID;
335 invService.MoveFolder(folder); 352 invService.MoveFolder(folder);
353 client.SendBulkUpdateInventory(folder);
336 } 354 }
337 } 355 }
338 356
@@ -433,22 +451,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
433 /// 451 ///
434 /// </summary> 452 /// </summary>
435 /// <param name="msg"></param> 453 /// <param name="msg"></param>
436 private void OnGridInstantMessage(GridInstantMessage msg) 454 private void OnGridInstantMessage(GridInstantMessage im)
437 { 455 {
438 // Check if this is ours to handle 456 // Check if this is ours to handle
439 // 457 //
440 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 458 Scene scene = FindClientScene(new UUID(im.toAgentID));
441 459
442 if (scene == null) 460 if (scene == null)
443 return; 461 return;
444 462
445 // Find agent to deliver to 463 // Find agent to deliver to
446 // 464 //
447 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 465 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
466 if (user == null)
467 return;
468
469 // This requires a little bit of processing because we have to make the
470 // new item visible in the recipient's inventory here
471 //
472 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
473 {
474 if (im.binaryBucket.Length < 17) // Invalid
475 return;
476
477 UUID recipientID = new UUID(im.toAgentID);
478
479 // First byte is the asset type
480 AssetType assetType = (AssetType)im.binaryBucket[0];
481
482 if (AssetType.Folder == assetType)
483 {
484 UUID folderID = new UUID(im.binaryBucket, 1);
448 485
449 // Just forward to local handling 486 InventoryFolderBase given =
450 OnInstantMessage(user.ControllingClient, msg); 487 new InventoryFolderBase(folderID, recipientID);
488 InventoryFolderBase folder =
489 scene.InventoryService.GetFolder(given);
451 490
491 if (folder != null)
492 user.ControllingClient.SendBulkUpdateInventory(folder);
493 }
494 else
495 {
496 UUID itemID = new UUID(im.binaryBucket, 1);
497
498 InventoryItemBase given =
499 new InventoryItemBase(itemID, recipientID);
500 InventoryItemBase item =
501 scene.InventoryService.GetItem(given);
502
503 if (item != null)
504 {
505 user.ControllingClient.SendBulkUpdateInventory(item);
506 }
507 }
508 user.ControllingClient.SendInstantMessage(im);
509 }
510 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
511 {
512 if (im.binaryBucket.Length < 1) // Invalid
513 return;
514
515 UUID recipientID = new UUID(im.toAgentID);
516
517 // Bucket is the asset type
518 AssetType assetType = (AssetType)im.binaryBucket[0];
519
520 if (AssetType.Folder == assetType)
521 {
522 UUID folderID = new UUID(im.imSessionID);
523
524 InventoryFolderBase given =
525 new InventoryFolderBase(folderID, recipientID);
526 InventoryFolderBase folder =
527 scene.InventoryService.GetFolder(given);
528
529 if (folder != null)
530 user.ControllingClient.SendBulkUpdateInventory(folder);
531 }
532 else
533 {
534 UUID itemID = new UUID(im.imSessionID);
535
536 InventoryItemBase given =
537 new InventoryItemBase(itemID, recipientID);
538 InventoryItemBase item =
539 scene.InventoryService.GetItem(given);
540
541 if (item != null)
542 {
543 user.ControllingClient.SendBulkUpdateInventory(item);
544 }
545 }
546
547 // Fix up binary bucket since this may be 17 chars long here
548 Byte[] bucket = new Byte[1];
549 bucket[0] = im.binaryBucket[0];
550 im.binaryBucket = bucket;
551
552 user.ControllingClient.SendInstantMessage(im);
553 }
554 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
555 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
556 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
557 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
558 {
559 user.ControllingClient.SendInstantMessage(im);
560 }
452 } 561 }
453 } 562 }
454} 563}
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/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..192b4f6 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,10 +179,10 @@ 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 m_HttpServer.AddPollServiceHTTPHandler(
224 uri, 188 uri,
@@ -261,6 +225,7 @@ 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() + "/";
@@ -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 322a9f8..6cd077a 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;
@@ -247,4 +250,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
247 } 250 }
248 } 251 }
249 } 252 }
250} \ No newline at end of file 253}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 026c6c8..008992e 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 }
@@ -392,4 +392,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
392 392
393 #endregion 393 #endregion
394 } 394 }
395} \ No newline at end of file 395}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index f980f68..d395413 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..b7667b9 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 2eac0fa..5b03ac7 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..4e6bfb8 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -86,9 +86,9 @@ 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 if (mapName.Length < 2)
90 { 90 {
91 remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); 91 remoteClient.SendAlertMessage("Use a search string with at least 2 characters");
92 return; 92 return;
93 } 93 }
94 94
@@ -112,10 +112,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
112 112
113 // try to fetch from GridServer 113 // try to fetch from GridServer
114 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); 114 List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20);
115 if (regionInfos.Count == 0) 115// if (regionInfos.Count == 0)
116 remoteClient.SendAlertMessage("Hyperlink could not be established."); 116// remoteClient.SendAlertMessage("Hyperlink could not be established.");
117 117
118 m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); 118 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
119 List<MapBlockData> blocks = new List<MapBlockData>(); 119 List<MapBlockData> blocks = new List<MapBlockData>();
120 120
121 MapBlockData data; 121 MapBlockData data;
@@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
149 data.Agents = 0; 149 data.Agents = 0;
150 data.Access = 255; 150 data.Access = 255;
151 data.MapImageId = UUID.Zero; 151 data.MapImageId = UUID.Zero;
152 data.Name = ""; // mapName; 152 data.Name = mapName;
153 data.RegionFlags = 0; 153 data.RegionFlags = 0;
154 data.WaterHeight = 0; // not used 154 data.WaterHeight = 0; // not used
155 data.X = 0; 155 data.X = 0;
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index c1c6b49..724bb4c 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -1241,7 +1241,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1241 } 1241 }
1242 else 1242 else
1243 { 1243 {
1244 OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); 1244 OSDArray responsearr = new OSDArray(); // Don't preallocate. MT (m_scene.GetRootAgentCount());
1245 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 1245 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
1246 { 1246 {
1247 OSDMap responsemapdata = new OSDMap(); 1247 OSDMap responsemapdata = new OSDMap();
@@ -1461,9 +1461,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1461 Color background = Color.FromArgb(0, 0, 0, 0); 1461 Color background = Color.FromArgb(0, 0, 0, 0);
1462 SolidBrush transparent = new SolidBrush(background); 1462 SolidBrush transparent = new SolidBrush(background);
1463 Graphics g = Graphics.FromImage(overlay); 1463 Graphics g = Graphics.FromImage(overlay);
1464 g.FillRectangle(transparent, 0, 0, 256, 256); 1464 g.FillRectangle(transparent, 0, 0, 255, 255);
1465 1465
1466 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); 1466 SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9));
1467 Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92));
1467 1468
1468 foreach (ILandObject land in parcels) 1469 foreach (ILandObject land in parcels)
1469 { 1470 {
@@ -1471,8 +1472,42 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1471 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) 1472 if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0)
1472 { 1473 {
1473 landForSale = true; 1474 landForSale = true;
1475
1476 bool[,] landBitmap = land.GetLandBitmap();
1477
1478 for (int x = 0 ; x < 64 ; x++)
1479 {
1480 for (int y = 0 ; y < 64 ; y++)
1481 {
1482 if (landBitmap[x, y])
1483 {
1484 g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4);
1485
1486 if (x > 0)
1487 {
1488 if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false)
1489 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4));
1490 }
1491 if (y > 0)
1492 {
1493 if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false)
1494 g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4));
1495 }
1496 if (x < 63)
1497 {
1498 if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false)
1499 g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4));
1500 }
1501 if (y < 63)
1502 {
1503 if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false)
1504 g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4));
1505 }
1506 }
1507 }
1508 }
1474 1509
1475 saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); 1510 saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap);
1476 } 1511 }
1477 } 1512 }
1478 1513
@@ -1484,15 +1519,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1484 1519
1485 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); 1520 m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName);
1486 1521
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 1522 try
1497 { 1523 {
1498 return OpenJPEG.EncodeFromImage(overlay, true); 1524 return OpenJPEG.EncodeFromImage(overlay, true);