diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 40bbe0c812..b0bebd96f8 100755 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -38,7 +38,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Groups { @@ -344,14 +344,24 @@ namespace OpenSim.Groups private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat("[Groups]: OnInstantMessage called"); + + if(remoteClient == null || !remoteClient.IsActive || remoteClient.AgentId == UUID.Zero) + return; + + Scene scene = (Scene)remoteClient.Scene; + if (scene == null) + return; + + string remoteAgentIDstr = remoteClient.AgentId.ToString(); //m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog); // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(remoteAgentIDstr, inviteID); if (inviteInfo == null) { @@ -374,7 +384,7 @@ namespace OpenSim.Groups // and the sessionid is the role string reason = string.Empty; - if (!m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason)) + if (!m_groupData.AddAgentToGroup(remoteAgentIDstr, invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason)) remoteClient.SendAgentAlertMessage("Unable to add you to the group: " + reason, false); else { @@ -401,121 +411,237 @@ namespace OpenSim.Groups } } - m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { - if (m_debugEnabled) m_log.DebugFormat("[Groups]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); + if (m_debugEnabled) + m_log.DebugFormat("[Groups]: Received a reject invite notice."); - m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID); + m_groupData.RemoveAgentToGroupInvite(remoteAgentIDstr, inviteID); + m_groupData.RemoveAgentFromGroup(remoteAgentIDstr, inviteInfo.AgentID, inviteInfo.GroupID); } } } // Group notices - if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) + else if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) { if (!m_groupNoticesEnabled) + return; + + UUID GroupID = new UUID(im.toAgentID); + GroupMembershipData grpMemberData = m_groupData.GetAgentGroupMembership(remoteAgentIDstr, remoteAgentIDstr, GroupID); + if (grpMemberData == null) { + remoteClient.SendAgentAlertMessage("Group membership not found", false); return; } - UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null) != null) + if ((grpMemberData.GroupPowers & (ulong)GroupPowers.SendNotices) == 0) { - UUID NoticeID = UUID.Random(); - string Subject = im.message.Substring(0, im.message.IndexOf('|')); - string Message = im.message.Substring(Subject.Length + 1); + remoteClient.SendAgentAlertMessage("No permission to send notice to group", false); + return; + } - InventoryItemBase item = null; - bool hasAttachment = false; + int index = im.message.IndexOf('|'); + if (index < 0) + return; - if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) + string Subject = im.message.Substring(0, index); + string Message = im.message.Substring(index + 1); + + UUID NoticeID = UUID.Random(); + + InventoryItemBase item = null; + bool hasAttachment = false; + + if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) + { + UUID itemID = UUID.Zero; + UUID ownerID = UUID.Zero; + try { - hasAttachment = true; - string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); - binBucket = binBucket.Remove(0, 14).Trim(); + string binBucket = Utils.BytesToString(im.binaryBucket); + binBucket = binBucket.Substring(15); // remove extra LLSD pre header - OSD binBucketOSD = OSDParser.DeserializeLLSDXml(binBucket); - if (binBucketOSD is OSDMap) - { - OSDMap binBucketMap = (OSDMap)binBucketOSD; - - UUID itemID = binBucketMap["item_id"].AsUUID(); - UUID ownerID = binBucketMap["owner_id"].AsUUID(); - item = m_sceneList[0].InventoryService.GetItem(ownerID, itemID); - } - else - m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); + OSDMap binBucketMAP = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); + itemID = binBucketMAP["item_id"].AsUUID(); + ownerID = binBucketMAP["owner_id"].AsUUID(); + } + catch + { + m_log.DebugFormat("[GROUPS]: failed to decode group notice bucket"); + return; } - if (m_groupData.AddGroupNotice(GetRequestingAgentIDStr(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, - hasAttachment, - (byte)(item == null ? 0 : item.AssetType), - item == null ? null : item.Name, - item == null ? UUID.Zero : item.ID, - item == null ? UUID.Zero.ToString() : item.Owner.ToString())) + if (itemID != UUID.Zero && ownerID != UUID.Zero) { - if (OnNewGroupNotice != null) + item = scene.InventoryService.GetItem(ownerID, itemID); + if(item != null) { - OnNewGroupNotice(GroupID, NoticeID); - } - - // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) - { - if (member.AcceptNotices) + if ((item.CurrentPermissions & (uint)(PermissionMask.Transfer | PermissionMask.Copy)) != + (uint)(PermissionMask.Transfer | PermissionMask.Copy)) { - // Build notice IIM, one of reach, because the sending may be async - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - msg.toAgentID = member.AgentID.Guid; - OutgoingInstantMessage(msg, member.AgentID); + remoteClient.SendAgentAlertMessage("Item must be have Copy and Transfer rights to attach to group notice", false); + return; } } + hasAttachment = true; + } + } + + if (m_groupData.AddGroupNotice(remoteAgentIDstr, GroupID, NoticeID, im.fromAgentName, Subject, Message, + hasAttachment, + (byte)(item == null ? 0 : item.AssetType), + item == null ? null : item.Name, + item == null ? UUID.Zero : item.ID, + item == null ? UUID.Zero.ToString() : item.Owner.ToString())) + { + OnNewGroupNotice?.Invoke(GroupID, NoticeID); + + // Send notice out to everyone that wants notices + foreach (GroupMembersData member in m_groupData.GetGroupMembers(remoteAgentIDstr, GroupID)) + { + GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)InstantMessageDialog.GroupNotice); + if (member.AcceptNotices) + { + // Build notice IIM, one of reach, because the sending may be async + msg.toAgentID = member.AgentID.Guid; + OutgoingInstantMessage(msg, member.AgentID); + } } } } if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) { - if (im.binaryBucket.Length < 16) // Invalid + if (!m_groupNoticesEnabled) return; - //// 16 bytes are the UUID. Maybe. -// UUID folderID = new UUID(im.binaryBucket, 0); UUID noticeID = new UUID(im.imSessionID); - GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); - if (notice != null) + if (m_debugEnabled) + m_log.DebugFormat("[xmlGROUPS]: Accepted notice {0} for {1}", noticeID, remoteClient.AgentId); + + if (noticeID == UUID.Zero) + return; + + UUID folderID = UUID.Zero; + try { - UUID giver = new UUID(im.toAgentID); - string tmp = string.Empty; - Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp); - - m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); - string message; - InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, - giver, notice.noticeData.AttachmentItemID, out message); - - if (itemCopy == null) - { - remoteClient.SendAgentAlertMessage(message, false); - return; - } - - remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); + if (im.binaryBucket != null && im.binaryBucket.Length >= 16) + folderID = new UUID(im.binaryBucket, 0); } + catch + { + m_log.DebugFormat("[xmlGROUPS]: GroupNoticeInventoryAccepted failed to decode target folder"); + return; + } + + GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID); + if (notice == null) + { + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", + noticeID, remoteClient.AgentId); + return; + } + + string tmp; + UUID giver = new UUID(im.toAgentID); + Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp); + + m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); + + string message = "Could not find group notice attached item"; + InventoryItemBase itemCopy = scene.GiveInventoryItem(remoteClient.AgentId, + giver, notice.noticeData.AttachmentItemID, folderID, out message); + + if (itemCopy == null) + { + remoteClient.SendAgentAlertMessage(message, false); + return; + } + + remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); } + else if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined) + { + if (!m_groupNoticesEnabled) + return; + + UUID noticeID = new UUID(im.imSessionID); + + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS]: Accepted notice {0} for {1}", noticeID, remoteAgentIDstr); + + if (noticeID == UUID.Zero) + return; + + UUID remoteAgentID = remoteClient.AgentId; + + GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentIDstr, noticeID); + if (notice == null) + { + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", + noticeID, remoteClient.AgentId); + return; + } + string giver = notice.noticeData.AttachmentOwnerID; + UUID attachmentUUID = notice.noticeData.AttachmentItemID; + + if (attachmentUUID == null || + attachmentUUID == UUID.Zero || + giver == null || + giver == UUID.Zero.ToString() + ) + return; + + if (m_debugEnabled) + m_log.DebugFormat("[xmlGroups]: Deny inventory from {0} to {1}", giver, remoteAgentIDstr); + + string message = String.Empty; + + InventoryItemBase itemCopy = scene.InventoryService.GetItem(remoteAgentID, attachmentUUID); + if (itemCopy == null) + return; + + InventoryFolderBase trash = scene.InventoryService.GetFolderForType(remoteAgentID, FolderType.Trash); + if (trash == null) + { + m_log.DebugFormat("[GROUPS]: failed to find trash folder for {0} ", remoteAgentID); + return; + } + + if (itemCopy.Folder == trash.ID || remoteAgentIDstr == notice.noticeData.AttachmentOwnerID) + return; + + itemCopy.Folder = trash.ID; + scene.InventoryService.MoveItems(itemCopy.Owner, new List() { itemCopy }); + + if (itemCopy == null) + { + remoteClient.SendAgentAlertMessage(message, false); + return; + } + + remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); + } + + // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid // TODO:FIXME: Use a presense server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue - if ((im.dialog == 210)) + else if ((im.dialog == 210)) { // This is sent from the region that the ejectee was ejected from // if it's being delivered here, then the ejectee is here @@ -949,6 +1075,7 @@ namespace OpenSim.Groups bucket = new byte[19 + name.Length]; bucket[0] = 1; // has attachment? bucket[1] = info.noticeData.AttachmentType; // attachment type + info.GroupID.ToBytes(bucket, 2); name.CopyTo(bucket, 18); } else @@ -959,7 +1086,6 @@ namespace OpenSim.Groups bucket[18] = 0; // null terminated } - info.GroupID.ToBytes(bucket, 2); msg.binaryBucket = bucket; } else @@ -1208,7 +1334,7 @@ namespace OpenSim.Groups public List FindGroups(IClientAPI remoteClient, string query) { - return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query); + return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query); } #endregion diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index a1093c9b53..cf0dfe9f91 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -246,9 +246,9 @@ namespace OpenSim.Groups return null; } - public List FindGroups(string RequestingAgentID, string search) + public List FindGroups(UUID RequestingAgentID, string search) { - return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search); + return m_LocalGroupsConnector.FindGroups(RequestingAgentID, search); } public List GetGroupMembers(string RequestingAgentID, UUID GroupID) diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs index 8a6e88dfbf..5583bdf882 100644 --- a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs +++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs @@ -39,7 +39,7 @@ namespace OpenSim.Groups bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, out string reason); ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName); - List FindGroups(string RequestingAgentID, string search); + List FindGroups(UUID RequestingAgentID, string search); List GetGroupMembers(string RequestingAgentID, UUID GroupID); bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason); diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs index c7877c6b9f..30f25f2525 100644 --- a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs +++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs @@ -173,7 +173,7 @@ namespace OpenSim.Groups return null; } - public List FindGroups(string RequestingAgentID, string search) + public List FindGroups(UUID RequestingAgentID, string search) { return m_GroupsService.FindGroups(RequestingAgentID, search); } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index 8f6be0d0b5..6d16293621 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -153,7 +153,7 @@ namespace OpenSim.Groups return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]); } - public List FindGroups(string RequestingAgentID, string query) + public List FindGroups(UUID RequestingAgentID, string query) { List hits = new List(); if (string.IsNullOrEmpty(query)) @@ -161,7 +161,7 @@ namespace OpenSim.Groups Dictionary sendData = new Dictionary(); sendData["Query"] = query; - sendData["RequestingAgentID"] = RequestingAgentID; + sendData["RequestingAgentID"] = RequestingAgentID.ToString(); Dictionary ret = MakeRequest("FINDGROUPS", sendData); diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs index b6c75a8c7b..d4fab797b7 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs @@ -192,7 +192,7 @@ namespace OpenSim.Groups }); } - public List FindGroups(string RequestingAgentID, string search) + public List FindGroups(UUID RequestingAgentID, string search) { // TODO! return m_GroupsService.FindGroups(RequestingAgentID, search); diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 8502bb5bda..500407e332 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -769,7 +769,7 @@ namespace OpenSim.Groups if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query")) NullResult(result, "Bad network data"); - List hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString()); + List hits = m_GroupsService.FindGroups(new UUID(request["RequestingAgentID"].ToString()), request["Query"].ToString()); if (hits == null || (hits != null && hits.Count == 0)) NullResult(result, "No hits"); diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs index b5f8ff5494..2c5073f50e 100644 --- a/OpenSim/Addons/Groups/Service/GroupsService.cs +++ b/OpenSim/Addons/Groups/Service/GroupsService.cs @@ -216,7 +216,7 @@ namespace OpenSim.Groups return _GroupDataToRecord(data); } - public List FindGroups(string RequestingAgentID, string search) + public List FindGroups(UUID RequestingAgentID, string search) { List groups = new List(); diff --git a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs index d1ecdce77b..bf578a0b9e 100644 --- a/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs +++ b/OpenSim/Addons/OfflineIM/Service/OfflineIMService.cs @@ -110,9 +110,8 @@ namespace OpenSim.OfflineIM { m_serializer.Serialize(writer, im); writer.Flush(); + imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray()); } - - imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray()); } OfflineIMData data = new OfflineIMData();