aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs226
1 files changed, 152 insertions, 74 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d0a5989..2764465 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;
39using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using System.Text;
42using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; 43using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
43 44
44namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 45namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
@@ -194,6 +195,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
194 } 195 }
195 196
196 scene.EventManager.OnNewClient += OnNewClient; 197 scene.EventManager.OnNewClient += OnNewClient;
198 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
199 scene.EventManager.OnMakeChildAgent += OnMakeChild;
197 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 200 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
198 // The InstantMessageModule itself doesn't do this, 201 // The InstantMessageModule itself doesn't do this,
199 // so lets see if things explode if we don't do it 202 // so lets see if things explode if we don't do it
@@ -244,20 +247,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
244 #endregion 247 #endregion
245 248
246 #region EventHandlers 249 #region EventHandlers
250
251 private void OnMakeRoot(ScenePresence sp)
252 {
253 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
254
255 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
256 // Used for Notices and Group Invites/Accept/Reject
257 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
258 // Send client their groups information.
259// SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
260 // only send data viwer will ask rest later
261 OnAgentDataUpdateRequest(sp.ControllingClient, sp.UUID, sp.UUID);
262 }
263
264 private void OnMakeChild(ScenePresence sp)
265 {
266 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
267
268 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
269 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
270 }
271
247 private void OnNewClient(IClientAPI client) 272 private void OnNewClient(IClientAPI client)
248 { 273 {
249 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 274 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
250 275
251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 276 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
253 client.OnDirFindQuery += OnDirFindQuery;
254 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 277 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
255
256 // Used for Notices and Group Invites/Accept/Reject
257 client.OnInstantMessage += OnInstantMessage;
258
259 // Send client their groups information.
260 SendAgentGroupDataUpdate(client, client.AgentId);
261 } 278 }
262 279
263 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 280 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@@ -303,21 +320,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
303 } 320 }
304 */ 321 */
305 322
306 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
307 {
308 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
309 {
310 if (m_debugEnabled)
311 m_log.DebugFormat(
312 "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
313 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
314
315 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
316 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
317 }
318
319 }
320
321 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 323 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
322 { 324 {
323 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 325 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -437,44 +439,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
437 string Subject = im.message.Substring(0, im.message.IndexOf('|')); 439 string Subject = im.message.Substring(0, im.message.IndexOf('|'));
438 string Message = im.message.Substring(Subject.Length + 1); 440 string Message = im.message.Substring(Subject.Length + 1);
439 441
442 InventoryItemBase item = null;
443 bool hasAttachment = false;
444 UUID itemID = UUID.Zero; //Assignment to quiet compiler
445 UUID ownerID = UUID.Zero; //Assignment to quiet compiler
440 byte[] bucket; 446 byte[] bucket;
441 447
442 if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) 448 if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
443 {
444 bucket = new byte[19];
445 bucket[0] = 0; //dunno
446 bucket[1] = 0; //dunno
447 GroupID.ToBytes(bucket, 2);
448 bucket[18] = 0; //dunno
449 }
450 else
451 { 449 {
452 string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); 450 string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
453 binBucket = binBucket.Remove(0, 14).Trim(); 451 binBucket = binBucket.Remove(0, 14).Trim();
454 if (m_debugEnabled) 452
453 OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
454 if (binBucketOSD is OSD)
455 { 455 {
456 m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); 456 OSDMap binBucketMap = (OSDMap)binBucketOSD;
457
458 itemID = binBucketMap["item_id"].AsUUID();
459 ownerID = binBucketMap["owner_id"].AsUUID();
457 460
458 OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); 461 //Attempt to get the details of the attached item.
459 462 //If sender doesn't own the attachment, the item
460 foreach (string key in binBucketOSD.Keys) 463 //variable will be set to null and attachment will
464 //not be included with the group notice.
465 Scene scene = (Scene)remoteClient.Scene;
466 item = new InventoryItemBase(itemID, ownerID);
467 item = scene.InventoryService.GetItem(item);
468
469 if (item != null)
461 { 470 {
462 if (binBucketOSD.ContainsKey(key)) 471 //Got item details so include the attachment.
463 { 472 hasAttachment = true;
464 m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString());
465 }
466 } 473 }
467 } 474 }
468 475 else
469 // treat as if no attachment 476 {
477 m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
478 }
479 }
480
481 if (hasAttachment)
482 {
483 //Bucket contains information about attachment.
484 //
485 //Byte offset and description of bucket data:
486 //0: 1 byte indicating if attachment is present
487 //1: 1 byte indicating the type of attachment
488 //2: 16 bytes - Group UUID
489 //18: 16 bytes - UUID of the attachment owner
490 //34: 16 bytes - UUID of the attachment
491 //50: variable - Name of the attachment
492 //??: NUL byte to terminate the attachment name
493 byte[] name = Encoding.UTF8.GetBytes(item.Name);
494 bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name
495 bucket[0] = 1; //Has attachment flag
496 bucket[1] = (byte)item.InvType; //Type of Attachment
497 GroupID.ToBytes(bucket, 2);
498 ownerID.ToBytes(bucket, 18);
499 itemID.ToBytes(bucket, 34);
500 name.CopyTo(bucket, 50);
501 }
502 else
503 {
470 bucket = new byte[19]; 504 bucket = new byte[19];
471 bucket[0] = 0; //dunno 505 bucket[0] = 0; //Has attachment flag
472 bucket[1] = 0; //dunno 506 bucket[1] = 0; //Type of attachment
473 GroupID.ToBytes(bucket, 2); 507 GroupID.ToBytes(bucket, 2);
474 bucket[18] = 0; //dunno 508 bucket[18] = 0; //NUL terminate name of attachment
475 } 509 }
476 510
477
478 m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); 511 m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
479 if (OnNewGroupNotice != null) 512 if (OnNewGroupNotice != null)
480 { 513 {
@@ -499,7 +532,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
499 532
500 if (member.AcceptNotices) 533 if (member.AcceptNotices)
501 { 534 {
502 // Build notice IIM 535 // Build notice IM
503 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); 536 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
504 537
505 msg.toAgentID = member.AgentID.Guid; 538 msg.toAgentID = member.AgentID.Guid;
@@ -508,10 +541,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
508 } 541 }
509 } 542 }
510 } 543 }
511 544
545 if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
546 {
547 //Is bucket large enough to hold UUID of the attachment?
548 if (im.binaryBucket.Length < 16)
549 return;
550
551 UUID noticeID = new UUID(im.imSessionID);
552
553 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
554 if (notice != null)
555 {
556 UUID giver = new UUID(notice.BinaryBucket, 18);
557 UUID attachmentUUID = new UUID(notice.BinaryBucket, 34);
558
559 if (m_debugEnabled)
560 m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
561
562 InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
563 giver, attachmentUUID);
564
565 if (itemCopy == null)
566 {
567 remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
568 return;
569 }
570
571 remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
572 }
573 }
574
512 // Interop, received special 210 code for ejecting a group member 575 // Interop, received special 210 code for ejecting a group member
513 // this only works within the comms servers domain, and won't work hypergrid 576 // this only works within the comms servers domain, and won't work hypergrid
514 // TODO:FIXME: Use a presense server of some kind to find out where the 577 // TODO:FIXME: Use a presence server of some kind to find out where the
515 // client actually is, and try contacting that region directly to notify them, 578 // client actually is, and try contacting that region directly to notify them,
516 // or provide the notification via xmlrpc update queue 579 // or provide the notification via xmlrpc update queue
517 if ((im.dialog == 210)) 580 if ((im.dialog == 210))
@@ -889,26 +952,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
889 952
890 if (data != null) 953 if (data != null)
891 { 954 {
892 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); 955 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
893
894 GridInstantMessage msg = new GridInstantMessage();
895 msg.imSessionID = UUID.Zero.Guid;
896 msg.fromAgentID = data.GroupID.Guid;
897 msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
898 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
899 msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
900 msg.message = data.noticeData.Subject + "|" + data.Message;
901 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
902 msg.fromGroup = true;
903 msg.offline = (byte)0;
904 msg.ParentEstateID = 0;
905 msg.Position = Vector3.Zero;
906 msg.RegionID = UUID.Zero.Guid;
907 msg.binaryBucket = data.BinaryBucket;
908 956
909 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); 957 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
910 } 958 }
911
912 } 959 }
913 960
914 public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) 961 public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
@@ -916,10 +963,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
916 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 963 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
917 964
918 GridInstantMessage msg = new GridInstantMessage(); 965 GridInstantMessage msg = new GridInstantMessage();
919 msg.imSessionID = UUID.Zero.Guid; 966 byte[] bucket;
967
968 msg.imSessionID = groupNoticeID.Guid;
920 msg.toAgentID = agentID.Guid; 969 msg.toAgentID = agentID.Guid;
921 msg.dialog = dialog; 970 msg.dialog = dialog;
922 // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
923 msg.fromGroup = true; 971 msg.fromGroup = true;
924 msg.offline = (byte)1; // Allow this message to be stored for offline use 972 msg.offline = (byte)1; // Allow this message to be stored for offline use
925 msg.ParentEstateID = 0; 973 msg.ParentEstateID = 0;
@@ -933,13 +981,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
933 msg.timestamp = info.noticeData.Timestamp; 981 msg.timestamp = info.noticeData.Timestamp;
934 msg.fromAgentName = info.noticeData.FromName; 982 msg.fromAgentName = info.noticeData.FromName;
935 msg.message = info.noticeData.Subject + "|" + info.Message; 983 msg.message = info.noticeData.Subject + "|" + info.Message;
936 msg.binaryBucket = info.BinaryBucket; 984
985 if (info.BinaryBucket[0] > 0)
986 {
987 //32 is due to not needing space for two of the UUIDs.
988 //(Don't need UUID of attachment or its owner in IM)
989 //50 offset gets us to start of attachment name.
990 //We are skipping the attachment flag, type, and
991 //the three UUID fields at the start of the bucket.
992 bucket = new byte[info.BinaryBucket.Length-32];
993 bucket[0] = 1; //Has attachment
994 bucket[1] = info.BinaryBucket[1];
995 Array.Copy(info.BinaryBucket, 50,
996 bucket, 18, info.BinaryBucket.Length-50);
997 }
998 else
999 {
1000 bucket = new byte[19];
1001 bucket[0] = 0; //No attachment
1002 bucket[1] = 0; //Attachment type
1003 bucket[18] = 0; //NUL terminate name
1004 }
1005
1006 info.GroupID.ToBytes(bucket, 2);
1007 msg.binaryBucket = bucket;
937 } 1008 }
938 else 1009 else
939 { 1010 {
940 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); 1011 if (m_debugEnabled)
1012 m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
1013
941 msg.fromAgentID = UUID.Zero.Guid; 1014 msg.fromAgentID = UUID.Zero.Guid;
942 msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; 1015 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
943 msg.fromAgentName = string.Empty; 1016 msg.fromAgentName = string.Empty;
944 msg.message = string.Empty; 1017 msg.message = string.Empty;
945 msg.binaryBucket = new byte[0]; 1018 msg.binaryBucket = new byte[0];
@@ -1063,7 +1136,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1063 // Message to ejector 1136 // Message to ejector
1064 // Interop, received special 210 code for ejecting a group member 1137 // Interop, received special 210 code for ejecting a group member
1065 // this only works within the comms servers domain, and won't work hypergrid 1138 // this only works within the comms servers domain, and won't work hypergrid
1066 // TODO:FIXME: Use a presense server of some kind to find out where the 1139 // TODO:FIXME: Use a presence server of some kind to find out where the
1067 // client actually is, and try contacting that region directly to notify them, 1140 // client actually is, and try contacting that region directly to notify them,
1068 // or provide the notification via xmlrpc update queue 1141 // or provide the notification via xmlrpc update queue
1069 1142
@@ -1178,6 +1251,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1178 } 1251 }
1179 } 1252 }
1180 1253
1254 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1255 {
1256 return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
1257 }
1258
1259
1181 #endregion 1260 #endregion
1182 1261
1183 #region Client/Update Tools 1262 #region Client/Update Tools
@@ -1222,7 +1301,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1222 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); 1301 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1223 AgentData.Add(AgentDataMap); 1302 AgentData.Add(AgentDataMap);
1224 1303
1225
1226 OSDArray GroupData = new OSDArray(data.Length); 1304 OSDArray GroupData = new OSDArray(data.Length);
1227 OSDArray NewGroupData = new OSDArray(data.Length); 1305 OSDArray NewGroupData = new OSDArray(data.Length);
1228 1306