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.cs107
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs463
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs208
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs260
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs67
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs100
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs56
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs168
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs30
15 files changed, 1024 insertions, 476 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 7d16635..cb724aa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization; 42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Services.Interfaces;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.Attachments 45namespace OpenSim.Region.CoreModules.Avatar.Attachments
45{ 46{
@@ -235,6 +236,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
235 if (DebugLevel > 0) 236 if (DebugLevel > 0)
236 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name); 237 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name);
237 238
239 XmlDocument doc = new XmlDocument();
240 string stateData = String.Empty;
241
242 IAttachmentsService attServ = m_scene.RequestModuleInterface<IAttachmentsService>();
243 if (attServ != null)
244 {
245 m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service");
246 stateData = attServ.Get(sp.UUID.ToString());
247 if (stateData != String.Empty)
248 {
249 try
250 {
251 doc.LoadXml(stateData);
252 }
253 catch { }
254 }
255 }
256
257 Dictionary<UUID, string> itemData = new Dictionary<UUID, string>();
258
259 XmlNodeList nodes = doc.GetElementsByTagName("Attachment");
260 if (nodes.Count > 0)
261 {
262 foreach (XmlNode n in nodes)
263 {
264 XmlElement elem = (XmlElement)n;
265 string itemID = elem.GetAttribute("ItemID");
266 string xml = elem.InnerXml;
267
268 itemData[new UUID(itemID)] = xml;
269 }
270 }
271
272
238 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 273 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
239 foreach (AvatarAttachment attach in attachments) 274 foreach (AvatarAttachment attach in attachments)
240 { 275 {
@@ -254,10 +289,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
254 289
255 try 290 try
256 { 291 {
292 string xmlData;
293 XmlDocument d = null;
294 UUID asset;
295 if (itemData.TryGetValue(attach.ItemID, out xmlData))
296 {
297 d = new XmlDocument();
298 d.LoadXml(xmlData);
299 m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID);
300 }
301
257 // If we're an NPC then skip all the item checks and manipulations since we don't have an 302 // If we're an NPC then skip all the item checks and manipulations since we don't have an
258 // inventory right now. 303 // inventory right now.
259 RezSingleAttachmentFromInventoryInternal( 304 RezSingleAttachmentFromInventoryInternal(
260 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true); 305 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null);
261 } 306 }
262 catch (Exception e) 307 catch (Exception e)
263 { 308 {
@@ -320,13 +365,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
320 sp.ClearAttachments(); 365 sp.ClearAttachments();
321 } 366 }
322 367
323 public bool AttachObject( 368 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool append)
324 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append)
325 { 369 {
326 if (!Enabled) 370 if (!Enabled)
327 return false; 371 return false;
328 372
329 return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append); 373 return AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, addToInventory, false, append);
330 } 374 }
331 375
332 /// <summary> 376 /// <summary>
@@ -339,10 +383,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
339 /// <param name='silent'></param> 383 /// <param name='silent'></param>
340 /// <param name='addToInventory'>If true then add object to user inventory.</param> 384 /// <param name='addToInventory'>If true then add object to user inventory.</param>
341 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> 385 /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param>
342 /// <param name='append'>Append to attachment point rather than replace.</param> 386 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool addToInventory, bool resumeScripts, bool append)
343 private bool AttachObjectInternal(
344 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool resumeScripts, bool append)
345 { 387 {
388// m_log.DebugFormat(
389// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
390// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
391
392 if (sp.GetAttachments().Contains(group))
393 {
394// m_log.WarnFormat(
395// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
396// group.Name, group.LocalId, sp.Name, AttachmentPt);
397
398 return false;
399 }
400
346 if (group.GetSittingAvatarsCount() != 0) 401 if (group.GetSittingAvatarsCount() != 0)
347 { 402 {
348 if (DebugLevel > 0) 403 if (DebugLevel > 0)
@@ -354,6 +409,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
354 } 409 }
355 410
356 Vector3 attachPos = group.AbsolutePosition; 411 Vector3 attachPos = group.AbsolutePosition;
412
413 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
414 // be removed when that functionality is implemented in opensim
415 attachmentPt &= 0x7f;
416
357 // If the attachment point isn't the same as the one previously used 417 // If the attachment point isn't the same as the one previously used
358 // set it's offset position = 0 so that it appears on the attachment point 418 // set it's offset position = 0 so that it appears on the attachment point
359 // and not in a weird location somewhere unknown. 419 // and not in a weird location somewhere unknown.
@@ -362,7 +422,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
362 attachPos = Vector3.Zero; 422 attachPos = Vector3.Zero;
363 } 423 }
364 424
365 // AttachmentPt 0 means the client chose to 'wear' the attachment. 425 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment.
366 if (attachmentPt == (uint)AttachmentPoint.Default) 426 if (attachmentPt == (uint)AttachmentPoint.Default)
367 { 427 {
368 // Check object for stored attachment point 428 // Check object for stored attachment point
@@ -377,9 +437,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
377 attachPos = Vector3.Zero; 437 attachPos = Vector3.Zero;
378 } 438 }
379 439
380 group.AttachmentPoint = attachmentPt;
381 group.AbsolutePosition = attachPos;
382
383 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); 440 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
384 441
385 if (attachments.Contains(group)) 442 if (attachments.Contains(group))
@@ -412,6 +469,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
412 469
413 lock (sp.AttachmentsSyncLock) 470 lock (sp.AttachmentsSyncLock)
414 { 471 {
472 group.AttachmentPoint = attachmentPt;
473 group.AbsolutePosition = attachPos;
474
415 if (addToInventory && sp.PresenceType != PresenceType.Npc) 475 if (addToInventory && sp.PresenceType != PresenceType.Npc)
416 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append); 476 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
417 477
@@ -442,7 +502,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
442 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append); 502 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
443 } 503 }
444 504
445 public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) 505 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
506 {
507 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
508 }
509
510 public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
446 { 511 {
447 if (!Enabled) 512 if (!Enabled)
448 return null; 513 return null;
@@ -480,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
480 bool append = (AttachmentPt & 0x80) != 0; 545 bool append = (AttachmentPt & 0x80) != 0;
481 AttachmentPt &= 0x7f; 546 AttachmentPt &= 0x7f;
482 547
483 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append); 548 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append, doc);
484 } 549 }
485 550
486 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 551 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -557,7 +622,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
557 so.AttachedAvatar = UUID.Zero; 622 so.AttachedAvatar = UUID.Zero;
558 rootPart.SetParentLocalId(0); 623 rootPart.SetParentLocalId(0);
559 so.ClearPartAttachmentData(); 624 so.ClearPartAttachmentData();
560 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive); 625 rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
561 so.HasGroupChanged = true; 626 so.HasGroupChanged = true;
562 rootPart.Rezzed = DateTime.Now; 627 rootPart.Rezzed = DateTime.Now;
563 rootPart.RemFlag(PrimFlags.TemporaryOnRez); 628 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -890,7 +955,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
890 } 955 }
891 956
892 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 957 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
893 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append) 958 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc)
894 { 959 {
895 if (m_invAccessModule == null) 960 if (m_invAccessModule == null)
896 return null; 961 return null;
@@ -934,7 +999,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
934 // This will throw if the attachment fails 999 // This will throw if the attachment fails
935 try 1000 try
936 { 1001 {
937 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, append); 1002 if (doc != null)
1003 {
1004 objatt.LoadScriptState(doc);
1005 objatt.ResetOwnerChangeFlag();
1006 }
1007
1008 AttachObjectInternal(sp, objatt, attachmentPt, false, true, true, true, append);
938 } 1009 }
939 catch (Exception e) 1010 catch (Exception e)
940 { 1011 {
@@ -1076,7 +1147,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1076 AttachmentPt &= 0x7f; 1147 AttachmentPt &= 0x7f;
1077 1148
1078 // Calls attach with a Zero position 1149 // Calls attach with a Zero position
1079 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) 1150 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, false, append))
1080 { 1151 {
1081 if (DebugLevel > 0) 1152 if (DebugLevel > 0)
1082 m_log.Debug( 1153 m_log.Debug(
@@ -1138,4 +1209,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1138 1209
1139 #endregion 1210 #endregion
1140 } 1211 }
1141} \ No newline at end of file 1212}
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 25444e5..1a38619 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
199 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 199 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
200 200
201 m_numberOfAttachEventsFired = 0; 201 m_numberOfAttachEventsFired = 0;
202 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); 202 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
203 203
204 // Check status on scene presence 204 // Check status on scene presence
205 Assert.That(sp.HasAttachments(), Is.True); 205 Assert.That(sp.HasAttachments(), Is.True);
@@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
246 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); 246 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID);
247 247
248 m_numberOfAttachEventsFired = 0; 248 m_numberOfAttachEventsFired = 0;
249 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false); 249 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, true, false, false);
250 250
251 // Check status on scene presence 251 // Check status on scene presence
252 Assert.That(sp.HasAttachments(), Is.True); 252 Assert.That(sp.HasAttachments(), Is.True);
@@ -279,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
279 279
280 // Test wearing a different attachment from the ground. 280 // Test wearing a different attachment from the ground.
281 { 281 {
282 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); 282 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
283 283
284 // Check status on scene presence 284 // Check status on scene presence
285 Assert.That(sp.HasAttachments(), Is.True); 285 Assert.That(sp.HasAttachments(), Is.True);
@@ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
312 312
313 // Test rewearing an already worn attachment from ground. Nothing should happen. 313 // Test rewearing an already worn attachment from ground. Nothing should happen.
314 { 314 {
315 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false); 315 scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, true, false, false);
316 316
317 // Check status on scene presence 317 // Check status on scene presence
318 Assert.That(sp.HasAttachments(), Is.True); 318 Assert.That(sp.HasAttachments(), Is.True);
@@ -370,7 +370,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
370 sp2.AbsolutePosition = new Vector3(0, 0, 0); 370 sp2.AbsolutePosition = new Vector3(0, 0, 0);
371 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); 371 sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
372 372
373 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false); 373 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false, false);
374 374
375 Assert.That(sp.HasAttachments(), Is.False); 375 Assert.That(sp.HasAttachments(), Is.False);
376 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 376 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
@@ -665,7 +665,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
665 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 665 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
666 666
667 SceneObjectGroup rezzedSo 667 SceneObjectGroup rezzedSo
668 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 668 = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
669 669
670 // Wait for chat to signal rezzed script has been started. 670 // Wait for chat to signal rezzed script has been started.
671 m_chatEvent.WaitOne(60000); 671 m_chatEvent.WaitOne(60000);
@@ -684,7 +684,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
684 Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); 684 Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
685 685
686 // Re-rez the attachment to check script running state 686 // Re-rez the attachment to check script running state
687 SceneObjectGroup reRezzedSo = scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); 687 SceneObjectGroup reRezzedSo = (SceneObjectGroup)(scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest));
688 688
689 // Wait for chat to signal rezzed script has been started. 689 // Wait for chat to signal rezzed script has been started.
690 m_chatEvent.WaitOne(60000); 690 m_chatEvent.WaitOne(60000);
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index c7ac7c4..bc79944 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -141,9 +141,24 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
141 /// <param name="sp"></param> 141 /// <param name="sp"></param>
142 /// <param name="texture"></param> 142 /// <param name="texture"></param>
143 /// <param name="visualParam"></param> 143 /// <param name="visualParam"></param>
144 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) 144 public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
145 { 145 {
146 SetAppearance(sp, appearance.Texture, appearance.VisualParams); 146 SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
147 }
148
149
150 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
151 {
152 float oldoff = sp.Appearance.AvatarFeetOffset;
153 Vector3 oldbox = sp.Appearance.AvatarBoxSize;
154
155 SetAppearance(sp, textureEntry, visualParams, cacheItems);
156 sp.Appearance.SetSize(avSize);
157
158 float off = sp.Appearance.AvatarFeetOffset;
159 Vector3 box = sp.Appearance.AvatarBoxSize;
160 if (oldoff != off || oldbox != box)
161 ((ScenePresence)sp).SetSize(box, off);
147 } 162 }
148 163
149 /// <summary> 164 /// <summary>
@@ -152,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
152 /// <param name="sp"></param> 167 /// <param name="sp"></param>
153 /// <param name="texture"></param> 168 /// <param name="texture"></param>
154 /// <param name="visualParam"></param> 169 /// <param name="visualParam"></param>
155 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) 170 public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
156 { 171 {
157// m_log.DebugFormat( 172// m_log.DebugFormat(
158// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", 173// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
@@ -175,18 +190,27 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
175 // m_log.DebugFormat( 190 // m_log.DebugFormat(
176 // "[AVFACTORY]: Setting visual params for {0} to {1}", 191 // "[AVFACTORY]: Setting visual params for {0} to {1}",
177 // client.Name, string.Join(", ", visualParamsStrings)); 192 // client.Name, string.Join(", ", visualParamsStrings));
178 193/*
179 float oldHeight = sp.Appearance.AvatarHeight; 194 float oldHeight = sp.Appearance.AvatarHeight;
180 changed = sp.Appearance.SetVisualParams(visualParams); 195 changed = sp.Appearance.SetVisualParams(visualParams);
181 196
182 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) 197 if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
183 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); 198 ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
184 } 199 */
200// float oldoff = sp.Appearance.AvatarFeetOffset;
201// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
202 changed = sp.Appearance.SetVisualParams(visualParams);
203// float off = sp.Appearance.AvatarFeetOffset;
204// Vector3 box = sp.Appearance.AvatarBoxSize;
205// if(oldoff != off || oldbox != box)
206// ((ScenePresence)sp).SetSize(box,off);
185 207
208 }
209
186 // Process the baked texture array 210 // Process the baked texture array
187 if (textureEntry != null) 211 if (textureEntry != null)
188 { 212 {
189// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); 213 m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
190 214
191// WriteBakedTexturesReport(sp, m_log.DebugFormat); 215// WriteBakedTexturesReport(sp, m_log.DebugFormat);
192 216
@@ -255,6 +279,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
255 return GetBakedTextureFaces(sp); 279 return GetBakedTextureFaces(sp);
256 } 280 }
257 281
282 public WearableCacheItem[] GetCachedItems(UUID agentId)
283 {
284 ScenePresence sp = m_scene.GetScenePresence(agentId);
285 WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
286 //foreach (WearableCacheItem item in items)
287 //{
288
289 //}
290 return items;
291 }
292
258 public bool SaveBakedTextures(UUID agentId) 293 public bool SaveBakedTextures(UUID agentId)
259 { 294 {
260 ScenePresence sp = m_scene.GetScenePresence(agentId); 295 ScenePresence sp = m_scene.GetScenePresence(agentId);
@@ -341,6 +376,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
341 public bool ValidateBakedTextureCache(IScenePresence sp) 376 public bool ValidateBakedTextureCache(IScenePresence sp)
342 { 377 {
343 bool defonly = true; // are we only using default textures 378 bool defonly = true; // are we only using default textures
379 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
380 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
381 WearableCacheItem[] wearableCache = null;
382
383 // Cache wearable data for teleport.
384 // Only makes sense if there's a bake module and a cache module
385 if (bakedModule != null && cache != null)
386 {
387 try
388 {
389 wearableCache = bakedModule.Get(sp.UUID);
390 }
391 catch (Exception)
392 {
393
394 }
395 if (wearableCache != null)
396 {
397 for (int i = 0; i < wearableCache.Length; i++)
398 {
399 cache.Cache(wearableCache[i].TextureAsset);
400 }
401 }
402 }
403 /*
404 IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
405 if (invService.GetRootFolder(userID) != null)
406 {
407 WearableCacheItem[] wearableCache = null;
408 if (bakedModule != null)
409 {
410 try
411 {
412 wearableCache = bakedModule.Get(userID);
413 appearance.WearableCacheItems = wearableCache;
414 appearance.WearableCacheItemsDirty = false;
415 foreach (WearableCacheItem item in wearableCache)
416 {
417 appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID;
418 }
419 }
420 catch (Exception)
421 {
422
423 }
424 }
425 */
344 426
345 // Process the texture entry 427 // Process the texture entry
346 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 428 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@@ -348,9 +430,32 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
348 int idx = AvatarAppearance.BAKE_INDICES[i]; 430 int idx = AvatarAppearance.BAKE_INDICES[i];
349 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 431 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
350 432
351 // if there is no texture entry, skip it 433 // No face, so lets check our baked service cache, teleport or login.
352 if (face == null) 434 if (face == null)
353 continue; 435 {
436 if (wearableCache != null)
437 {
438 // If we find the an appearance item, set it as the textureentry and the face
439 WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache);
440 if (searchitem != null)
441 {
442 sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx);
443 sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID;
444 face = sp.Appearance.Texture.FaceTextures[idx];
445 }
446 else
447 {
448 // if there is no texture entry and no baked cache, skip it
449 continue;
450 }
451 }
452 else
453 {
454 //No texture entry face and no cache. Skip this face.
455 continue;
456 }
457 }
458
354 459
355// m_log.DebugFormat( 460// m_log.DebugFormat(
356// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", 461// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
@@ -365,8 +470,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
365 470
366 defonly = false; // found a non-default texture reference 471 defonly = false; // found a non-default texture reference
367 472
368 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 473 if (cache != null)
369 return false; 474 {
475 if (!cache.Check(face.TextureID.ToString()))
476 return false;
477 }
478 else
479 {
480 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
481 return false;
482 }
370 } 483 }
371 484
372// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); 485// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
@@ -378,6 +491,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
378 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) 491 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
379 { 492 {
380 int texturesRebaked = 0; 493 int texturesRebaked = 0;
494 IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
381 495
382 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 496 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
383 { 497 {
@@ -401,21 +515,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
401 515
402 if (missingTexturesOnly) 516 if (missingTexturesOnly)
403 { 517 {
404 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) 518 if (cache != null)
405 { 519 {
406 continue; 520 if (cache.Check(face.TextureID.ToString()))
521 continue;
522 else
523 {
524 m_log.DebugFormat(
525 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
526 face.TextureID, idx, sp.Name);
527 }
407 } 528 }
408 else 529 else
409 { 530 {
410 // On inter-simulator teleports, this occurs if baked textures are not being stored by the 531 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
411 // grid asset service (which means that they are not available to the new region and so have 532 {
412 // to be re-requested from the client). 533 continue;
413 // 534 }
414 // The only available core OpenSimulator behaviour right now 535
415 // is not to store these textures, temporarily or otherwise. 536 else
416 m_log.DebugFormat( 537 {
417 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 538 // On inter-simulator teleports, this occurs if baked textures are not being stored by the
418 face.TextureID, idx, sp.Name); 539 // grid asset service (which means that they are not available to the new region and so have
540 // to be re-requested from the client).
541 //
542 // The only available core OpenSimulator behaviour right now
543 // is not to store these textures, temporarily or otherwise.
544 m_log.DebugFormat(
545 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
546 face.TextureID, idx, sp.Name);
547 }
419 } 548 }
420 } 549 }
421 else 550 else
@@ -557,26 +686,70 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
557 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 686 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
558 { 687 {
559 IInventoryService invService = m_scene.InventoryService; 688 IInventoryService invService = m_scene.InventoryService;
560 689 bool resetwearable = false;
561 if (invService.GetRootFolder(userID) != null) 690 if (invService.GetRootFolder(userID) != null)
562 { 691 {
563 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
564 { 693 {
565 for (int j = 0; j < appearance.Wearables[i].Count; j++) 694 for (int j = 0; j < appearance.Wearables[i].Count; j++)
566 { 695 {
696 // Check if the default wearables are not set
567 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 697 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
698 {
699 switch ((WearableType) i)
700 {
701 case WearableType.Eyes:
702 case WearableType.Hair:
703 case WearableType.Shape:
704 case WearableType.Skin:
705 //case WearableType.Underpants:
706 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
707 resetwearable = true;
708 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
709 resetwearable = true;
710 break;
711
712 }
568 continue; 713 continue;
714 }
569 715
570 // Ignore ruth's assets 716 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
571 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 717 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
718 {
719 switch ((WearableType)i)
720 {
721 case WearableType.Eyes:
722 case WearableType.Hair:
723 case WearableType.Shape:
724 case WearableType.Skin:
725 //case WearableType.Underpants:
726 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
727
728 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
729 resetwearable = true;
730 break;
731
732 }
572 continue; 733 continue;
573 734 }
735
574 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 736 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
575 baseItem = invService.GetItem(baseItem); 737 baseItem = invService.GetItem(baseItem);
576 738
577 if (baseItem != null) 739 if (baseItem != null)
578 { 740 {
579 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 741 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
742 int unmodifiedWearableIndexForClosure = i;
743 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
744 delegate(string x, object y, AssetBase z)
745 {
746 if (z == null)
747 {
748 TryAndRepairBrokenWearable(
749 (WearableType)unmodifiedWearableIndexForClosure, invService,
750 userID, appearance);
751 }
752 });
580 } 753 }
581 else 754 else
582 { 755 {
@@ -584,17 +757,236 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
584 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 757 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
585 appearance.Wearables[i][j].ItemID, (WearableType)i); 758 appearance.Wearables[i][j].ItemID, (WearableType)i);
586 759
587 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 760 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
761 resetwearable = true;
762
588 } 763 }
589 } 764 }
590 } 765 }
766
767 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
768 if (appearance.Wearables[(int) WearableType.Eyes] == null)
769 {
770 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
771
772 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
773 resetwearable = true;
774 }
775 else
776 {
777 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
778 {
779 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
780 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
781 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
782 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
783 resetwearable = true;
784
785 }
786
787 }
788 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
789 if (appearance.Wearables[(int)WearableType.Shape] == null)
790 {
791 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
792
793 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
794 resetwearable = true;
795 }
796 else
797 {
798 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
799 {
800 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
801 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
802 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
803 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
804 resetwearable = true;
805
806 }
807
808 }
809 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
810 if (appearance.Wearables[(int)WearableType.Hair] == null)
811 {
812 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
813
814 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
815 resetwearable = true;
816 }
817 else
818 {
819 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
820 {
821 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
822 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
823 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
824 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
825 resetwearable = true;
826
827 }
828
829 }
830 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
831 if (appearance.Wearables[(int)WearableType.Skin] == null)
832 {
833 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
834
835 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
836 resetwearable = true;
837 }
838 else
839 {
840 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
841 {
842 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
843 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
844 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
845 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
846 resetwearable = true;
847
848 }
849
850 }
851 if (resetwearable)
852 {
853 ScenePresence presence = null;
854 if (m_scene.TryGetScenePresence(userID, out presence))
855 {
856 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
857 presence.Appearance.Serial++);
858 }
859 }
860
591 } 861 }
592 else 862 else
593 { 863 {
594 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 864 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
595 } 865 }
596 } 866 }
867 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
868 {
869 UUID defaultwearable = GetDefaultItem(type);
870 if (defaultwearable != UUID.Zero)
871 {
872 UUID newInvItem = UUID.Random();
873 InventoryItemBase itembase = new InventoryItemBase(newInvItem, userID)
874 {
875 AssetID =
876 defaultwearable,
877 AssetType
878 =
879 (int)
880 AssetType
881 .Bodypart,
882 CreatorId
883 =
884 userID
885 .ToString
886 (),
887 //InvType = (int)InventoryType.Wearable,
888
889 Description
890 =
891 "Failed Wearable Replacement",
892 Folder =
893 invService
894 .GetFolderForType
895 (userID,
896 AssetType
897 .Bodypart)
898 .ID,
899 Flags = (uint) type,
900 Name = Enum.GetName(typeof (WearableType), type),
901 BasePermissions = (uint) PermissionMask.Copy,
902 CurrentPermissions = (uint) PermissionMask.Copy,
903 EveryOnePermissions = (uint) PermissionMask.Copy,
904 GroupPermissions = (uint) PermissionMask.Copy,
905 NextPermissions = (uint) PermissionMask.Copy
906 };
907 invService.AddItem(itembase);
908 UUID LinkInvItem = UUID.Random();
909 itembase = new InventoryItemBase(LinkInvItem, userID)
910 {
911 AssetID =
912 newInvItem,
913 AssetType
914 =
915 (int)
916 AssetType
917 .Link,
918 CreatorId
919 =
920 userID
921 .ToString
922 (),
923 InvType = (int) InventoryType.Wearable,
924
925 Description
926 =
927 "Failed Wearable Replacement",
928 Folder =
929 invService
930 .GetFolderForType
931 (userID,
932 AssetType
933 .CurrentOutfitFolder)
934 .ID,
935 Flags = (uint) type,
936 Name = Enum.GetName(typeof (WearableType), type),
937 BasePermissions = (uint) PermissionMask.Copy,
938 CurrentPermissions = (uint) PermissionMask.Copy,
939 EveryOnePermissions = (uint) PermissionMask.Copy,
940 GroupPermissions = (uint) PermissionMask.Copy,
941 NextPermissions = (uint) PermissionMask.Copy
942 };
943 invService.AddItem(itembase);
944 appearance.Wearables[(int)type] = new AvatarWearable(newInvItem, GetDefaultItem(type));
945 ScenePresence presence = null;
946 if (m_scene.TryGetScenePresence(userID, out presence))
947 {
948 m_scene.SendInventoryUpdate(presence.ControllingClient,
949 invService.GetFolderForType(userID,
950 AssetType
951 .CurrentOutfitFolder),
952 false, true);
953 }
954 }
955 }
956 private UUID GetDefaultItem(WearableType wearable)
957 {
958 // These are ruth
959 UUID ret = UUID.Zero;
960 switch (wearable)
961 {
962 case WearableType.Eyes:
963 ret = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
964 break;
965 case WearableType.Hair:
966 ret = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
967 break;
968 case WearableType.Pants:
969 ret = new UUID("00000000-38f9-1111-024e-222222111120");
970 break;
971 case WearableType.Shape:
972 ret = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
973 break;
974 case WearableType.Shirt:
975 ret = new UUID("00000000-38f9-1111-024e-222222111110");
976 break;
977 case WearableType.Skin:
978 ret = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
979 break;
980 case WearableType.Undershirt:
981 ret = new UUID("16499ebb-3208-ec27-2def-481881728f47");
982 break;
983 case WearableType.Underpants:
984 ret = new UUID("4ac2e9c7-3671-d229-316a-67717730841d");
985 break;
986 }
597 987
988 return ret;
989 }
598 #endregion 990 #endregion
599 991
600 #region Client Event Handlers 992 #region Client Event Handlers
@@ -604,12 +996,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
604 /// <param name="client"></param> 996 /// <param name="client"></param>
605 private void Client_OnRequestWearables(IClientAPI client) 997 private void Client_OnRequestWearables(IClientAPI client)
606 { 998 {
607 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); 999 Util.FireAndForget(delegate(object x)
608 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1000 {
609 if (sp != null) 1001 Thread.Sleep(4000);
610 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 1002
611 else 1003 // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
612 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); 1004 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
1005 if (sp != null)
1006 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
1007 else
1008 m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
1009 });
613 } 1010 }
614 1011
615 /// <summary> 1012 /// <summary>
@@ -618,12 +1015,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
618 /// <param name="client"></param> 1015 /// <param name="client"></param>
619 /// <param name="texture"></param> 1016 /// <param name="texture"></param>
620 /// <param name="visualParam"></param> 1017 /// <param name="visualParam"></param>
621 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 1018 private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
622 { 1019 {
623 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); 1020 // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
624 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 1021 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
625 if (sp != null) 1022 if (sp != null)
626 SetAppearance(sp, textureEntry, visualParams); 1023 SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
627 else 1024 else
628 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); 1025 m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
629 } 1026 }
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
index 1830d41..f090e15 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
61 for (byte i = 0; i < visualParams.Length; i++) 61 for (byte i = 0; i < visualParams.Length; i++)
62 visualParams[i] = i; 62 visualParams[i] = i;
63 63
64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); 64 afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]);
65 65
66 // TODO: Check baked texture 66 // TODO: Check baked texture
67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams); 67 Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
@@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); 102 Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
103 eyesFace.TextureID = eyesTextureId; 103 eyesFace.TextureID = eyesTextureId;
104 104
105 afm.SetAppearance(sp, bakedTextureEntry, visualParams); 105 afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]);
106 afm.SaveBakedTextures(userId); 106 afm.SaveBakedTextures(userId);
107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); 107// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
108 108
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index 58f747b..174642d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -50,7 +50,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
50 private int m_saydistance = 20; 50 private int m_saydistance = 20;
51 private int m_shoutdistance = 100; 51 private int m_shoutdistance = 100;
52 private int m_whisperdistance = 10; 52 private int m_whisperdistance = 10;
53 53 private List<Scene> m_scenes = new List<Scene>();
54 private List<string> FreezeCache = new List<string>();
55 private string m_adminPrefix = "";
54 internal object m_syncy = new object(); 56 internal object m_syncy = new object();
55 57
56 internal IConfig m_config; 58 internal IConfig m_config;
@@ -77,16 +79,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
77 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 79 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
78 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 80 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
79 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 81 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
82 m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
80 } 83 }
81 84
82 public virtual void AddRegion(Scene scene) 85 public virtual void AddRegion(Scene scene)
83 { 86 {
84 if (!m_enabled) 87 if (!m_enabled) return;
85 return;
86 88
87 scene.EventManager.OnNewClient += OnNewClient; 89 lock (m_syncy)
88 scene.EventManager.OnChatFromWorld += OnChatFromWorld; 90 {
89 scene.EventManager.OnChatBroadcast += OnChatBroadcast; 91 if (!m_scenes.Contains(scene))
92 {
93 m_scenes.Add(scene);
94 scene.EventManager.OnNewClient += OnNewClient;
95 scene.EventManager.OnChatFromWorld += OnChatFromWorld;
96 scene.EventManager.OnChatBroadcast += OnChatBroadcast;
97 }
98 }
90 99
91 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName, 100 m_log.InfoFormat("[CHAT]: Initialized for {0} w:{1} s:{2} S:{3}", scene.RegionInfo.RegionName,
92 m_whisperdistance, m_saydistance, m_shoutdistance); 101 m_whisperdistance, m_saydistance, m_shoutdistance);
@@ -98,12 +107,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
98 107
99 public virtual void RemoveRegion(Scene scene) 108 public virtual void RemoveRegion(Scene scene)
100 { 109 {
101 if (!m_enabled) 110 if (!m_enabled) return;
102 return;
103 111
104 scene.EventManager.OnNewClient -= OnNewClient; 112 lock (m_syncy)
105 scene.EventManager.OnChatFromWorld -= OnChatFromWorld; 113 {
106 scene.EventManager.OnChatBroadcast -= OnChatBroadcast; 114 if (m_scenes.Contains(scene))
115 {
116 scene.EventManager.OnNewClient -= OnNewClient;
117 scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
118 scene.EventManager.OnChatBroadcast -= OnChatBroadcast;
119 m_scenes.Remove(scene);
120 }
121 }
107 } 122 }
108 123
109 public virtual void Close() 124 public virtual void Close()
@@ -160,7 +175,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
160 return; 175 return;
161 } 176 }
162 177
163 DeliverChatToAvatars(ChatSourceType.Agent, c); 178 if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
179 {
180 if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
181 c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
182 }
183 else
184 {
185 DeliverChatToAvatars(ChatSourceType.Agent, c);
186 }
164 } 187 }
165 188
166 public virtual void OnChatFromWorld(Object sender, OSChatMessage c) 189 public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
@@ -174,11 +197,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
174 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) 197 protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
175 { 198 {
176 string fromName = c.From; 199 string fromName = c.From;
200 string fromNamePrefix = "";
177 UUID fromID = UUID.Zero; 201 UUID fromID = UUID.Zero;
178 UUID ownerID = UUID.Zero; 202 UUID ownerID = UUID.Zero;
179 UUID targetID = c.TargetUUID;
180 string message = c.Message; 203 string message = c.Message;
181 Scene scene = (Scene)c.Scene; 204 IScene scene = c.Scene;
205 UUID destination = c.Destination;
182 Vector3 fromPos = c.Position; 206 Vector3 fromPos = c.Position;
183 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, 207 Vector3 regionPos = new Vector3(scene.RegionInfo.RegionLocX * Constants.RegionSize,
184 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 208 scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
@@ -188,10 +212,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
188 switch (sourceType) 212 switch (sourceType)
189 { 213 {
190 case ChatSourceType.Agent: 214 case ChatSourceType.Agent:
191 ScenePresence avatar = scene.GetScenePresence(c.Sender.AgentId); 215 if (!(scene is Scene))
216 {
217 m_log.WarnFormat("[CHAT]: scene {0} is not a Scene object, cannot obtain scene presence for {1}",
218 scene.RegionInfo.RegionName, c.Sender.AgentId);
219 return;
220 }
221 ScenePresence avatar = (scene as Scene).GetScenePresence(c.Sender.AgentId);
192 fromPos = avatar.AbsolutePosition; 222 fromPos = avatar.AbsolutePosition;
193 fromName = avatar.Name; 223 fromName = avatar.Name;
194 fromID = c.Sender.AgentId; 224 fromID = c.Sender.AgentId;
225 if (avatar.GodLevel >= 200)
226 {
227 fromNamePrefix = m_adminPrefix;
228 }
229 destination = UUID.Zero; // Avatars cant "SayTo"
195 ownerID = c.Sender.AgentId; 230 ownerID = c.Sender.AgentId;
196 231
197 break; 232 break;
@@ -210,38 +245,48 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
210 message = message.Substring(0, 1000); 245 message = message.Substring(0, 1000);
211 246
212// m_log.DebugFormat( 247// m_log.DebugFormat(
213// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}, targetID {5}", 248// "[CHAT]: DCTA: fromID {0} fromName {1}, region{2}, cType {3}, sType {4}",
214// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType, targetID); 249// fromID, fromName, scene.RegionInfo.RegionName, c.Type, sourceType);
215 250
216 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 251 HashSet<UUID> receiverIDs = new HashSet<UUID>();
217 252
218 if (targetID == UUID.Zero) 253 foreach (Scene s in m_scenes)
219 { 254 {
220 // This should use ForEachClient, but clients don't have a position. 255 // This should use ForEachClient, but clients don't have a position.
221 // If camera is moved into client, then camera position can be used 256 // If camera is moved into client, then camera position can be used
222 scene.ForEachScenePresence( 257 // MT: No, it can't, as chat is heard from the avatar position, not
258 // the camera position.
259 s.ForEachScenePresence(
223 delegate(ScenePresence presence) 260 delegate(ScenePresence presence)
224 { 261 {
225 if (TrySendChatMessage( 262 if (destination != UUID.Zero && presence.UUID != destination)
226 presence, fromPos, regionPos, fromID, ownerID, fromName, c.Type, message, sourceType, false)) 263 return;
227 receiverIDs.Add(presence.UUID); 264 ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
265 if (Presencecheck != null)
266 {
267 // This will pass all chat from objects. Not
268 // perfect, but it will do. For now. Better
269 // than the prior behavior of muting all
270 // objects on a parcel with access restrictions
271 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
272 {
273 if (destination != UUID.Zero)
274 {
275 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
276 receiverIDs.Add(presence.UUID);
277 }
278 else
279 {
280 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
281 receiverIDs.Add(presence.UUID);
282 }
283 }
284 }
228 } 285 }
229 ); 286 );
230 } 287 }
231 else 288
232 { 289 (scene as Scene).EventManager.TriggerOnChatToClients(
233 // This is a send to a specific client eg from llRegionSayTo
234 // no need to check distance etc, jand send is as say
235 ScenePresence presence = scene.GetScenePresence(targetID);
236 if (presence != null && !presence.IsChildAgent)
237 {
238 if (TrySendChatMessage(
239 presence, fromPos, regionPos, fromID, ownerID, fromName, ChatTypeEnum.Say, message, sourceType, true))
240 receiverIDs.Add(presence.UUID);
241 }
242 }
243
244 scene.EventManager.TriggerOnChatToClients(
245 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully); 290 fromID, receiverIDs, message, c.Type, fromPos, fromName, sourceType, ChatAudibleLevel.Fully);
246 } 291 }
247 292
@@ -280,28 +325,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
280 } 325 }
281 326
282 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); 327 // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
283
284 HashSet<UUID> receiverIDs = new HashSet<UUID>(); 328 HashSet<UUID> receiverIDs = new HashSet<UUID>();
285 329
286 ((Scene)c.Scene).ForEachRootClient( 330 if (c.Scene != null)
287 delegate(IClientAPI client) 331 {
288 { 332 ((Scene)c.Scene).ForEachRootClient
289 // don't forward SayOwner chat from objects to 333 (
290 // non-owner agents 334 delegate(IClientAPI client)
291 if ((c.Type == ChatTypeEnum.Owner) && 335 {
292 (null != c.SenderObject) && 336 // don't forward SayOwner chat from objects to
293 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 337 // non-owner agents
294 return; 338 if ((c.Type == ChatTypeEnum.Owner) &&
295 339 (null != c.SenderObject) &&
296 client.SendChatMessage( 340 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
297 c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, 341 return;
298 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 342
299 343 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
300 receiverIDs.Add(client.AgentId); 344 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
301 }); 345 receiverIDs.Add(client.AgentId);
302 346 }
303 (c.Scene as Scene).EventManager.TriggerOnChatToClients( 347 );
304 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully); 348 (c.Scene as Scene).EventManager.TriggerOnChatToClients(
349 fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
350 }
305 } 351 }
306 352
307 /// <summary> 353 /// <summary>
@@ -326,21 +372,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
326 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, 372 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
327 string message, ChatSourceType src, bool ignoreDistance) 373 string message, ChatSourceType src, bool ignoreDistance)
328 { 374 {
375 // don't send chat to child agents
376 if (presence.IsChildAgent) return false;
377
329 Vector3 fromRegionPos = fromPos + regionPos; 378 Vector3 fromRegionPos = fromPos + regionPos;
330 Vector3 toRegionPos = presence.AbsolutePosition + 379 Vector3 toRegionPos = presence.AbsolutePosition +
331 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, 380 new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize,
332 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); 381 presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
333 382
334 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); 383 int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
335 384
336 if (!ignoreDistance) 385 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
386 type == ChatTypeEnum.Say && dis > m_saydistance ||
387 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
337 { 388 {
338 if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || 389 return false;
339 type == ChatTypeEnum.Say && dis > m_saydistance ||
340 type == ChatTypeEnum.Shout && dis > m_shoutdistance)
341 {
342 return false;
343 }
344 } 390 }
345 391
346 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 392 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
@@ -350,5 +396,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
350 396
351 return true; 397 return true;
352 } 398 }
399
400 Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
401 public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
402 {
403 System.Threading.Timer Timer;
404 if (flags == 0)
405 {
406 FreezeCache.Add(target.ToString());
407 System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
408 Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
409 Timers.Add(target, Timer);
410 }
411 else
412 {
413 FreezeCache.Remove(target.ToString());
414 Timers.TryGetValue(target, out Timer);
415 Timers.Remove(target);
416 Timer.Dispose();
417 }
418 }
419
420 private void OnEndParcelFrozen(object avatar)
421 {
422 UUID target = (UUID)avatar;
423 FreezeCache.Remove(target.ToString());
424 System.Threading.Timer Timer;
425 Timers.TryGetValue(target, out Timer);
426 Timers.Remove(target);
427 Timer.Dispose();
428 }
353 } 429 }
354} \ No newline at end of file 430}
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index d26907b..0e7ab7e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -260,4 +260,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
260 return result; 260 return result;
261 } 261 }
262 } 262 }
263} \ No newline at end of file 263}
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 16673ec..89a4d30 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -41,9 +41,7 @@ using System.IO;
41using System.Web; 41using System.Web;
42using System.Xml; 42using System.Xml;
43using log4net; 43using log4net;
44
45using Mono.Addins; 44using Mono.Addins;
46
47using OpenMetaverse.Messages.Linden; 45using OpenMetaverse.Messages.Linden;
48using OpenMetaverse.StructuredData; 46using OpenMetaverse.StructuredData;
49using OpenSim.Framework.Capabilities; 47using OpenSim.Framework.Capabilities;
@@ -53,6 +51,8 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
53using OSDArray = OpenMetaverse.StructuredData.OSDArray; 51using OSDArray = OpenMetaverse.StructuredData.OSDArray;
54using OSDMap = OpenMetaverse.StructuredData.OSDMap; 52using OSDMap = OpenMetaverse.StructuredData.OSDMap;
55 53
54using Mono.Addins;
55
56namespace OpenSim.Region.CoreModules.Avatar.Gods 56namespace OpenSim.Region.CoreModules.Avatar.Gods
57{ 57{
58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")] 58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
@@ -66,6 +66,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
66 66
67 protected Scene m_scene; 67 protected Scene m_scene;
68 protected IDialogModule m_dialogModule; 68 protected IDialogModule m_dialogModule;
69
70 protected Dictionary<UUID, string> m_capsDict =
71 new Dictionary<UUID, string>();
72
69 protected IDialogModule DialogModule 73 protected IDialogModule DialogModule
70 { 74 {
71 get 75 get
@@ -87,6 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
87 m_scene.RegisterModuleInterface<IGodsModule>(this); 91 m_scene.RegisterModuleInterface<IGodsModule>(this);
88 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 92 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
89 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; 93 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
94 m_scene.EventManager.OnClientClosed += OnClientClosed;
90 scene.EventManager.OnIncomingInstantMessage += 95 scene.EventManager.OnIncomingInstantMessage +=
91 OnIncomingInstantMessage; 96 OnIncomingInstantMessage;
92 } 97 }
@@ -122,9 +127,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
122 client.OnRequestGodlikePowers -= RequestGodlikePowers; 127 client.OnRequestGodlikePowers -= RequestGodlikePowers;
123 } 128 }
124 129
130 private void OnClientClosed(UUID agentID, Scene scene)
131 {
132 m_capsDict.Remove(agentID);
133 }
134
125 private void OnRegisterCaps(UUID agentID, Caps caps) 135 private void OnRegisterCaps(UUID agentID, Caps caps)
126 { 136 {
127 string uri = "/CAPS/" + UUID.Random(); 137 string uri = "/CAPS/" + UUID.Random();
138 m_capsDict[agentID] = uri;
128 139
129 caps.RegisterHandler("UntrustedSimulatorMessage", 140 caps.RegisterHandler("UntrustedSimulatorMessage",
130 new RestStreamHandler("POST", uri, 141 new RestStreamHandler("POST", uri,
@@ -150,6 +161,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
150 UUID godSessionID = userData["GodSessionID"].AsUUID(); 161 UUID godSessionID = userData["GodSessionID"].AsUUID();
151 uint kickFlags = userData["KickFlags"].AsUInteger(); 162 uint kickFlags = userData["KickFlags"].AsUInteger();
152 string reason = userData["Reason"].AsString(); 163 string reason = userData["Reason"].AsString();
164
153 ScenePresence god = m_scene.GetScenePresence(godID); 165 ScenePresence god = m_scene.GetScenePresence(godID);
154 if (god == null || god.ControllingClient.SessionId != godSessionID) 166 if (god == null || god.ControllingClient.SessionId != godSessionID)
155 return String.Empty; 167 return String.Empty;
diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
deleted file mode 100644
index b735c61..0000000
--- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37
38using Mono.Addins;
39
40namespace OpenSim.Region.CoreModules.Avatar.Groups
41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
43 public class GroupsModule : ISharedRegionModule
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private Dictionary<UUID, GroupMembershipData> m_GroupMap =
49 new Dictionary<UUID, GroupMembershipData>();
50
51 private Dictionary<UUID, IClientAPI> m_ClientMap =
52 new Dictionary<UUID, IClientAPI>();
53
54 private UUID opensimulatorGroupID =
55 new UUID("00000000-68f9-1111-024e-222222111123");
56
57 private List<Scene> m_SceneList = new List<Scene>();
58
59 private static GroupMembershipData osGroup =
60 new GroupMembershipData();
61
62 private bool m_Enabled = false;
63
64 #region ISharedRegionModule Members
65
66 public void Initialise(IConfigSource config)
67 {
68 IConfig groupsConfig = config.Configs["Groups"];
69
70 if (groupsConfig == null)
71 {
72 m_log.Info("[GROUPS]: No configuration found. Using defaults");
73 }
74 else
75 {
76 m_Enabled = groupsConfig.GetBoolean("Enabled", false);
77 if (!m_Enabled)
78 {
79 m_log.Info("[GROUPS]: Groups disabled in configuration");
80 return;
81 }
82
83 if (groupsConfig.GetString("Module", "Default") != "Default")
84 {
85 m_Enabled = false;
86 return;
87 }
88 }
89
90 }
91
92 public void AddRegion(Scene scene)
93 {
94 if (!m_Enabled)
95 return;
96
97 lock (m_SceneList)
98 {
99 if (!m_SceneList.Contains(scene))
100 {
101 if (m_SceneList.Count == 0)
102 {
103 osGroup.GroupID = opensimulatorGroupID;
104 osGroup.GroupName = "OpenSimulator Testing";
105 osGroup.GroupPowers =
106 (uint)(GroupPowers.AllowLandmark |
107 GroupPowers.AllowSetHome);
108 m_GroupMap[opensimulatorGroupID] = osGroup;
109 }
110 m_SceneList.Add(scene);
111 }
112 }
113
114 scene.EventManager.OnNewClient += OnNewClient;
115 scene.EventManager.OnClientClosed += OnClientClosed;
116 // scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
117 }
118
119 public void RemoveRegion(Scene scene)
120 {
121 if (!m_Enabled)
122 return;
123
124 lock (m_SceneList)
125 {
126 if (m_SceneList.Contains(scene))
127 m_SceneList.Remove(scene);
128 }
129
130 scene.EventManager.OnNewClient -= OnNewClient;
131 scene.EventManager.OnClientClosed -= OnClientClosed;
132 }
133
134 public void RegionLoaded(Scene scene)
135 {
136 }
137
138 public void PostInitialise()
139 {
140 }
141
142 public void Close()
143 {
144 if (!m_Enabled)
145 return;
146
147// m_log.Debug("[GROUPS]: Shutting down group module.");
148
149 lock (m_ClientMap)
150 {
151 m_ClientMap.Clear();
152 }
153
154 lock (m_GroupMap)
155 {
156 m_GroupMap.Clear();
157 }
158 }
159
160 public string Name
161 {
162 get { return "GroupsModule"; }
163 }
164
165 public Type ReplaceableInterface
166 {
167 get { return null; }
168 }
169
170 #endregion
171
172 private void OnNewClient(IClientAPI client)
173 {
174 // Subscribe to instant messages
175// client.OnInstantMessage += OnInstantMessage;
176 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
177 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
178 lock (m_ClientMap)
179 {
180 if (!m_ClientMap.ContainsKey(client.AgentId))
181 {
182 m_ClientMap.Add(client.AgentId, client);
183 }
184 }
185
186 GroupMembershipData[] updateGroups = new GroupMembershipData[1];
187 updateGroups[0] = osGroup;
188
189 client.SendGroupMembership(updateGroups);
190 }
191
192 private void OnAgentDataUpdateRequest(IClientAPI remoteClient,
193 UUID AgentID, UUID SessionID)
194 {
195 UUID ActiveGroupID;
196 string ActiveGroupName;
197 ulong ActiveGroupPowers;
198
199 string firstname = remoteClient.FirstName;
200 string lastname = remoteClient.LastName;
201
202 string ActiveGroupTitle = "I IZ N0T";
203
204 ActiveGroupID = osGroup.GroupID;
205 ActiveGroupName = osGroup.GroupName;
206 ActiveGroupPowers = osGroup.GroupPowers;
207
208 remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname,
209 lastname, ActiveGroupPowers, ActiveGroupName,
210 ActiveGroupTitle);
211 }
212
213// private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
214// {
215// }
216
217// private void OnGridInstantMessage(GridInstantMessage msg)
218// {
219// // Trigger the above event handler
220// OnInstantMessage(null, msg);
221// }
222
223 private void HandleUUIDGroupNameRequest(UUID id,IClientAPI remote_client)
224 {
225 string groupnamereply = "Unknown";
226 UUID groupUUID = UUID.Zero;
227
228 lock (m_GroupMap)
229 {
230 if (m_GroupMap.ContainsKey(id))
231 {
232 GroupMembershipData grp = m_GroupMap[id];
233 groupnamereply = grp.GroupName;
234 groupUUID = grp.GroupID;
235 }
236 }
237 remote_client.SendGroupNameReply(groupUUID, groupnamereply);
238 }
239
240 private void OnClientClosed(UUID agentID, Scene scene)
241 {
242 lock (m_ClientMap)
243 {
244 if (m_ClientMap.ContainsKey(agentID))
245 {
246// IClientAPI cli = m_ClientMap[agentID];
247// if (cli != null)
248// {
249// //m_log.Info("[GROUPS]: Removing all reference to groups for " + cli.Name);
250// }
251// else
252// {
253// //m_log.Info("[GROUPS]: Removing all reference to groups for " + agentID.ToString());
254// }
255 m_ClientMap.Remove(agentID);
256 }
257 }
258 }
259 }
260}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index c33a296..55e30a0 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -27,6 +27,7 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using System.Timers;
30using log4net; 31using log4net;
31using Mono.Addins; 32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
@@ -44,6 +45,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
44 private static readonly ILog m_log = LogManager.GetLogger( 45 private static readonly ILog m_log = LogManager.GetLogger(
45 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
46 47
48 private Timer m_logTimer = new Timer(10000);
49 private List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
50 private string m_restUrl;
51
47 /// <value> 52 /// <value>
48 /// Is this module enabled? 53 /// Is this module enabled?
49 /// </value> 54 /// </value>
@@ -63,9 +68,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
63 "InstantMessageModule", "InstantMessageModule") != 68 "InstantMessageModule", "InstantMessageModule") !=
64 "InstantMessageModule") 69 "InstantMessageModule")
65 return; 70 return;
71 m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
66 } 72 }
67 73
68 m_enabled = true; 74 m_enabled = true;
75 m_logTimer.AutoReset = false;
76 m_logTimer.Elapsed += LogTimerElapsed;
69 } 77 }
70 78
71 public void AddRegion(Scene scene) 79 public void AddRegion(Scene scene)
@@ -150,6 +158,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
150 { 158 {
151 byte dialog = im.dialog; 159 byte dialog = im.dialog;
152 160
161 if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
162 LogInstantMesssage(im);
163
153 if (dialog != (byte)InstantMessageDialog.MessageFromAgent 164 if (dialog != (byte)InstantMessageDialog.MessageFromAgent
154 && dialog != (byte)InstantMessageDialog.StartTyping 165 && dialog != (byte)InstantMessageDialog.StartTyping
155 && dialog != (byte)InstantMessageDialog.StopTyping 166 && dialog != (byte)InstantMessageDialog.StopTyping
@@ -159,6 +170,32 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
159 return; 170 return;
160 } 171 }
161 172
173 //DateTime dt = DateTime.UtcNow;
174
175 // Ticks from UtcNow, but make it look like local. Evil, huh?
176 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
177
178 //try
179 //{
180 // // Convert that to the PST timezone
181 // TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
182 // dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
183 //}
184 //catch
185 //{
186 // //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
187 //}
188
189 //// And make it look local again to fool the unix time util
190 //dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
191
192 // If client is null, this message comes from storage and IS offline
193 if (client != null)
194 im.offline = 0;
195
196 if (im.offline == 0)
197 im.timestamp = (uint)Util.UnixTimeSinceEpoch();
198
162 if (m_TransferModule != null) 199 if (m_TransferModule != null)
163 { 200 {
164 if (client != null) 201 if (client != null)
@@ -202,5 +239,35 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
202 // 239 //
203 OnInstantMessage(null, msg); 240 OnInstantMessage(null, msg);
204 } 241 }
242
243 private void LogInstantMesssage(GridInstantMessage im)
244 {
245 if (m_logData.Count < 20)
246 {
247 // Restart the log write timer
248 m_logTimer.Stop();
249 }
250 if (!m_logTimer.Enabled)
251 m_logTimer.Start();
252
253 lock (m_logData)
254 {
255 m_logData.Add(im);
256 }
257 }
258
259 private void LogTimerElapsed(object source, ElapsedEventArgs e)
260 {
261 lock (m_logData)
262 {
263 if (m_restUrl != String.Empty && m_logData.Count > 0)
264 {
265 bool success = SynchronousRestObjectRequester.MakeRequest<List<GridInstantMessage>, bool>("POST", m_restUrl + "/LogMessages/", m_logData);
266 if (!success)
267 m_log.ErrorFormat("[INSTANT MESSAGE]: Failed to save log data");
268 }
269 m_logData.Clear();
270 }
271 }
205 } 272 }
206} 273}
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index fa935cd..1627f6c 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private bool m_Enabled = false; 52 private bool m_Enabled = false;
53 protected string m_MessageKey = String.Empty;
53 protected List<Scene> m_Scenes = new List<Scene>(); 54 protected List<Scene> m_Scenes = new List<Scene>();
54 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>(); 55 protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
55 56
@@ -69,14 +70,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
69 public virtual void Initialise(IConfigSource config) 70 public virtual void Initialise(IConfigSource config)
70 { 71 {
71 IConfig cnf = config.Configs["Messaging"]; 72 IConfig cnf = config.Configs["Messaging"];
72 if (cnf != null && cnf.GetString( 73 if (cnf != null)
73 "MessageTransferModule", "MessageTransferModule") !=
74 "MessageTransferModule")
75 { 74 {
76 m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); 75 if (cnf.GetString("MessageTransferModule",
77 return; 76 "MessageTransferModule") != "MessageTransferModule")
78 } 77 {
78 return;
79 }
79 80
81 m_MessageKey = cnf.GetString("MessageKey", String.Empty);
82 }
83 m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
80 m_Enabled = true; 84 m_Enabled = true;
81 } 85 }
82 86
@@ -135,6 +139,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
135 { 139 {
136 UUID toAgentID = new UUID(im.toAgentID); 140 UUID toAgentID = new UUID(im.toAgentID);
137 141
142 if (toAgentID == UUID.Zero)
143 return;
144
138 // Try root avatar only first 145 // Try root avatar only first
139 foreach (Scene scene in m_Scenes) 146 foreach (Scene scene in m_Scenes)
140 { 147 {
@@ -249,6 +256,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
249 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 256 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
250 && requestData.ContainsKey("binary_bucket")) 257 && requestData.ContainsKey("binary_bucket"))
251 { 258 {
259 if (m_MessageKey != String.Empty)
260 {
261 XmlRpcResponse error_resp = new XmlRpcResponse();
262 Hashtable error_respdata = new Hashtable();
263 error_respdata["success"] = "FALSE";
264 error_resp.Value = error_respdata;
265
266 if (!requestData.Contains("message_key"))
267 return error_resp;
268 if (m_MessageKey != (string)requestData["message_key"])
269 return error_resp;
270 }
271
252 // Do the easy way of validating the UUIDs 272 // Do the easy way of validating the UUIDs
253 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID); 273 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
254 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID); 274 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -425,24 +445,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
425 return resp; 445 return resp;
426 } 446 }
427 447
428 /// <summary> 448 private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
429 /// delegate for sending a grid instant message asynchronously
430 /// </summary>
431 public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
432 449
433 protected virtual void GridInstantMessageCompleted(IAsyncResult iar) 450 private class GIM {
434 { 451 public GridInstantMessage im;
435 GridInstantMessageDelegate icon = 452 public MessageResultNotification result;
436 (GridInstantMessageDelegate)iar.AsyncState; 453 };
437 icon.EndInvoke(iar);
438 }
439 454
455 private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
456 private int numInstantMessageThreads = 0;
440 457
441 protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) 458 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
442 { 459 {
443 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; 460 lock (pendingInstantMessages) {
461 if (numInstantMessageThreads >= 4) {
462 GIM gim = new GIM();
463 gim.im = im;
464 gim.result = result;
465 pendingInstantMessages.Enqueue(gim);
466 } else {
467 ++ numInstantMessageThreads;
468 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
469 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
470 d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
471 }
472 }
473 }
444 474
445 d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); 475 private void GridInstantMessageCompleted(IAsyncResult iar)
476 {
477 GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
478 d.EndInvoke(iar);
446 } 479 }
447 480
448 /// <summary> 481 /// <summary>
@@ -457,8 +490,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
457 /// Pass in 0 the first time this method is called. It will be called recursively with the last 490 /// Pass in 0 the first time this method is called. It will be called recursively with the last
458 /// regionhandle tried 491 /// regionhandle tried
459 /// </param> 492 /// </param>
460 protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) 493 private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
461 { 494 {
495 GIM gim;
496 do {
497 try {
498 SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
499 } catch (Exception e) {
500 m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
501 }
502 lock (pendingInstantMessages) {
503 if (pendingInstantMessages.Count > 0) {
504 gim = pendingInstantMessages.Dequeue();
505 im = gim.im;
506 result = gim.result;
507 } else {
508 gim = null;
509 -- numInstantMessageThreads;
510 //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
511 }
512 }
513 } while (gim != null);
514 }
515 private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
516 {
517
462 UUID toAgentID = new UUID(im.toAgentID); 518 UUID toAgentID = new UUID(im.toAgentID);
463 519
464 PresenceInfo upd = null; 520 PresenceInfo upd = null;
@@ -525,7 +581,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
525 581
526 if (upd != null) 582 if (upd != null)
527 { 583 {
528 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, 584 GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
529 upd.RegionID); 585 upd.RegionID);
530 if (reginfo != null) 586 if (reginfo != null)
531 { 587 {
@@ -674,6 +730,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
674 gim["position_z"] = msg.Position.Z.ToString(); 730 gim["position_z"] = msg.Position.Z.ToString();
675 gim["region_id"] = msg.RegionID.ToString(); 731 gim["region_id"] = msg.RegionID.ToString();
676 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 732 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
733 if (m_MessageKey != String.Empty)
734 gim["message_key"] = m_MessageKey;
677 return gim; 735 return gim;
678 } 736 }
679 737
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 7d763fa..2d46276 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -173,7 +173,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
173 173
174 private void RetrieveInstantMessages(IClientAPI client) 174 private void RetrieveInstantMessages(IClientAPI client)
175 { 175 {
176 if (m_RestURL != "") 176 if (m_RestURL == String.Empty)
177 {
178 return;
179 }
180 else
177 { 181 {
178 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); 182 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
179 183
@@ -181,25 +185,28 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
181 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>( 185 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
182 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 186 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
183 187
184 if (msglist == null) 188 if (msglist != null)
185 m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
186
187 foreach (GridInstantMessage im in msglist)
188 { 189 {
189 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) 190 foreach (GridInstantMessage im in msglist)
190 // send it directly or else the item will be given twice
191 client.SendInstantMessage(im);
192 else
193 { 191 {
194 // Send through scene event manager so all modules get a chance 192 if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
195 // to look at this message before it gets delivered. 193 // send it directly or else the item will be given twice
196 // 194 client.SendInstantMessage(im);
197 // Needed for proper state management for stored group 195 else
198 // invitations 196 {
199 // 197 // Send through scene event manager so all modules get a chance
200 Scene s = FindScene(client.AgentId); 198 // to look at this message before it gets delivered.
201 if (s != null) 199 //
202 s.EventManager.TriggerIncomingInstantMessage(im); 200 // Needed for proper state management for stored group
201 // invitations
202 //
203
204 im.offline = 1;
205
206 Scene s = FindScene(client.AgentId);
207 if (s != null)
208 s.EventManager.TriggerIncomingInstantMessage(im);
209 }
203 } 210 }
204 } 211 }
205 } 212 }
@@ -211,24 +218,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
211 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 218 im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
212 im.dialog != (byte)InstantMessageDialog.GroupNotice && 219 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
213 im.dialog != (byte)InstantMessageDialog.GroupInvitation && 220 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
214 im.dialog != (byte)InstantMessageDialog.InventoryOffered) 221 im.dialog != (byte)InstantMessageDialog.InventoryOffered &&
222 im.dialog != (byte)InstantMessageDialog.TaskInventoryOffered)
215 { 223 {
216 return; 224 return;
217 } 225 }
218 226
219 if (!m_ForwardOfflineGroupMessages)
220 {
221 if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
222 im.dialog == (byte)InstantMessageDialog.GroupInvitation)
223 return;
224 }
225
226 Scene scene = FindScene(new UUID(im.fromAgentID)); 227 Scene scene = FindScene(new UUID(im.fromAgentID));
227 if (scene == null) 228 if (scene == null)
228 scene = m_SceneList[0]; 229 scene = m_SceneList[0];
229 230
230 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 231 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
231 "POST", m_RestURL+"/SaveMessage/", im); 232 "POST", m_RestURL+"/SaveMessage/?scope=" +
233 scene.RegionInfo.ScopeID.ToString(), im);
232 234
233 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 235 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
234 { 236 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 98285e9..659b178 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -652,4 +652,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
652 m_assetsLoaded = true; 652 m_assetsLoaded = true;
653 } 653 }
654 } 654 }
655} \ No newline at end of file 655}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 849449b..f4f9e2d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -519,6 +519,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
519 return null; 519 return null;
520 } 520 }
521 521
522 return account;
523 /*
522 try 524 try
523 { 525 {
524 string encpass = Util.Md5Hash(pass); 526 string encpass = Util.Md5Hash(pass);
@@ -539,6 +541,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
539 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message); 541 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message);
540 return null; 542 return null;
541 } 543 }
544 */
542 } 545 }
543 546
544 /// <summary> 547 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index 1417a19..e285f21 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
@@ -164,8 +164,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
164 if (im.binaryBucket.Length < 17) // Invalid 164 if (im.binaryBucket.Length < 17) // Invalid
165 return; 165 return;
166 166
167 UUID receipientID = new UUID(im.toAgentID); 167 UUID recipientID = new UUID(im.toAgentID);
168 ScenePresence user = scene.GetScenePresence(receipientID); 168 ScenePresence user = scene.GetScenePresence(recipientID);
169 UUID copyID; 169 UUID copyID;
170 170
171 // First byte is the asset type 171 // First byte is the asset type
@@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
180 folderID, new UUID(im.toAgentID)); 180 folderID, new UUID(im.toAgentID));
181 181
182 InventoryFolderBase folderCopy 182 InventoryFolderBase folderCopy
183 = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); 183 = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero);
184 184
185 if (folderCopy == null) 185 if (folderCopy == null)
186 { 186 {
@@ -239,6 +239,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
239 im.imSessionID = copyID.Guid; 239 im.imSessionID = copyID.Guid;
240 } 240 }
241 241
242 im.offline = 0;
243
242 // Send the IM to the recipient. The item is already 244 // Send the IM to the recipient. The item is already
243 // in their inventory, so it will not be lost if 245 // in their inventory, so it will not be lost if
244 // they are offline. 246 // they are offline.
@@ -258,8 +260,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
258 }); 260 });
259 } 261 }
260 } 262 }
261 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) 263 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
264 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
262 { 265 {
266 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
267 IInventoryService invService = scene.InventoryService;
268
269 // Special case: folder redirect.
270 // RLV uses this
271 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
272 {
273 InventoryFolderBase folder = new InventoryFolderBase(inventoryID, client.AgentId);
274 folder = invService.GetFolder(folder);
275
276 if (folder != null)
277 {
278 if (im.binaryBucket.Length >= 16)
279 {
280 UUID destFolderID = new UUID(im.binaryBucket, 0);
281 if (destFolderID != UUID.Zero)
282 {
283 InventoryFolderBase destFolder = new InventoryFolderBase(destFolderID, client.AgentId);
284 destFolder = invService.GetFolder(destFolder);
285 if (destFolder != null)
286 {
287 if (folder.ParentID != destFolder.ID)
288 {
289 folder.ParentID = destFolder.ID;
290 invService.MoveFolder(folder);
291 client.SendBulkUpdateInventory(folder);
292 }
293 }
294 }
295 }
296 }
297 }
298
263 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 299 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
264 300
265 if (user != null) // Local 301 if (user != null) // Local
@@ -269,27 +305,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
269 else 305 else
270 { 306 {
271 if (m_TransferModule != null) 307 if (m_TransferModule != null)
272 m_TransferModule.SendInstantMessage(im, delegate(bool success) { 308 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
273
274 // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
275 // and is apparently supposed to fix bulk inventory updates after accepting items. But
276 // instead it appears to cause two copies of an accepted folder for the receiving user in
277 // at least some cases. Folder/item update is already done when the offer is made (see code above)
278
279// // Send BulkUpdateInventory
280// IInventoryService invService = scene.InventoryService;
281// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
282//
283// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
284// folder = invService.GetFolder(folder);
285//
286// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
287//
288// // If the user has left the scene by the time the message comes back then we can't send
289// // them the update.
290// if (fromUser != null)
291// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
292 });
293 } 309 }
294 } 310 }
295 311
@@ -402,6 +418,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
402 previousParentFolderID = folder.ParentID; 418 previousParentFolderID = folder.ParentID;
403 folder.ParentID = trashFolder.ID; 419 folder.ParentID = trashFolder.ID;
404 invService.MoveFolder(folder); 420 invService.MoveFolder(folder);
421 client.SendBulkUpdateInventory(folder);
405 } 422 }
406 } 423 }
407 424
@@ -451,22 +468,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
451 /// 468 ///
452 /// </summary> 469 /// </summary>
453 /// <param name="msg"></param> 470 /// <param name="msg"></param>
454 private void OnGridInstantMessage(GridInstantMessage msg) 471 private void OnGridInstantMessage(GridInstantMessage im)
455 { 472 {
456 // Check if this is ours to handle 473 // Check if this is ours to handle
457 // 474 //
458 Scene scene = FindClientScene(new UUID(msg.toAgentID)); 475 Scene scene = FindClientScene(new UUID(im.toAgentID));
459 476
460 if (scene == null) 477 if (scene == null)
461 return; 478 return;
462 479
463 // Find agent to deliver to 480 // Find agent to deliver to
464 // 481 //
465 ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); 482 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
483 if (user == null)
484 return;
485
486 // This requires a little bit of processing because we have to make the
487 // new item visible in the recipient's inventory here
488 //
489 if (im.dialog == (byte) InstantMessageDialog.InventoryOffered)
490 {
491 if (im.binaryBucket.Length < 17) // Invalid
492 return;
493
494 UUID recipientID = new UUID(im.toAgentID);
495
496 // First byte is the asset type
497 AssetType assetType = (AssetType)im.binaryBucket[0];
498
499 if (AssetType.Folder == assetType)
500 {
501 UUID folderID = new UUID(im.binaryBucket, 1);
502
503 InventoryFolderBase given =
504 new InventoryFolderBase(folderID, recipientID);
505 InventoryFolderBase folder =
506 scene.InventoryService.GetFolder(given);
507
508 if (folder != null)
509 user.ControllingClient.SendBulkUpdateInventory(folder);
510 }
511 else
512 {
513 UUID itemID = new UUID(im.binaryBucket, 1);
466 514
467 // Just forward to local handling 515 InventoryItemBase given =
468 OnInstantMessage(user.ControllingClient, msg); 516 new InventoryItemBase(itemID, recipientID);
517 InventoryItemBase item =
518 scene.InventoryService.GetItem(given);
519
520 if (item != null)
521 {
522 user.ControllingClient.SendBulkUpdateInventory(item);
523 }
524 }
525 user.ControllingClient.SendInstantMessage(im);
526 }
527 if (im.dialog == (byte) InstantMessageDialog.TaskInventoryOffered)
528 {
529 if (im.binaryBucket.Length < 1) // Invalid
530 return;
531
532 UUID recipientID = new UUID(im.toAgentID);
469 533
534 // Bucket is the asset type
535 AssetType assetType = (AssetType)im.binaryBucket[0];
536
537 if (AssetType.Folder == assetType)
538 {
539 UUID folderID = new UUID(im.imSessionID);
540
541 InventoryFolderBase given =
542 new InventoryFolderBase(folderID, recipientID);
543 InventoryFolderBase folder =
544 scene.InventoryService.GetFolder(given);
545
546 if (folder != null)
547 user.ControllingClient.SendBulkUpdateInventory(folder);
548 }
549 else
550 {
551 UUID itemID = new UUID(im.imSessionID);
552
553 InventoryItemBase given =
554 new InventoryItemBase(itemID, recipientID);
555 InventoryItemBase item =
556 scene.InventoryService.GetItem(given);
557
558 if (item != null)
559 {
560 user.ControllingClient.SendBulkUpdateInventory(item);
561 }
562 }
563
564 // Fix up binary bucket since this may be 17 chars long here
565 Byte[] bucket = new Byte[1];
566 bucket[0] = im.binaryBucket[0];
567 im.binaryBucket = bucket;
568
569 user.ControllingClient.SendInstantMessage(im);
570 }
571 else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted ||
572 im.dialog == (byte) InstantMessageDialog.InventoryDeclined ||
573 im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined ||
574 im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
575 {
576 user.ControllingClient.SendInstantMessage(im);
577 }
470 } 578 }
471 } 579 }
472} 580}
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index 7f4606b..0c64f19 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -163,16 +163,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
163 scene.RegionInfo.RegionHandle, 163 scene.RegionInfo.RegionHandle,
164 (uint)presence.AbsolutePosition.X, 164 (uint)presence.AbsolutePosition.X,
165 (uint)presence.AbsolutePosition.Y, 165 (uint)presence.AbsolutePosition.Y,
166 (uint)Math.Ceiling(presence.AbsolutePosition.Z)); 166 (uint)presence.AbsolutePosition.Z + 2);
167 167
168 m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); 168 m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType);
169 169
170 GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, 170 GridInstantMessage m;
171 client.FirstName+" "+client.LastName, targetid, 171
172 (byte)InstantMessageDialog.RequestTeleport, false, 172 if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid)))
173 message, dest, false, presence.AbsolutePosition, 173 {
174 new Byte[0], true); 174 m = new GridInstantMessage(scene, client.AgentId,
175 175 client.FirstName+" "+client.LastName, targetid,
176 (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
177 message, dest, false, presence.AbsolutePosition,
178 new Byte[0], true);
179 }
180 else
181 {
182 m = new GridInstantMessage(scene, client.AgentId,
183 client.FirstName+" "+client.LastName, targetid,
184 (byte)InstantMessageDialog.RequestTeleport, false,
185 message, dest, false, presence.AbsolutePosition,
186 new Byte[0], true);
187 }
188
176 if (m_TransferModule != null) 189 if (m_TransferModule != null)
177 { 190 {
178 m_TransferModule.SendInstantMessage(m, 191 m_TransferModule.SendInstantMessage(m,
@@ -207,7 +220,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
207 { 220 {
208 // Forward remote teleport requests 221 // Forward remote teleport requests
209 // 222 //
210 if (msg.dialog != 22) 223 if (msg.dialog != (byte)InstantMessageDialog.RequestTeleport &&
224 msg.dialog != (byte)InstantMessageDialog.GodLikeRequestTeleport)
211 return; 225 return;
212 226
213 if (m_TransferModule != null) 227 if (m_TransferModule != null)