XmlRpcGroup: try to improve notices attachments

master
UbitUmarov 2020-06-08 23:17:41 +01:00
parent 775420c46a
commit 1a57abebfc
1 changed files with 280 additions and 171 deletions

View File

@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using System.Text; using System.Text;
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
using PermissionMask = OpenSim.Framework.PermissionMask;
namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{ {
@ -103,18 +104,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{ {
m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false); m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false);
if (!m_groupsEnabled) if (!m_groupsEnabled)
{
return; return;
}
if (groupsConfig.GetString("Module", "Default") != Name) if (groupsConfig.GetString("Module", "Default") != Name)
{ {
m_groupsEnabled = false; m_groupsEnabled = false;
return; return;
} }
m_log.InfoFormat("[GROUPS]: Initializing {0}", this.Name); m_log.InfoFormat("[xmlGROUPS]: Initializing {0}", this.Name);
m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true);
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false);
@ -404,9 +402,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
{ {
if (m_debugEnabled) if (m_debugEnabled)
m_log.DebugFormat( m_log.DebugFormat("[xmlGROUPS]: OnInstantMessage called for {0}, message type {1}",
"[GROUPS]: {0} called for {1}, message type {2}", remoteClient.Name, (InstantMessageDialog)im.dialog);
System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog);
if (!m_groupNoticesEnabled || remoteClient == null || !remoteClient.IsActive || remoteClient.AgentId == UUID.Zero)
return;
Scene scene = (Scene)remoteClient.Scene;
if(scene == null)
return;
UUID remoteAgentID = remoteClient.AgentId;
// Group invitations // Group invitations
if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
@ -416,11 +422,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
if (inviteInfo == null) if (inviteInfo == null)
{ {
if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID); if (m_debugEnabled)
m_log.WarnFormat("[xmlGROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID);
return; return;
} }
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); if (m_debugEnabled)
m_log.DebugFormat("[xmlGROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID);
UUID fromAgentID = new UUID(im.fromAgentID); UUID fromAgentID = new UUID(im.fromAgentID);
if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID))
@ -428,10 +436,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Accept // Accept
if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept)
{ {
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); if (m_debugEnabled)
m_log.DebugFormat("[xmlGROUPS]: Received an accept invite notice.");
// and the sessionid is the role // and the sessionid is the role
m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); m_groupData.AddAgentToGroup(remoteAgentID, inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID);
GridInstantMessage msg = new GridInstantMessage(); GridInstantMessage msg = new GridInstantMessage();
msg.imSessionID = UUID.Zero.Guid; msg.imSessionID = UUID.Zero.Guid;
@ -461,175 +470,275 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Reject // Reject
if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)
{ {
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); if (m_debugEnabled)
m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); m_log.DebugFormat("[xmlGROUPS]: Received a reject invite notice.");
m_groupData.RemoveAgentToGroupInvite(remoteAgentID, inviteID);
} }
} }
return;
} }
// Group notices // Group notices
if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
{ {
if (!m_groupNoticesEnabled)
{
return;
}
UUID GroupID = new UUID(im.toAgentID); UUID GroupID = new UUID(im.toAgentID);
if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) GroupMembershipData grpMemberData = m_groupData.GetAgentGroupMembership(remoteAgentID, remoteAgentID, GroupID);
if (grpMemberData == null)
{ {
UUID NoticeID = UUID.Random(); remoteClient.SendAgentAlertMessage("Group membership not found", false);
string Subject = im.message.Substring(0, im.message.IndexOf('|')); return;
string Message = im.message.Substring(Subject.Length + 1);
InventoryItemBase item = null;
bool hasAttachment = false;
UUID itemID = UUID.Zero; //Assignment to quiet compiler
UUID ownerID = UUID.Zero; //Assignment to quiet compiler
byte[] bucket;
if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
{
string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
binBucket = binBucket.Remove(0, 14).Trim();
OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
if (binBucketOSD is OSD)
{
OSDMap binBucketMap = (OSDMap)binBucketOSD;
itemID = binBucketMap["item_id"].AsUUID();
ownerID = binBucketMap["owner_id"].AsUUID();
//Attempt to get the details of the attached item.
//If sender doesn't own the attachment, the item
//variable will be set to null and attachment will
//not be included with the group notice.
Scene scene = (Scene)remoteClient.Scene;
item = scene.InventoryService.GetItem(ownerID, itemID);
if (item != null)
{
//Got item details so include the attachment.
hasAttachment = true;
}
}
else
{
m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
}
}
if (hasAttachment)
{
//Bucket contains information about attachment.
//
//Byte offset and description of bucket data:
//0: 1 byte indicating if attachment is present
//1: 1 byte indicating the type of attachment
//2: 16 bytes - Group UUID
//18: 16 bytes - UUID of the attachment owner
//34: 16 bytes - UUID of the attachment
//50: variable - Name of the attachment
//??: NUL byte to terminate the attachment name
byte[] name = Encoding.UTF8.GetBytes(item.Name);
bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name
bucket[0] = 1; //Has attachment flag
bucket[1] = (byte)item.InvType; //Type of Attachment
GroupID.ToBytes(bucket, 2);
ownerID.ToBytes(bucket, 18);
itemID.ToBytes(bucket, 34);
name.CopyTo(bucket, 50);
}
else
{
bucket = new byte[19];
bucket[0] = 0; //Has attachment flag
bucket[1] = 0; //Type of attachment
GroupID.ToBytes(bucket, 2);
bucket[18] = 0; //NUL terminate name of attachment
}
m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
if (OnNewGroupNotice != null)
{
OnNewGroupNotice(GroupID, NoticeID);
}
if (m_debugEnabled)
{
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID))
{
if (m_debugEnabled)
{
UserAccount targetUser
= m_sceneList[0].UserAccountService.GetUserAccount(
remoteClient.Scene.RegionInfo.ScopeID, member.AgentID);
if (targetUser != null)
{
m_log.DebugFormat(
"[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
}
else
{
m_log.DebugFormat(
"[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
NoticeID, member.AgentID, member.AcceptNotices);
}
}
}
}
GridInstantMessage msg
= CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
if (m_groupsMessagingModule != null)
m_groupsMessagingModule.SendMessageToGroup(
msg, GroupID, remoteClient.AgentId, gmd => gmd.AcceptNotices);
} }
}
if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) if ((grpMemberData.GroupPowers & (ulong)GroupPowers.SendNotices) == 0)
{ {
//Is bucket large enough to hold UUID of the attachment? remoteClient.SendAgentAlertMessage("No permission to send notice to group", false);
if (im.binaryBucket.Length < 16) return;
}
int index = im.message.IndexOf('|');
if(index < 0)
return; return;
UUID noticeID = new UUID(im.imSessionID); string Subject = im.message.Substring(0, index);
string Message = im.message.Substring(index + 1);
if (m_debugEnabled) InventoryItemBase item = null;
m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId); bool hasAttachment = false;
UUID itemID = UUID.Zero;
UUID ownerID = UUID.Zero;
byte[] bucket;
GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
if (notice != null)
{ {
UUID giver = new UUID(notice.BinaryBucket, 18); try
UUID attachmentUUID = new UUID(notice.BinaryBucket, 34);
if (m_debugEnabled)
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
string message;
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
giver, attachmentUUID, out message);
if (itemCopy == null)
{ {
remoteClient.SendAgentAlertMessage(message, false); string binBucket = Utils.BytesToString(im.binaryBucket);
binBucket = binBucket.Substring(15); // remove extra LLSD pre header
OSDMap binBucketMAP = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
itemID = binBucketMAP["item_id"].AsUUID();
ownerID = binBucketMAP["owner_id"].AsUUID();
}
catch
{
m_log.DebugFormat("[xmlGROUPS]: failed to decode group notice bucket");
return; return;
} }
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); if(itemID != UUID.Zero && ownerID != UUID.Zero)
{
item = scene.InventoryService.GetItem(ownerID, itemID);
if (item != null)
{
if((item.CurrentPermissions & (uint)(PermissionMask.Transfer | PermissionMask.Copy)) !=
(uint)(PermissionMask.Transfer | PermissionMask.Copy))
{
remoteClient.SendAgentAlertMessage("Item must be have Copy and Transfer rights to attach to group notice", false);
return;
}
hasAttachment = true;
}
}
}
if (hasAttachment)
{
//Bucket contains information about attachment.
//
//Byte offset and description of bucket data:
//0: 1 byte indicating if attachment is present
//1: 1 byte indicating the type of attachment
//2: 16 bytes - Group UUID
//18: 16 bytes - UUID of the attachment owner
//34: 16 bytes - UUID of the attachment
//50: variable - Name of the attachment
//??: NUL byte to terminate the attachment name
byte[] name = Encoding.UTF8.GetBytes(item.Name);
bucket = new byte[51 + name.Length];//2 bytes, 3 UUIDs, and name and null
bucket[0] = 1; //Has attachment flag
bucket[1] = (byte)item.AssetType; //Type of Attachment
GroupID.ToBytes(bucket, 2);
ownerID.ToBytes(bucket, 18);
itemID.ToBytes(bucket, 34);
name.CopyTo(bucket, 50);
} }
else else
{
bucket = new byte[19];
bucket[0] = 0; //Has attachment flag
bucket[1] = 0; //Type of attachment
GroupID.ToBytes(bucket, 2);
bucket[18] = 0; //NUL terminate name of attachment
}
UUID NoticeID = UUID.Random();
m_groupData.AddGroupNotice(remoteAgentID, GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
OnNewGroupNotice?.Invoke(GroupID, NoticeID);
if (m_debugEnabled)
{
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID))
{
if (m_debugEnabled)
{
UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(
remoteClient.Scene.RegionInfo.ScopeID, member.AgentID);
if (targetUser != null)
{
m_log.DebugFormat(
"[xmlGROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
}
else
{
m_log.DebugFormat(
"[xmlGROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
NoticeID, member.AgentID, member.AcceptNotices);
}
}
}
}
if (m_groupsMessagingModule != null)
{
GridInstantMessage msg
= CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)InstantMessageDialog.GroupNotice);
m_groupsMessagingModule.SendMessageToGroup(
msg, GroupID, remoteAgentID, gmd => gmd.AcceptNotices);
}
}
else if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
{
UUID noticeID = new UUID(im.imSessionID);
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
{
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(remoteAgentID, noticeID);
if (notice == null)
{ {
if (m_debugEnabled) if (m_debugEnabled)
m_log.DebugFormat( m_log.DebugFormat(
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
noticeID, remoteClient.AgentId); noticeID, remoteClient.AgentId);
return;
} }
UUID giver = UUID.Zero;
UUID attachmentUUID = UUID.Zero;
try
{
giver = new UUID(notice.BinaryBucket, 18);
attachmentUUID = new UUID(notice.BinaryBucket, 34);
}
catch
{
m_log.DebugFormat("[xmlGROUPS]: GroupNoticeInventoryAccepted failed to giver or attachment ID");
return;
}
if (m_debugEnabled)
m_log.DebugFormat("[xmlGroups]: Giving inventory from {0} to {1}", giver, remoteAgentID);
string message = "Could not find group notice attached item";
InventoryItemBase itemCopy = scene.InventoryService.GetItem(giver, attachmentUUID);
if (itemCopy != null)
{
itemCopy = scene.GiveInventoryItem(remoteAgentID, giver, attachmentUUID, folderID, out message);
}
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage(message, false);
return;
}
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
}
else if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryDeclined)
{
UUID noticeID = new UUID(im.imSessionID);
if (m_debugEnabled)
m_log.DebugFormat("[xmlGROUPS]: Accepted notice {0} for {1}", noticeID, remoteAgentID);
if (noticeID == UUID.Zero)
return;
InventoryFolderBase trash = scene.InventoryService.GetFolderForType(remoteAgentID, FolderType.Trash);
if(trash == null)
{
m_log.DebugFormat("[xmlGROUPS]: failed to find trash folder for {0} ", remoteAgentID);
return;
}
GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteAgentID, noticeID);
if (notice == null)
{
if (m_debugEnabled)
m_log.DebugFormat(
"[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
noticeID, remoteClient.AgentId);
return;
}
UUID giver = UUID.Zero;
UUID attachmentUUID = UUID.Zero;
try
{
giver = new UUID(notice.BinaryBucket, 18);
attachmentUUID = new UUID(notice.BinaryBucket, 34);
}
catch
{
m_log.DebugFormat("[xmlGROUPS]: GroupNoticeInventoryAccepted failed to giver or attachment ID");
return;
}
if (m_debugEnabled)
m_log.DebugFormat("[xmlGroups]: Deny inventory from {0} to {1}", giver, remoteAgentID);
string message = String.Empty;
// check if we already have it
InventoryItemBase itemCopy = scene.InventoryService.GetItem(remoteAgentID, attachmentUUID);
if (itemCopy == null)
return;
if (itemCopy.Folder == trash.ID || remoteAgentID == giver)
return;
itemCopy.Folder = trash.ID;
scene.InventoryService.MoveItems(itemCopy.Owner, new List<InventoryItemBase>() { itemCopy });
if (itemCopy == null)
{
remoteClient.SendAgentAlertMessage(message, false);
return;
}
remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
} }
// Interop, received special 210 code for ejecting a group member // Interop, received special 210 code for ejecting a group member
@ -637,7 +746,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// TODO:FIXME: Use a presence server of some kind to find out where the // TODO:FIXME: Use a presence server of some kind to find out where the
// client actually is, and try contacting that region directly to notify them, // client actually is, and try contacting that region directly to notify them,
// or provide the notification via xmlrpc update queue // 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 // This is sent from the region that the ejectee was ejected from
// if it's being delivered here, then the ejectee is here // if it's being delivered here, then the ejectee is here
@ -660,7 +769,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private void OnGridInstantMessage(GridInstantMessage msg) private void OnGridInstantMessage(GridInstantMessage msg)
{ {
if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled)
m_log.InfoFormat("[xmlGROUPS]: OnGridInstantMessage called");
// Trigger the above event handler // Trigger the above event handler
OnInstantMessage(null, msg); OnInstantMessage(null, msg);
@ -1012,22 +1122,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
{ {
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled)
m_log.DebugFormat("[xmlGROUPS]: GroupNoticeRequest {0}", groupNoticeID);
GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); GroupNoticeInfo info = m_groupData.GetGroupNotice(remoteClient.AgentId, groupNoticeID);
if(info == null)
return;
if (data != null) GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested, info);
{ OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
}
} }
public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
{ {
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID);
return CreateGroupNoticeIM(agentID, groupNoticeID, dialog, info);
}
private GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog, GroupNoticeInfo info)
{
GridInstantMessage msg = new GridInstantMessage(); GridInstantMessage msg = new GridInstantMessage();
byte[] bucket; byte[] bucket;
@ -1040,7 +1153,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
msg.Position = Vector3.Zero; msg.Position = Vector3.Zero;
msg.RegionID = UUID.Zero.Guid; msg.RegionID = UUID.Zero.Guid;
GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID);
if (info != null) if (info != null)
{ {
msg.fromAgentID = info.GroupID.Guid; msg.fromAgentID = info.GroupID.Guid;
@ -1053,13 +1165,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
//32 is due to not needing space for two of the UUIDs. //32 is due to not needing space for two of the UUIDs.
//(Don't need UUID of attachment or its owner in IM) //(Don't need UUID of attachment or its owner in IM)
//50 offset gets us to start of attachment name. //50 offset gets us to start of attachment name.
//We are skipping the attachment flag, type, and bucket = new byte[info.BinaryBucket.Length - 32];
//the three UUID fields at the start of the bucket. Array.Copy(info.BinaryBucket, 0,
bucket = new byte[info.BinaryBucket.Length-32]; bucket, 0, 18);
bucket[0] = 1; //Has attachment
bucket[1] = info.BinaryBucket[1];
Array.Copy(info.BinaryBucket, 50, Array.Copy(info.BinaryBucket, 50,
bucket, 18, info.BinaryBucket.Length-50); bucket, 18, info.BinaryBucket.Length - 50);
} }
else else
{ {
@ -1069,7 +1179,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
bucket[18] = 0; //NUL terminate name bucket[18] = 0; //NUL terminate name
} }
info.GroupID.ToBytes(bucket, 2);
msg.binaryBucket = bucket; msg.binaryBucket = bucket;
} }
else else