aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs68
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs115
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs204
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs102
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs60
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs63
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs32
12 files changed, 518 insertions, 180 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 4881499..8be0455 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;
@@ -202,6 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
202 return; 203 return;
203 } 204 }
204 205
206 if (part.OwnerID != remoteClient.AgentId) // Not ours
207 {
208 remoteClient.SendAgentAlertMessage(
209 "You don't have sufficient permissions to attach this object", false);
210 return;
211 }
212
205 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 213 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
206 // be removed when that functionality is implemented in opensim 214 // be removed when that functionality is implemented in opensim
207 AttachmentPt &= 0x7f; 215 AttachmentPt &= 0x7f;
@@ -332,25 +340,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
332 public ISceneEntity RezSingleAttachmentFromInventory( 340 public ISceneEntity RezSingleAttachmentFromInventory(
333 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) 341 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
334 { 342 {
335// m_log.DebugFormat( 343 return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null);
336// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", 344 }
337// (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name);
338 345
346 public UUID RezSingleAttachmentFromInventory(
347 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc)
339 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); 348 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
340 349
341 if (sp == null) 350 {
342 { 351 if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", remoteClient.Name, remoteClient.AgentId); return null; }
343 m_log.ErrorFormat(
344 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
345 remoteClient.Name, remoteClient.AgentId);
346 return null;
347 }
348
349 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 352 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
350 // be removed when that functionality is implemented in opensim 353 // be removed when that functionality is implemented in opensim
351 AttachmentPt &= 0x7f; 354 AttachmentPt &= 0x7f;
352 355
353 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 356 SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt, doc);
354 357
355 if (updateInventoryStatus) 358 if (updateInventoryStatus)
356 { 359 {
@@ -363,8 +366,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
363 return att; 366 return att;
364 } 367 }
365 368
366 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 369 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
367 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 370 IClientAPI remoteClient, UUID itemID, uint AttachmentPt, XmlDocument doc)
368 { 371 {
369 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); 372 IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
370 if (invAccess != null) 373 if (invAccess != null)
@@ -414,6 +417,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
414 if (tainted) 417 if (tainted)
415 objatt.HasGroupChanged = true; 418 objatt.HasGroupChanged = true;
416 419
420 if (doc != null)
421 {
422 objatt.LoadScriptState(doc);
423 objatt.ResetOwnerChangeFlag();
424 }
425
417 // Fire after attach, so we don't get messy perms dialogs 426 // Fire after attach, so we don't get messy perms dialogs
418 // 4 == AttachedRez 427 // 4 == AttachedRez
419 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); 428 objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
@@ -453,8 +462,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
453 if (!att.IsDeleted) 462 if (!att.IsDeleted)
454 attachmentPoint = att.AttachmentPoint; 463 attachmentPoint = att.AttachmentPoint;
455 464
465 ScenePresence presence;
466 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
467 {
456 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); 468 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
457 item = m_scene.InventoryService.GetItem(item); 469 if (m_scene.InventoryService != null)
470 item = m_scene.InventoryService.GetItem(item);
458 471
459 bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID); 472 bool changed = sp.Appearance.SetAttachment((int)attachmentPoint, itemID, item.AssetID);
460 if (changed && m_scene.AvatarFactory != null) 473 if (changed && m_scene.AvatarFactory != null)
@@ -489,7 +502,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
489 return; 502 return;
490 } 503 }
491 504
505 if (null == att.RootPart)
506 {
507 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
508 return;
509 }
492 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); 510 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
511
512
513
514
515
516
493 item = m_scene.InventoryService.GetItem(item); 517 item = m_scene.InventoryService.GetItem(item);
494 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 518 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
495 if (changed && m_scene.AvatarFactory != null) 519 if (changed && m_scene.AvatarFactory != null)
@@ -611,7 +635,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
611 if (group.GetFromItemID() == itemID) 635 if (group.GetFromItemID() == itemID)
612 { 636 {
613 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); 637 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
614 sp.RemoveAttachment(group); 638 // CM / XMREngine!!!! Needed to conclude attach event
639 //SceneObjectSerializer.ToOriginalXmlFormat(group);
640 group.DetachToInventoryPrep();
641 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
615 642
616 // Prepare sog for storage 643 // Prepare sog for storage
617 group.AttachedAvatar = UUID.Zero; 644 group.AttachedAvatar = UUID.Zero;
@@ -755,15 +782,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
755 782
756 if (!silent) 783 if (!silent)
757 { 784 {
758 // Killing it here will cause the client to deselect it
759 // It then reappears on the avatar, deselected
760 // through the full update below
761 //
762 if (so.IsSelected)
763 {
764 m_scene.SendKillObject(so.RootPart.LocalId);
765 }
766
767 so.IsSelected = false; // fudge.... 785 so.IsSelected = false; // fudge....
768 so.ScheduleGroupForFullUpdate(); 786 so.ScheduleGroupForFullUpdate();
769 } 787 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 4359c01..35a3f43 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,6 +195,7 @@ 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 string message = c.Message; 200 string message = c.Message;
190 IScene scene = c.Scene; 201 IScene scene = c.Scene;
@@ -207,7 +218,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
207 fromPos = avatar.AbsolutePosition; 218 fromPos = avatar.AbsolutePosition;
208 fromName = avatar.Name; 219 fromName = avatar.Name;
209 fromID = c.Sender.AgentId; 220 fromID = c.Sender.AgentId;
210 221 if (avatar.GodLevel >= 200)
222 {
223 fromNamePrefix = m_adminPrefix;
224 }
211 break; 225 break;
212 226
213 case ChatSourceType.Object: 227 case ChatSourceType.Object:
@@ -231,8 +245,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
231 s.ForEachScenePresence( 245 s.ForEachScenePresence(
232 delegate(ScenePresence presence) 246 delegate(ScenePresence presence)
233 { 247 {
234 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType)) 248 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
235 receiverIDs.Add(presence.UUID); 249 if (Presencecheck != null)
250 {
251 // This will pass all chat from objects. Not
252 // perfect, but it will do. For now. Better
253 // than the prior behavior of muting all
254 // objects on a parcel with access restrictions
255 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
256 {
257 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType))
258 receiverIDs.Add(presence.UUID);
259 }
260 }
261
236 } 262 }
237 ); 263 );
238 } 264 }
@@ -276,31 +302,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
276 } 302 }
277 303
278 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 304 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
279
280 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 305 HashSet<UUID> receiverIDs = new HashSet<UUID>();
281 306
282 ((Scene)c.Scene).ForEachScenePresence( 307 if (c.Scene != null)
283 delegate(ScenePresence presence) 308 {
284 { 309 ((Scene)c.Scene).ForEachScenePresence
285 // ignore chat from child agents 310 (
286 if (presence.IsChildAgent) return; 311 delegate(ScenePresence presence)
287 312 {
288 IClientAPI client = presence.ControllingClient; 313 // ignore chat from child agents
289 314 if (presence.IsChildAgent) return;
290 // don't forward SayOwner chat from objects to 315
291 // non-owner agents 316 IClientAPI client = presence.ControllingClient;
292 if ((c.Type == ChatTypeEnum.Owner) && 317
293 (null != c.SenderObject) && 318 // don't forward SayOwner chat from objects to
294 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 319 // non-owner agents
295 return; 320 if ((c.Type == ChatTypeEnum.Owner) &&
296 321 (null != c.SenderObject) &&
297 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, 322 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
298 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 323 return;
299 receiverIDs.Add(presence.UUID); 324
300 }); 325 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
301 326 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
302 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 327 receiverIDs.Add(presence.UUID);
303 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 328 }
329 );
330 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
331 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
332 }
304 } 333 }
305 334
306 /// <summary> 335 /// <summary>
@@ -343,5 +372,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
343 372
344 return true; 373 return true;
345 } 374 }
375
376 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
377 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
378 {
379 System.Threading.Timer Timer;
380 if (flags == 0)
381 {
382 FreezeCache.Add(target.ToString());
383 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
384 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
385 Timers.Add(target, Timer);
386 }
387 else
388 {
389 FreezeCache.Remove(target.ToString());
390 Timers.TryGetValue(target, out Timer);
391 Timers.Remove(target);
392 Timer.Dispose();
393 }
394 }
395
396 private void OnEndParcelFrozen(object avatar)
397 {
398 UUID target = (UUID)avatar;
399 FreezeCache.Remove(target.ToString());
400 System.Threading.Timer Timer;
401 Timers.TryGetValue(target, out Timer);
402 Timers.Remove(target);
403 Timer.Dispose();
404 }
346 } 405 }
347} 406}
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index 36fe040..f343f80 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -218,4 +218,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
218 return result; 218 return result;
219 } 219 }
220 } 220 }
221} \ No newline at end of file 221}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 3a7178c..4350cde 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -304,7 +304,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
304 //m_log.DebugFormat("[XXX]: OnClientLogin!"); 304 //m_log.DebugFormat("[XXX]: OnClientLogin!");
305 // Inform the friends that this user is online 305 // Inform the friends that this user is online
306 StatusChange(agentID, true); 306 StatusChange(agentID, true);
307 307
308 // Register that we need to send the list of online friends to this user 308 // Register that we need to send the list of online friends to this user
309 lock (m_NeedsListOfFriends) 309 lock (m_NeedsListOfFriends)
310 m_NeedsListOfFriends.Add(agentID); 310 m_NeedsListOfFriends.Add(agentID);
@@ -579,6 +579,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
579 579
580 StoreFriendships(agentID, friendID); 580 StoreFriendships(agentID, friendID);
581 581
582 ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
583 if (ccm != null)
584 {
585 ccm.CreateCallingCard(agentID, friendID, UUID.Zero);
586 }
587
582 // Update the local cache 588 // Update the local cache
583 RefetchFriends(client); 589 RefetchFriends(client);
584 590
@@ -755,6 +761,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
755 (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero); 761 (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
756 friendClient.SendInstantMessage(im); 762 friendClient.SendInstantMessage(im);
757 763
764 ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
765 if (ccm != null)
766 {
767 ccm.CreateCallingCard(friendID, userID, UUID.Zero);
768 }
769
770
758 // Update the local cache 771 // Update the local cache
759 RefetchFriends(friendClient); 772 RefetchFriends(friendClient);
760 773
@@ -777,7 +790,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
777 // we're done 790 // we're done
778 return true; 791 return true;
779 } 792 }
780 793
781 return false; 794 return false;
782 } 795 }
783 796
@@ -830,7 +843,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
830 843
831 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online) 844 public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
832 { 845 {
833// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online); 846 //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
834 IClientAPI friendClient = LocateClientObject(friendID); 847 IClientAPI friendClient = LocateClientObject(friendID);
835 if (friendClient != null) 848 if (friendClient != null)
836 { 849 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 5ec64d5..a83b3df 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, OSHttpRequest httpRequest,
115 OSHttpResponse 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,71 +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.ForEachScenePresence(
144 delegate(ScenePresence p)
145 {
146 if (p.UUID != godID && !p.IsChildAgent)
147 {
148 // Possibly this should really be p.Close() though that method doesn't send a close
149 // to the client
150 p.ControllingClient.Close();
151 }
152 }
153 );
154 }
155 else
156 {
157 m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
158 214
159 sp.ControllingClient.Kick(Utils.BytesToString(reason)); 215 switch (kickflags)
160 sp.ControllingClient.Close(); 216 {
161 } 217 case 0:
162 } 218 if (sp != null)
163 219 {
164 if (kickflags == 1) 220 KickPresence(sp, Utils.BytesToString(reason));
165 {
166 sp.AllowMovement = false;
167 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
168 m_dialogModule.SendAlertToUser(godID, "User Frozen");
169 }
170
171 if (kickflags == 2)
172 {
173 sp.AllowMovement = true;
174 m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
175 m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
176 }
177 } 221 }
178 else 222 else if (agentID == ALL_AGENTS)
179 { 223 {
180 m_dialogModule.SendAlertToUser(godID, "Kick request denied"); 224 m_scene.ForEachScenePresence(
225 delegate(ScenePresence p)
226 {
227 if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
228 KickPresence(p, Utils.BytesToString(reason));
229 }
230 );
181 } 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));
182 } 272 }
183 } 273 }
184 } 274 }
185} \ 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 af39565..feb5fb8 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -156,6 +156,32 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
156 return; 156 return;
157 } 157 }
158 158
159 //DateTime dt = DateTime.UtcNow;
160
161 // Ticks from UtcNow, but make it look like local. Evil, huh?
162 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
163
164 //try
165 //{
166 // // Convert that to the PST timezone
167 // TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
168 // dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
169 //}
170 //catch
171 //{
172 // //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
173 //}
174
175 //// And make it look local again to fool the unix time util
176 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
177
178 // If client is null, this message comes from storage and IS offline
179 if (client != null)
180 im.offline = 0;
181
182 if (im.offline == 0)
183 im.timestamp = (uint)Util.UnixTimeSinceEpoch();
184
159 if (m_TransferModule != null) 185 if (m_TransferModule != null)
160 { 186 {
161 if (client != null) 187 if (client != null)
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 77c7147..c1caf44 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private bool m_Enabled = false; 49 private bool m_Enabled = false;
50 protected string m_MessageKey = String.Empty;
50 protected List<Scene> m_Scenes = new List<Scene>(); 51 protected List<Scene> m_Scenes = new List<Scene>();
51 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); 52 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
52 53
@@ -66,14 +67,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
66 public virtual void Initialise(IConfigSource config) 67 public virtual void Initialise(IConfigSource config)
67 { 68 {
68 IConfig cnf = config.Configs["Messaging"]; 69 IConfig cnf = config.Configs["Messaging"];
69 if (cnf != null && cnf.GetString( 70 if (cnf != null)
70 "MessageTransferModule", "MessageTransferModule") !=
71 "MessageTransferModule")
72 { 71 {
73 m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); 72 if (cnf.GetString("MessageTransferModule",
74 return; 73 "MessageTransferModule") != "MessageTransferModule")
75 } 74 {
75 return;
76 }
76 77
78 m_MessageKey = cnf.GetString("MessageKey", String.Empty);
79 }
80 m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
77 m_Enabled = true; 81 m_Enabled = true;
78 } 82 }
79 83
@@ -145,8 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
145 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 149 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
146 if (!user.IsChildAgent) 150 if (!user.IsChildAgent)
147 { 151 {
148 // Local message 152 // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
149// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
150 user.ControllingClient.SendInstantMessage(im); 153 user.ControllingClient.SendInstantMessage(im);
151 154
152 // Message sent 155 // Message sent
@@ -168,7 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
168 // Local message 171 // Local message
169 ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; 172 ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
170 173
171// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); 174 // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
172 user.ControllingClient.SendInstantMessage(im); 175 user.ControllingClient.SendInstantMessage(im);
173 176
174 // Message sent 177 // Message sent
@@ -251,6 +254,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
251 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 254 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
252 && requestData.ContainsKey("binary_bucket")) 255 && requestData.ContainsKey("binary_bucket"))
253 { 256 {
257 if (m_MessageKey != String.Empty)
258 {
259 XmlRpcResponse error_resp = new XmlRpcResponse();
260 Hashtable error_respdata = new Hashtable();
261 error_respdata["success"] = "FALSE";
262 error_resp.Value = error_respdata;
263
264 if (!requestData.Contains("message_key"))
265 return error_resp;
266 if (m_MessageKey != (string)requestData["message_key"])
267 return error_resp;
268 }
269
254 // Do the easy way of validating the UUIDs 270 // Do the easy way of validating the UUIDs
255 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 271 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
256 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 272 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -433,24 +449,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
433 return resp; 449 return resp;
434 } 450 }
435 451
436 /// <summary> 452 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
437 /// delegate for sending a grid instant message asynchronously
438 /// </summary>
439 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
440 453
441 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 454 private class GIM {
442 { 455 public GridInstantMessage im;
443 GridInstantMessageDelegate icon = 456 public MessageResultNotification result;
444 (GridInstantMessageDelegate)iar.AsyncState; 457 };
445 icon.EndInvoke(iar);
446 }
447 458
459 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
460 private int numInstantMessageThreads = 0;
448 461
449 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 462 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
450 { 463 {
451 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 464 lock (pendingInstantMessages) {
465 if (numInstantMessageThreads >= 4) {
466 GIM gim = new GIM();
467 gim.im = im;
468 gim.result = result;
469 pendingInstantMessages.Enqueue(gim);
470 } else {
471 ++ numInstantMessageThreads;
472 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
473 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
474 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
475 }
476 }
477 }
452 478
453 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 479 private void GridInstantMessageCompleted(IAsyncResult iar)
480 {
481 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
482 d.EndInvoke(iar);
454 } 483 }
455 484
456 /// <summary> 485 /// <summary>
@@ -465,8 +494,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
465 /// Pass in 0 the first time this method is called. It will be called recursively with the last 494 /// Pass in 0 the first time this method is called. It will be called recursively with the last
466 /// regionhandle tried 495 /// regionhandle tried
467 /// </param> 496 /// </param>
468 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 497 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
469 { 498 {
499 GIM gim;
500 do {
501 try {
502 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
503 } catch (Exception e) {
504 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
505 }
506 lock (pendingInstantMessages) {
507 if (pendingInstantMessages.Count > 0) {
508 gim = pendingInstantMessages.Dequeue();
509 im = gim.im;
510 result = gim.result;
511 } else {
512 gim = null;
513 -- numInstantMessageThreads;
514 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
515 }
516 }
517 } while (gim != null);
518 }
519 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
520 {
521
470 UUID toAgentID = new UUID(im.toAgentID); 522 UUID toAgentID = new UUID(im.toAgentID);
471 523
472 PresenceInfo upd = null; 524 PresenceInfo upd = null;
@@ -533,7 +585,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
533 585
534 if (upd != null) 586 if (upd != null)
535 { 587 {
536 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 588 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
537 upd.RegionID); 589 upd.RegionID);
538 if (reginfo != null) 590 if (reginfo != null)
539 { 591 {
@@ -682,6 +734,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
682 gim["position_z"] = msg.Position.Z.ToString(); 734 gim["position_z"] = msg.Position.Z.ToString();
683 gim["region_id"] = msg.RegionID.ToString(); 735 gim["region_id"] = msg.RegionID.ToString();
684 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 736 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
737 if (m_MessageKey != String.Empty)
738 gim["message_key"] = m_MessageKey;
685 return gim; 739 return gim;
686 } 740 }
687 741
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 8d055d4..d9dcee7 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,9 +183,8 @@ 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."); 187 {
184
185 foreach (GridInstantMessage im in msglist) 188 foreach (GridInstantMessage im in msglist)
186 { 189 {
187 // client.SendInstantMessage(im); 190 // client.SendInstantMessage(im);
@@ -192,6 +195,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
192 // Needed for proper state management for stored group 195 // Needed for proper state management for stored group
193 // invitations 196 // invitations
194 // 197 //
198
199 im.offline = 1;
200
195 Scene s = FindScene(client.AgentId); 201 Scene s = FindScene(client.AgentId);
196 if (s != null) 202 if (s != null)
197 s.EventManager.TriggerIncomingInstantMessage(im); 203 s.EventManager.TriggerIncomingInstantMessage(im);
@@ -201,26 +207,40 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
201 207
202 private void UndeliveredMessage(GridInstantMessage im) 208 private void UndeliveredMessage(GridInstantMessage im)
203 { 209 {
204 if ((im.offline != 0) 210 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
205 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) 211 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
212 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
213 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
214 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
206 { 215 {
207 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 216 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
208 "POST", m_RestURL+"/SaveMessage/", im); 217 "POST", m_RestURL+"/SaveMessage/", im);
218 return;
219 }
209 220
210 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 221 // It's not delivered. Make sure the scope id is saved
211 { 222 // We don't need the imSessionID here anymore, overwrite it
212 IClientAPI client = FindClient(new UUID(im.fromAgentID)); 223 Scene scene = FindScene(new UUID(im.fromAgentID));
213 if (client == null) 224 if (scene == null)
214 return; 225 scene = m_SceneList[0];
215 226
216 client.SendInstantMessage(new GridInstantMessage( 227 bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
217 null, new UUID(im.toAgentID), 228 "POST", m_RestURL+"/SaveMessage/?scope=" +
218 "System", new UUID(im.fromAgentID), 229 scene.RegionInfo.ScopeID.ToString(), im);
219 (byte)InstantMessageDialog.MessageFromAgent, 230
220 "User is not logged in. "+ 231 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
221 (success ? "Message saved." : "Message not saved"), 232 {
222 false, new Vector3())); 233 IClientAPI client = FindClient(new UUID(im.fromAgentID));
223 } 234 if (client == null)
235 return;
236
237 client.SendInstantMessage(new GridInstantMessage(
238 null, new UUID(im.toAgentID),
239 "System", new UUID(im.fromAgentID),
240 (byte)InstantMessageDialog.MessageFromAgent,
241 "User is not logged in. "+
242 (success ? "Message saved." : "Message not saved"),
243 false, new Vector3()));
224 } 244 }
225 } 245 }
226 } 246 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 6b24718..a19bbfd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -632,4 +632,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
632 m_assetsLoaded = true; 632 m_assetsLoaded = true;
633 } 633 }
634 } 634 }
635} \ No newline at end of file 635}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 36ecb3b..63fde07 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -178,9 +178,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
178 InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, 178 InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself,
179 Dictionary<string, object> options, IUserAccountService userAccountService) 179 Dictionary<string, object> options, IUserAccountService userAccountService)
180 { 180 {
181 if (options.ContainsKey("verbose"))
182 m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name);
183
184 if (saveThisFolderItself) 181 if (saveThisFolderItself)
185 { 182 {
186 path += CreateArchiveFolderName(inventoryFolder); 183 path += CreateArchiveFolderName(inventoryFolder);
@@ -449,4 +446,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
449 return s; 446 return s;
450 } 447 }
451 } 448 }
452} \ No newline at end of file 449}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index f46d9f7..120fd43 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 = 1; // Remember these
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.
@@ -427,22 +429,67 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
427 /// 429 ///
428 /// </summary> 430 /// </summary>
429 /// <param name="msg"></param> 431 /// <param name="msg"></param>
430 private void OnGridInstantMessage(GridInstantMessage msg) 432 private void OnGridInstantMessage(GridInstantMessage im)
431 { 433 {
432 // Check if this is ours to handle 434 // Check if this is ours to handle
433 // 435 //
434 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 436 Scene scene = FindClientScene(new UUID(im.toAgentID));
435 437
436 if (scene == null) 438 if (scene == null)
437 return; 439 return;
438 440
439 // Find agent to deliver to 441 // Find agent to deliver to
440 // 442 //
441 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 443 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
444 if (user == null)
445 return;
446
447 // This requires a little bit of processing because we have to make the
448 // new item visible in the recipient's inventory here
449 //
450 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
451 {
452 if (im.binaryBucket.Length < 17) // Invalid
453 return;
454
455 UUID recipientID = new UUID(im.toAgentID);
456
457 // First byte is the asset type
458 AssetType assetType = (AssetType)im.binaryBucket[0];
459
460 if (AssetType.Folder == assetType)
461 {
462 UUID folderID = new UUID(im.binaryBucket, 1);
463
464 InventoryFolderBase given =
465 new InventoryFolderBase(folderID, recipientID);
466 InventoryFolderBase folder =
467 scene.InventoryService.GetFolder(given);
468
469 if (folder != null)
470 user.ControllingClient.SendBulkUpdateInventory(folder);
471 }
472 else
473 {
474 UUID itemID = new UUID(im.binaryBucket, 1);
442 475
443 // Just forward to local handling 476 InventoryItemBase given =
444 OnInstantMessage(user.ControllingClient, msg); 477 new InventoryItemBase(itemID, recipientID);
478 InventoryItemBase item =
479 scene.InventoryService.GetItem(given);
445 480
481 if (item != null)
482 {
483 user.ControllingClient.SendBulkUpdateInventory(item);
484 }
485 }
486 user.ControllingClient.SendInstantMessage(im);
487 }
488 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
489 im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
490 {
491 user.ControllingClient.SendInstantMessage(im);
492 }
446 } 493 }
447 } 494 }
448} 495}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index d295384..dcfdf8f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -155,16 +155,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
155 scene.RegionInfo.RegionHandle, 155 scene.RegionInfo.RegionHandle,
156 (uint)presence.AbsolutePosition.X, 156 (uint)presence.AbsolutePosition.X,
157 (uint)presence.AbsolutePosition.Y, 157 (uint)presence.AbsolutePosition.Y,
158 (uint)presence.AbsolutePosition.Z); 158 (uint)presence.AbsolutePosition.Z + 2);
159 159
160 m_log.DebugFormat("TP invite with message {0}", message); 160 m_log.DebugFormat("[LURE]: TP invite with message {0}", message);
161
162 GridInstantMessage m;
163
164 if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
165 {
166 m = new GridInstantMessage(scene, client.AgentId,
167 client.FirstName+" "+client.LastName, targetid,
168 (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
169 message, dest, false, presence.AbsolutePosition,
170 new Byte[0]);
171 }
172 else
173 {
174 m = new GridInstantMessage(scene, client.AgentId,
175 client.FirstName+" "+client.LastName, targetid,
176 (byte)InstantMessageDialog.RequestTeleport, false,
177 message, dest, false, presence.AbsolutePosition,
178 new Byte[0]);
179 }
161 180
162 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
163 client.FirstName+" "+client.LastName, targetid,
164 (byte)InstantMessageDialog.RequestTeleport, false,
165 message, dest, false, presence.AbsolutePosition,
166 new Byte[0]);
167
168 if (m_TransferModule != null) 181 if (m_TransferModule != null)
169 { 182 {
170 m_TransferModule.SendInstantMessage(m, 183 m_TransferModule.SendInstantMessage(m,
@@ -199,7 +212,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
199 { 212 {
200 // Forward remote teleport requests 213 // Forward remote teleport requests
201 // 214 //
202 if (msg.dialog != 22) 215 if (msg.dialog != (byte)InstantMessageDialog.RequestTeleport &&
216 msg.dialog != (byte)InstantMessageDialog.GodLikeRequestTeleport)
203 return; 217 return;
204 218
205 if (m_TransferModule != null) 219 if (m_TransferModule != null)