diff options
author | Kevin Cozens | 2013-08-02 15:26:28 -0400 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-10-15 23:07:49 +0100 |
commit | 5ca7395e175b476fd20fcf97383c8eb09b64ae3a (patch) | |
tree | f04df0fca60a4a1af4419d7fd34f9b149df4f60d /OpenSim/Region/OptionalModules/Avatar | |
parent | Made terrain uploads thread-safe (diff) | |
download | opensim-SC-5ca7395e175b476fd20fcf97383c8eb09b64ae3a.zip opensim-SC-5ca7395e175b476fd20fcf97383c8eb09b64ae3a.tar.gz opensim-SC-5ca7395e175b476fd20fcf97383c8eb09b64ae3a.tar.bz2 opensim-SC-5ca7395e175b476fd20fcf97383c8eb09b64ae3a.tar.xz |
Added support for attachments to group notices when using Flotsam groups.
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | 172 |
1 files changed, 122 insertions, 50 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d744a14..d09d3ad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |||
@@ -39,6 +39,7 @@ using OpenSim.Framework.Communications; | |||
39 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using System.Text; | ||
42 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | 43 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; |
43 | 44 | ||
44 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | 45 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups |
@@ -421,44 +422,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
421 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); | 422 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); |
422 | string Message = im.message.Substring(Subject.Length + 1); | 423 | string Message = im.message.Substring(Subject.Length + 1); |
423 | 424 | ||
425 | InventoryItemBase item = null; | ||
426 | bool hasAttachment = false; | ||
427 | UUID itemID = UUID.Zero; //Assignment to quiet compiler | ||
428 | UUID ownerID = UUID.Zero; //Assignment to quiet compiler | ||
424 | byte[] bucket; | 429 | byte[] bucket; |
425 | 430 | ||
426 | if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) | 431 | if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) |
427 | { | ||
428 | bucket = new byte[19]; | ||
429 | bucket[0] = 0; //dunno | ||
430 | bucket[1] = 0; //dunno | ||
431 | GroupID.ToBytes(bucket, 2); | ||
432 | bucket[18] = 0; //dunno | ||
433 | } | ||
434 | else | ||
435 | { | 432 | { |
436 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); | 433 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); |
437 | binBucket = binBucket.Remove(0, 14).Trim(); | 434 | binBucket = binBucket.Remove(0, 14).Trim(); |
438 | if (m_debugEnabled) | 435 | |
436 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | ||
437 | if (binBucketOSD is OSD) | ||
439 | { | 438 | { |
440 | m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); | 439 | OSDMap binBucketMap = (OSDMap)binBucketOSD; |
440 | |||
441 | itemID = binBucketMap["item_id"].AsUUID(); | ||
442 | ownerID = binBucketMap["owner_id"].AsUUID(); | ||
441 | 443 | ||
442 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | 444 | //Attempt to get the details of the attached item. |
443 | 445 | //If sender doesn't own the attachment, the item | |
444 | foreach (string key in binBucketOSD.Keys) | 446 | //variable will be set to null and attachment will |
447 | //not be included with the group notice. | ||
448 | Scene scene = (Scene)remoteClient.Scene; | ||
449 | item = new InventoryItemBase(itemID, ownerID); | ||
450 | item = scene.InventoryService.GetItem(item); | ||
451 | |||
452 | if (item != null) | ||
445 | { | 453 | { |
446 | if (binBucketOSD.ContainsKey(key)) | 454 | //Got item details so include the attachment. |
447 | { | 455 | hasAttachment = true; |
448 | m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); | ||
449 | } | ||
450 | } | 456 | } |
451 | } | 457 | } |
452 | 458 | else | |
453 | // treat as if no attachment | 459 | { |
460 | m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | if (hasAttachment) | ||
465 | { | ||
466 | //Bucket contains information about attachment. | ||
467 | // | ||
468 | //Byte offset and description of bucket data: | ||
469 | //0: 1 byte indicating if attachment is present | ||
470 | //1: 1 byte indicating the type of attachment | ||
471 | //2: 16 bytes - Group UUID | ||
472 | //18: 16 bytes - UUID of the attachment owner | ||
473 | //34: 16 bytes - UUID of the attachment | ||
474 | //50: variable - Name of the attachment | ||
475 | //??: NUL byte to terminate the attachment name | ||
476 | byte[] name = Encoding.UTF8.GetBytes(item.Name); | ||
477 | bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name | ||
478 | bucket[0] = 1; //Has attachment flag | ||
479 | bucket[1] = (byte)item.InvType; //Type of Attachment | ||
480 | GroupID.ToBytes(bucket, 2); | ||
481 | ownerID.ToBytes(bucket, 18); | ||
482 | itemID.ToBytes(bucket, 34); | ||
483 | name.CopyTo(bucket, 50); | ||
484 | } | ||
485 | else | ||
486 | { | ||
454 | bucket = new byte[19]; | 487 | bucket = new byte[19]; |
455 | bucket[0] = 0; //dunno | 488 | bucket[0] = 0; //Has attachment flag |
456 | bucket[1] = 0; //dunno | 489 | bucket[1] = 0; //Type of attachment |
457 | GroupID.ToBytes(bucket, 2); | 490 | GroupID.ToBytes(bucket, 2); |
458 | bucket[18] = 0; //dunno | 491 | bucket[18] = 0; //NUL terminate name of attachment |
459 | } | 492 | } |
460 | 493 | ||
461 | |||
462 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); | 494 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); |
463 | if (OnNewGroupNotice != null) | 495 | if (OnNewGroupNotice != null) |
464 | { | 496 | { |
@@ -483,7 +515,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
483 | 515 | ||
484 | if (member.AcceptNotices) | 516 | if (member.AcceptNotices) |
485 | { | 517 | { |
486 | // Build notice IIM | 518 | // Build notice IM |
487 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); | 519 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); |
488 | 520 | ||
489 | msg.toAgentID = member.AgentID.Guid; | 521 | msg.toAgentID = member.AgentID.Guid; |
@@ -492,10 +524,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
492 | } | 524 | } |
493 | } | 525 | } |
494 | } | 526 | } |
495 | 527 | ||
528 | if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) | ||
529 | { | ||
530 | //Is bucket large enough to hold UUID of the attachment? | ||
531 | if (im.binaryBucket.Length < 16) | ||
532 | return; | ||
533 | |||
534 | UUID noticeID = new UUID(im.imSessionID); | ||
535 | |||
536 | GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); | ||
537 | if (notice != null) | ||
538 | { | ||
539 | UUID giver = new UUID(notice.BinaryBucket, 18); | ||
540 | UUID attachmentUUID = new UUID(notice.BinaryBucket, 34); | ||
541 | |||
542 | if (m_debugEnabled) | ||
543 | m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); | ||
544 | |||
545 | InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, | ||
546 | giver, attachmentUUID); | ||
547 | |||
548 | if (itemCopy == null) | ||
549 | { | ||
550 | remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); | ||
555 | } | ||
556 | } | ||
557 | |||
496 | // Interop, received special 210 code for ejecting a group member | 558 | // Interop, received special 210 code for ejecting a group member |
497 | // this only works within the comms servers domain, and won't work hypergrid | 559 | // this only works within the comms servers domain, and won't work hypergrid |
498 | // TODO:FIXME: Use a presense server of some kind to find out where the | 560 | // TODO:FIXME: Use a presence server of some kind to find out where the |
499 | // client actually is, and try contacting that region directly to notify them, | 561 | // client actually is, and try contacting that region directly to notify them, |
500 | // or provide the notification via xmlrpc update queue | 562 | // or provide the notification via xmlrpc update queue |
501 | if ((im.dialog == 210)) | 563 | if ((im.dialog == 210)) |
@@ -873,26 +935,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
873 | 935 | ||
874 | if (data != null) | 936 | if (data != null) |
875 | { | 937 | { |
876 | GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); | 938 | GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); |
877 | |||
878 | GridInstantMessage msg = new GridInstantMessage(); | ||
879 | msg.imSessionID = UUID.Zero.Guid; | ||
880 | msg.fromAgentID = data.GroupID.Guid; | ||
881 | msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; | ||
882 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
883 | msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; | ||
884 | msg.message = data.noticeData.Subject + "|" + data.Message; | ||
885 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; | ||
886 | msg.fromGroup = true; | ||
887 | msg.offline = (byte)0; | ||
888 | msg.ParentEstateID = 0; | ||
889 | msg.Position = Vector3.Zero; | ||
890 | msg.RegionID = UUID.Zero.Guid; | ||
891 | msg.binaryBucket = data.BinaryBucket; | ||
892 | 939 | ||
893 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); | 940 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); |
894 | } | 941 | } |
895 | |||
896 | } | 942 | } |
897 | 943 | ||
898 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) | 944 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) |
@@ -900,10 +946,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
900 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 946 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
901 | 947 | ||
902 | GridInstantMessage msg = new GridInstantMessage(); | 948 | GridInstantMessage msg = new GridInstantMessage(); |
903 | msg.imSessionID = UUID.Zero.Guid; | 949 | byte[] bucket; |
950 | |||
951 | msg.imSessionID = groupNoticeID.Guid; | ||
904 | msg.toAgentID = agentID.Guid; | 952 | msg.toAgentID = agentID.Guid; |
905 | msg.dialog = dialog; | 953 | msg.dialog = dialog; |
906 | // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; | ||
907 | msg.fromGroup = true; | 954 | msg.fromGroup = true; |
908 | msg.offline = (byte)0; | 955 | msg.offline = (byte)0; |
909 | msg.ParentEstateID = 0; | 956 | msg.ParentEstateID = 0; |
@@ -917,13 +964,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
917 | msg.timestamp = info.noticeData.Timestamp; | 964 | msg.timestamp = info.noticeData.Timestamp; |
918 | msg.fromAgentName = info.noticeData.FromName; | 965 | msg.fromAgentName = info.noticeData.FromName; |
919 | msg.message = info.noticeData.Subject + "|" + info.Message; | 966 | msg.message = info.noticeData.Subject + "|" + info.Message; |
920 | msg.binaryBucket = info.BinaryBucket; | 967 | |
968 | if (info.BinaryBucket[0] > 0) | ||
969 | { | ||
970 | //32 is due to not needing space for two of the UUIDs. | ||
971 | //(Don't need UUID of attachment or its owner in IM) | ||
972 | //50 offset gets us to start of attachment name. | ||
973 | //We are skipping the attachment flag, type, and | ||
974 | //the three UUID fields at the start of the bucket. | ||
975 | bucket = new byte[info.BinaryBucket.Length-32]; | ||
976 | bucket[0] = 1; //Has attachment | ||
977 | bucket[1] = info.BinaryBucket[1]; | ||
978 | Array.Copy(info.BinaryBucket, 50, | ||
979 | bucket, 18, info.BinaryBucket.Length-50); | ||
980 | } | ||
981 | else | ||
982 | { | ||
983 | bucket = new byte[19]; | ||
984 | bucket[0] = 0; //No attachment | ||
985 | bucket[1] = 0; //Attachment type | ||
986 | bucket[18] = 0; //NUL terminate name | ||
987 | } | ||
988 | |||
989 | info.GroupID.ToBytes(bucket, 2); | ||
990 | msg.binaryBucket = bucket; | ||
921 | } | 991 | } |
922 | else | 992 | else |
923 | { | 993 | { |
924 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | 994 | if (m_debugEnabled) |
995 | m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | ||
996 | |||
925 | msg.fromAgentID = UUID.Zero.Guid; | 997 | msg.fromAgentID = UUID.Zero.Guid; |
926 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; | 998 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
927 | msg.fromAgentName = string.Empty; | 999 | msg.fromAgentName = string.Empty; |
928 | msg.message = string.Empty; | 1000 | msg.message = string.Empty; |
929 | msg.binaryBucket = new byte[0]; | 1001 | msg.binaryBucket = new byte[0]; |
@@ -1047,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1047 | // Message to ejector | 1119 | // Message to ejector |
1048 | // Interop, received special 210 code for ejecting a group member | 1120 | // Interop, received special 210 code for ejecting a group member |
1049 | // this only works within the comms servers domain, and won't work hypergrid | 1121 | // this only works within the comms servers domain, and won't work hypergrid |
1050 | // TODO:FIXME: Use a presense server of some kind to find out where the | 1122 | // TODO:FIXME: Use a presence server of some kind to find out where the |
1051 | // client actually is, and try contacting that region directly to notify them, | 1123 | // client actually is, and try contacting that region directly to notify them, |
1052 | // or provide the notification via xmlrpc update queue | 1124 | // or provide the notification via xmlrpc update queue |
1053 | 1125 | ||