//////////////////////////////////////////////// // Object-to-user inventory offers private void TaskInventoryOffer(IClientAPI client, Scene scene, GridInstantMessage im) { IMuteListModule m_muteListModule = scene.RequestModuleInterface <IMuteListModule>(); if (m_muteListModule != null) { UUID sender = new UUID(im.fromAgentID); UUID recipient = new UUID(im.toAgentID); if (m_muteListModule.IsMuted(sender, recipient)) { return; // recipient has sender muted } } RelayInventoryOfferIM(scene, im); }
//////////////////////////////////////////////// // User-to-user inventory offers private void UserInventoryOffer(IClientAPI client, Scene scene, GridInstantMessage im) { InventoryFolderBase folder = null; InventoryItemBase item = null; UUID toAgentID = new UUID(im.toAgentID); IMuteListModule m_muteListModule = scene.RequestModuleInterface <IMuteListModule>(); if (m_muteListModule != null) { if (m_muteListModule.IsMuted(client.AgentId, toAgentID)) { client.SendAgentAlertMessage("Inventory offer was automatically declined.", false); return; // recipient has sender muted } } // Unpack the binary bucket AssetType assetType = (AssetType)im.binaryBucket[0]; UUID destID = new UUID(im.binaryBucket, 1); UUID copyID; bool isFolder = (assetType == AssetType.Folder); ScenePresence recipient = scene.GetScenePresence(toAgentID); if (recipient != null && recipient.IsBot) { client.SendAgentAlertMessage("Can't give inventory to bots.", false); return;//can't give objects to bots } if (assetType == AssetType.Folder) { folder = scene.GiveInventoryFolder(toAgentID, client.AgentId, destID, UUID.Zero); if (folder == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } copyID = folder.ID; } else { item = scene.GiveInventoryItem(toAgentID, client.AgentId, destID); if (item == null) { client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } copyID = item.ID; } // m_log.InfoFormat("[AGENT INVENTORY]: Offering {0} {1} to user {2} inventory as {3}", isFolder ? "folder" : "item", destID, toAgentID, copyID); // Update the asset type and destination ID into the outgoing IM. im.binaryBucket = new byte[17]; im.binaryBucket[0] = (byte)assetType; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); // Also stuff the destination ID into the session ID field for retrieval in accept/decline im.imSessionID = copyID.Guid; CachedUserInfo recipientInfo = scene.CommsManager.UserService.GetUserDetails(toAgentID); if (recipientInfo != null && recipient != null) { if ((!isFolder) && (item != null)) { // item offer? recipient.ControllingClient.SendInventoryItemCreateUpdate(item, 0); } if (isFolder && (folder != null)) { // folder offer? folder = recipientInfo.GetFolder(folder.ID); if (folder != null) { recipient.ControllingClient.SendBulkUpdateInventory(folder); recipientInfo.SendInventoryDecendents(recipient.ControllingClient, folder.ID, false, true); } } } // Send the IM to the recipient. The item is already in their inventory, so // it will not be lost if they are offline. Transaction ID is the item ID. // We get that same ID back on the reply so we know what to act on. RelayInventoryOfferIM(scene, recipient, im); }
// agentID and agentName are only used if remoteClient is null. // agentID/agentName is the requesting user, typically owner of the script requesting it. public int InviteGroupRequest(IClientAPI remoteClient, UUID agentID, string agentName, UUID groupID, UUID invitedAgentID, UUID roleID) { GroupRequestID grID = GetClientGroupRequestID(remoteClient); GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); IScene scene = m_sceneList[0]; if (remoteClient != null) { agentID = remoteClient.AgentId; agentName = remoteClient.Name; scene = remoteClient.Scene; } string groupName; if (groupInfo != null) groupName = groupInfo.GroupName; else groupName = "(unknown)"; if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Get the list of users who have this sender muted. m_muteListModule = m_sceneList[0].RequestModuleInterface<IMuteListModule>(); if (m_muteListModule != null) { if (m_muteListModule.IsMuted(agentID, invitedAgentID)) { if (remoteClient != null) remoteClient.SendAlertMessage("You cannot invite someone who has you muted into a group."); return (int)Constants.GenericReturnCodes.MUTED; } } // Send notice out to everyone that wants notices // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); string reason = String.Empty; int rc = m_groupData.AddAgentToGroupInvite(grID, agentID, InviteID, groupID, roleID, invitedAgentID, out reason); if (rc != 0) { if ((remoteClient != null) && (reason != String.Empty)) remoteClient.SendAlertMessage(reason); return rc; } if (m_msgTransferModule == null) { if (remoteClient != null) remoteClient.SendAlertMessage("Error sending group invitation."); return (int)Constants.GenericReturnCodes.ERROR; } Guid inviteUUID = InviteID.Guid; GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = inviteUUID; // msg.fromAgentID = agentId.Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.timestamp = 0; msg.fromAgentName = agentName; msg.message = string.Format("{0} has invited you to join a group: {1}. There is no cost to join this group.", agentName, groupName); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; msg.fromGroup = true; msg.offline = (byte)1; //yes, store for fetching missed IMs on login msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[20]; OutgoingInstantMessage(msg, invitedAgentID); if ((remoteClient != null) && (reason != String.Empty)) remoteClient.SendAlertMessage(reason); return (int)Constants.GenericReturnCodes.SUCCESS; }
private void SendGroupNoticeIM(UUID NoticeID, UUID AgentID, OpenMetaverse.InstantMessageDialog dialog, bool checkMuted) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)dialog); if (msg == null) return; // old bad one stored from offlines? UUID sender = new UUID(msg.fromAgentID); if (checkMuted) { m_muteListModule = m_sceneList[0].RequestModuleInterface<IMuteListModule>(); if (m_muteListModule != null) if (m_muteListModule.IsMuted(sender, AgentID)) return; } bool HasAttachment = (msg.binaryBucket[0] != 0); if (HasAttachment) // save the notice with the session ID { lock (GroupAttachmentCache) { GroupAttachmentCache[msg.imSessionID] = NoticeID; } } msg.toAgentID = AgentID.Guid; IClientAPI localClient = GetActiveClient(AgentID); if (localClient != null) { if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: Recipient ({0}) is local, delivering group notice directly", localClient.Name); localClient.SendInstantMessage(msg); } else { // send for offline storage if (HasAttachment) // clean up the cache item added above { lock (GroupAttachmentCache) { GroupAttachmentCache.Remove(msg.imSessionID); } } // need to reformat this with db storage bucket, not the viewer IM bucket // format for database storage int bucketLen = msg.binaryBucket.Length; byte[] OfflineBucket = new byte[bucketLen + 4 + 16]; OfflineBucket[0] = 0xFF; // sign, would be 00 or 01 here in a normal viewer IM bucket OfflineBucket[1] = 0x00; OfflineBucket[2] = 0x00; OfflineBucket[3] = 0x00; // Spare bytes NoticeID.ToBytes(OfflineBucket, 4); // 16-byte UUID msg.binaryBucket.CopyTo(OfflineBucket, 20); msg.binaryBucket = OfflineBucket; if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: Recipient ({0}) is not local, delivering group notice via TransferModule", msg.toAgentID); m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Message Sent: {0}", success ? "Succeeded" : "Failed"); }); } }
public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) { UUID fromAgentID = new UUID(im.fromAgentID); UUID toAgentID = new UUID(im.toAgentID); foreach (Scene scene in m_Scenes) { if (!scene.EventManager.TriggerOnBeforeSendInstantMessage(im)) { m_log.WarnFormat("[INSTANT MESSAGE]: Outbound IM blocked by module"); return; } // Check for muted senders in specific IM cases. if (m_muteListModule == null) { m_muteListModule = scene.RequestModuleInterface <IMuteListModule>(); } if (m_muteListModule != null) { if ((im.dialog == (int)InstantMessageDialog.MessageFromAgent) || (im.dialog == (int)InstantMessageDialog.MessageFromObject)) { if (m_muteListModule.IsMuted(fromAgentID, toAgentID)) // owner ID is in fromAgentID in case of IMs from objects { return; // recipient has sender muted. } } } } //m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString()); // Try root avatar only first foreach (Scene scene in m_Scenes) { if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) { //m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName); // Local message ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; if (!user.IsChildAgent) { //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); user.ControllingClient.SendInstantMessage(im); // Message sent result(true); return; } } } // try child avatar second foreach (Scene scene in m_Scenes) { // m_log.DebugFormat( // "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) { // Local message ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); user.ControllingClient.SendInstantMessage(im); // Message sent result(true); return; } } if (m_Gridmode) { //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid"); // Still here, try send via Grid SendGridInstantMessageViaXMLRPC(im, result); return; } HandleUndeliveredMessage(im, result); return; }