Esempio n. 1
0
        private GridInstantMessage BuildGroupNoticeIM(GroupNoticeInfo data, UUID groupNoticeID, UUID AgentID)
        {
            GridInstantMessage msg = new GridInstantMessage
                                         {
                                             fromAgentID = data.GroupID,
                                             toAgentID = AgentID,
                                             timestamp = data.noticeData.Timestamp,
                                             fromAgentName = data.noticeData.FromName,
                                             message = data.noticeData.Subject + "|" + data.Message,
                                             dialog = (byte) InstantMessageDialog.GroupNoticeRequested,
                                             fromGroup = true,
                                             offline = 1,
                                             ParentEstateID = 0,
                                             Position = Vector3.Zero,
                                             RegionID = UUID.Zero,
                                             imSessionID = UUID.Random()
                                         };

            //Allow offline

            if (data.noticeData.HasAttachment)
            {
                msg.binaryBucket = CreateBitBucketForGroupAttachment(data.noticeData, data.GroupID);
                //Save the sessionID for the callback by the client (reject or accept)
                //Only save if has attachment
                msg.imSessionID = data.noticeData.ItemID;
                //GroupAttachmentCache[msg.imSessionID] = data.noticeData.ItemID;
            }
            else
            {
                byte[] bucket = new byte[19];
                bucket[0] = 0; //Attachment enabled == false so 0
                bucket[1] = 0; //No attachment, so no asset type
                data.GroupID.ToBytes(bucket, 2);
                bucket[18] = 0; //dunno
                msg.binaryBucket = bucket;
            }
            return msg;
        }
Esempio n. 2
0
        public GridInstantMessage CreateGroupNoticeIM(UUID agentID, GroupNoticeInfo info, byte dialog)
        {
            if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name);

            GridInstantMessage msg = new GridInstantMessage
                                         {
                                             toAgentID = agentID,
                                             dialog = dialog,
                                             fromGroup = true,
                                             offline = 1,
                                             ParentEstateID = 0,
                                             Position = Vector3.Zero,
                                             RegionID = UUID.Zero,
                                             imSessionID = UUID.Random()
                                         };

            // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
            // Allow this message to be stored for offline use

            msg.fromAgentID = info.GroupID;
            msg.timestamp = info.noticeData.Timestamp;
            msg.fromAgentName = info.noticeData.FromName;
            msg.message = info.noticeData.Subject + "|" + info.Message;
            if (info.noticeData.HasAttachment)
            {
                msg.binaryBucket = CreateBitBucketForGroupAttachment(info.noticeData, info.GroupID);
                //Save the sessionID for the callback by the client (reject or accept)
                //Only save if has attachment
                msg.imSessionID = info.noticeData.ItemID;
                //GroupAttachmentCache[msg.imSessionID] = info.noticeData.ItemID;
            }
            else
            {
                byte[] bucket = new byte[19];
                bucket[0] = 0; //Attachment enabled == false so 0
                bucket[1] = 0; //No attachment, so no asset type
                info.GroupID.ToBytes(bucket, 2);
                bucket[18] = 0; //dunno
                msg.binaryBucket = bucket;
            }

            return msg;
        }
Esempio n. 3
0
        private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
        {
            if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name);

            // Group invitations
            if ((im.dialog == (byte) InstantMessageDialog.GroupInvitationAccept) ||
                (im.dialog == (byte) InstantMessageDialog.GroupInvitationDecline))
            {
                UUID inviteID = im.imSessionID;
                GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient),
                                                                               inviteID);

                if (inviteInfo == null)
                {
                    if (m_debugEnabled)
                        MainConsole.Instance.WarnFormat("[GROUPS]: Received an Invite IM for an invite that does not exist {0}.",
                                         inviteID);
                    return;
                }

                if (m_debugEnabled)
                    MainConsole.Instance.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID,
                                      inviteInfo.GroupID);

                UUID fromAgentID = im.fromAgentID;
                if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID))
                {
                    // Accept
                    if (im.dialog == (byte) InstantMessageDialog.GroupInvitationAccept)
                    {
                        if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Received an accept invite notice.");

                        // and the sessionid is the role
                        UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.AllScopeIDs,
                                                                                               inviteInfo.FromAgentName);
                        if (account != null)
                        {
                            m_groupData.AddAgentToGroup(account.PrincipalID, inviteInfo.AgentID, inviteInfo.GroupID,
                                                        inviteInfo.RoleID);

                            GridInstantMessage msg = new GridInstantMessage
                                                         {
                                                             imSessionID = UUID.Zero,
                                                             fromAgentID = UUID.Zero,
                                                             toAgentID = inviteInfo.AgentID,
                                                             timestamp = (uint) Util.UnixTimeSinceEpoch(),
                                                             fromAgentName = "Groups",
                                                             message =
                                                                 string.Format("You have been added to the group."),
                                                             dialog = (byte) InstantMessageDialog.MessageBox,
                                                             fromGroup = false,
                                                             offline = 0,
                                                             ParentEstateID = 0,
                                                             Position = Vector3.Zero,
                                                             RegionID = UUID.Zero,
                                                             binaryBucket = new byte[0]
                                                         };

                            OutgoingInstantMessage(msg, inviteInfo.AgentID);

                            //WTH??? noone but the invitee needs to know
                            //The other client wants to know too...
                            GroupMembershipData gmd =
                                AttemptFindGroupMembershipData(inviteInfo.AgentID, inviteInfo.AgentID, inviteInfo.GroupID);
                            m_cachedGroupTitles[inviteInfo.AgentID] = gmd;
                            m_cachedGroupMemberships.Remove(remoteClient.AgentId);
                            UpdateAllClientsWithGroupInfo(inviteInfo.AgentID, gmd.GroupTitle);
                            SendAgentGroupDataUpdate(remoteClient);
                            // XTODO: If the inviter is still online, they need an agent dataupdate 
                            // and maybe group membership updates for the invitee
                            // Reply: why do they need that? they will get told about the new user when they reopen the groups panel

                            m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
                        }
                    }

                    // Reject
                    if (im.dialog == (byte) InstantMessageDialog.GroupInvitationDecline)
                    {
                        if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Received a reject invite notice.");
                        m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
                    }
                }
            }

            // Group notices
            if ((im.dialog == (byte) InstantMessageDialog.GroupNotice))
            {
                if (!m_groupNoticesEnabled)
                    return;

                UUID GroupID = im.toAgentID;
                if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null)
                {
                    UUID NoticeID = UUID.Random();
                    string Subject = im.message.Substring(0, im.message.IndexOf('|'));
                    string Message = im.message.Substring(Subject.Length + 1);

                    byte[] bucket;
                    UUID ItemID = UUID.Zero;
                    int AssetType = 0;
                    string ItemName = "";

                    if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0))
                    {
                        bucket = new byte[19];
                        bucket[0] = 0;
                        bucket[1] = 0;
                        GroupID.ToBytes(bucket, 2);
                        bucket[18] = 0;
                    }
                    else
                    {
                        bucket = im.binaryBucket;
                        string binBucket = Utils.BytesToString(im.binaryBucket);
                        binBucket = binBucket.Remove(0, 14).Trim();

                        OSDMap binBucketOSD = (OSDMap) OSDParser.DeserializeLLSDXml(binBucket);
                        if (binBucketOSD.ContainsKey("item_id"))
                        {
                            ItemID = binBucketOSD["item_id"].AsUUID();

                            InventoryItemBase item = m_sceneList[0].InventoryService.GetItem(new InventoryItemBase(ItemID, GetRequestingAgentID(remoteClient)));
                            if (item != null)
                            {
                                AssetType = item.AssetType;
                                ItemName = item.Name;
                            }
                            else
                                ItemID = UUID.Zero;
                        }
                    }

                    m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName,
                                               Subject, Message, ItemID, AssetType, ItemName);
                    if (OnNewGroupNotice != null)
                        OnNewGroupNotice(GroupID, NoticeID);
                    GroupNoticeInfo notice = new GroupNoticeInfo()
                    {
                        BinaryBucket = im.binaryBucket,
                        GroupID = GroupID,
                        Message = Message,
                        noticeData = new GroupNoticeData()
                        {
                            AssetType = (byte)AssetType,
                            FromName = im.fromAgentName,
                            GroupID = GroupID,
                            HasAttachment = ItemID != UUID.Zero,
                            ItemID = ItemID,
                            ItemName = ItemName,
                            NoticeID = NoticeID,
                            Subject = Subject,
                            Timestamp = im.timestamp
                        }
                    };

                    SendGroupNoticeToUsers(remoteClient, notice, false);
                }
            }
            else if ((im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryDeclined) ||
                     (im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryDeclined))
            {
                //GroupAttachmentCache.Remove(im.imSessionID);
            }
            else if ((im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryAccepted) ||
                     (im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryAccepted))
            {
                UUID FolderID = new UUID(im.binaryBucket, 0);
                remoteClient.Scene.InventoryService.GiveInventoryItemAsync(remoteClient.AgentId, im.imSessionID,
                    im.imSessionID, FolderID, false,
                    (item) =>
                    {

                        if (item != null)
                            remoteClient.SendBulkUpdateInventory(item);
                    });
                //GroupAttachmentCache.Remove(im.imSessionID);
            }
            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
                // so we need to send local updates to the agent.

                UUID ejecteeID = im.toAgentID;

                im.dialog = (byte) InstantMessageDialog.MessageFromAgent;
                OutgoingInstantMessage(im, ejecteeID);

                IClientAPI ejectee = GetActiveClient(ejecteeID);
                if (ejectee != null)
                {
                    UUID groupID = im.imSessionID;
                    ejectee.SendAgentDropGroup(groupID);
                    if (ejectee.ActiveGroupId == groupID)
                        GroupTitleUpdate(ejectee, UUID.Zero, UUID.Zero);
                }
            }

                // Interop, received special 211 code for offline group notice
            else if ((im.dialog == 211))
            {
                im.dialog = (byte) InstantMessageDialog.GroupNotice;

                //In offline group notices, imSessionID is replaced with the NoticeID so that we can rebuild the packet here
                GroupNoticeInfo GND = m_groupData.GetGroupNotice(im.toAgentID, im.imSessionID);

                //We reset the ID so that if this was set before, it won't be misadded or anything to the cache
                im.imSessionID = UUID.Random();

                //Rebuild the binary bucket
                if (GND.noticeData.HasAttachment)
                {
                    im.binaryBucket = CreateBitBucketForGroupAttachment(GND.noticeData, GND.GroupID);
                    //Save the sessionID for the callback by the client (reject or accept)
                    //Only save if has attachment
                    im.imSessionID = GND.noticeData.ItemID;
                    //GroupAttachmentCache[im.imSessionID] = GND.noticeData.ItemID;
                }
                else
                {
                    byte[] bucket = new byte[19];
                    bucket[0] = 0; //Attachment enabled == false so 0
                    bucket[1] = 0; //No attachment, so no asset type
                    GND.GroupID.ToBytes(bucket, 2);
                    bucket[18] = 0; //dunno
                    im.binaryBucket = bucket;
                }

                OutgoingInstantMessage(im, im.toAgentID);

                //You MUST reset this, otherwise the client will get it twice,
                // as it goes through OnGridInstantMessage
                // which will check and then reresent the notice
                im.dialog = 211;
            }
        }
Esempio n. 4
0
        public void SendGroupNoticeToUsers(IClientAPI remoteClient, GroupNoticeInfo notice, bool localOnly)
        {
            // Send notice out to everyone that wants notices
            foreach (
                GroupMembersData member in
                    m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), notice.GroupID))
            {
                if (m_debugEnabled)
                {
                    UserAccount targetUser =
                        m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.AllScopeIDs,
                                                                         member.AgentID);
                    if (targetUser != null)
                    {
                        MainConsole.Instance.DebugFormat(
                            "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
                            notice.noticeData.NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
                    }
                    else
                    {
                        MainConsole.Instance.DebugFormat(
                            "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
                            notice.noticeData.NoticeID, member.AgentID, member.AcceptNotices);
                    }
                }

                if (member.AcceptNotices)
                {
                    // Build notice IIM
                    GridInstantMessage msg = CreateGroupNoticeIM(GetRequestingAgentID(remoteClient), notice,
                                                                 (byte)InstantMessageDialog.GroupNotice);

                    msg.toAgentID = member.AgentID;
                    OutgoingInstantMessage(msg, member.AgentID, localOnly);
                }
            }
        }
        public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
        {
            object remoteValue = DoRemote(requestingAgentID, noticeID);
            if (remoteValue != null || m_doRemoteOnly)
                return (GroupNoticeInfo)remoteValue;

            QueryFilter filter = new QueryFilter();
            filter.andFilters["NoticeID"] = noticeID;
            string[] fields = new string[9]{
                "GroupID",
                "Timestamp",
                "FromName",
                "Subject",
                "ItemID",
                "HasAttachment",
                "Message",
                "AssetType",
                "ItemName"
            };
            List<string> notice = data.Query(fields, "osgroupnotice", filter, null, null, null);

            if (notice.Count != fields.Length)
            {
                return null;
            }

            GroupNoticeData GND = new GroupNoticeData
            {
                NoticeID = noticeID,
                Timestamp = uint.Parse(notice[1]),
                FromName = notice[2],
                Subject = notice[3],
                HasAttachment = int.Parse(notice[5]) == 1
            };
            if (GND.HasAttachment)
            {
                GND.ItemID = UUID.Parse(notice[4]);
                GND.AssetType = (byte)int.Parse(notice[7]);
                GND.ItemName = notice[8];
            }

            GroupNoticeInfo info = new GroupNoticeInfo
            {
                BinaryBucket = new byte[0],
                GroupID = UUID.Parse(notice[0]),
                Message = notice[6],
                noticeData = GND
            };

            return (!agentsCanBypassGroupNoticePermsCheck.Contains(requestingAgentID) && !CheckGroupPermissions(requestingAgentID, info.GroupID, (ulong)GroupPowers.ReceiveNotices)) ? null : info;
        }
        public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
        {
            Dictionary<string, object> sendData = new Dictionary<string, object>();

            sendData["METHOD"] = "GetGroupNotice";
            sendData["requestingAgentID"] = requestingAgentID;
            sendData["noticeID"] = noticeID;

            string reqString = WebUtils.BuildXmlResponse(sendData);

            try
            {
                List<string> m_ServerURIs =
                    m_registry.RequestModuleInterface<IConfigurationService>().FindValueOf(
                        requestingAgentID.ToString(), "RemoteServerURI", false);
                foreach (string m_ServerURI in m_ServerURIs)
                {
                    string reply = SynchronousRestFormsRequester.MakeRequest("POST",
                                                                             m_ServerURI,
                                                                             reqString);
                    if (reply != string.Empty)
                    {
                        Dictionary<string, object> replyData = WebUtils.ParseXmlResponse(reply);

                        if (replyData != null)
                        {
                            Dictionary<string, object>.ValueCollection replyvalues = replyData.Values;
                            GroupNoticeInfo group = null;
#if (!ISWIN)
                            foreach (object replyvalue in replyvalues)
                            {
                                Dictionary<string, object> f = replyvalue as Dictionary<string, object>;
                                if (f != null)
                                {
                                    group = new GroupNoticeInfo(f);
                                }
                            }
#else
                            foreach (Dictionary<string, object> f in replyvalues.OfType<Dictionary<string, object>>())
                            {
                                group = new GroupNoticeInfo(f);
                            }
#endif
                            // Success
                            return group;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                MainConsole.Instance.DebugFormat("[AuroraRemoteGroupsServiceConnector]: Exception when contacting server: {0}", e);
            }

            return null;
        }
        public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
        {
            Hashtable param = new Hashtable();
            param["NoticeID"] = noticeID.ToString();

            Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param);


            if (respData.Contains("error"))
            {
                return null;
            }

            GroupNoticeInfo data = new GroupNoticeInfo
                                       {
                                           GroupID = UUID.Parse((string) respData["GroupID"]),
                                           Message = (string) respData["Message"],
                                           BinaryBucket =
                                               Utils.HexStringToBytes((string) respData["BinaryBucket"], true),
                                           noticeData =
                                               {
                                                   NoticeID = UUID.Parse((string) respData["NoticeID"]),
                                                   Timestamp = uint.Parse((string) respData["Timestamp"]),
                                                   FromName = (string) respData["FromName"],
                                                   Subject = (string) respData["Subject"],
                                                   HasAttachment = false,
                                                   AssetType = 0
                                               }
                                       };

            if (data.Message == null)
            {
                data.Message = string.Empty;
            }

            return data;
        }
        public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
        {
            if (m_debugEnabled)
                MainConsole.Instance.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]  {0} called", MethodBase.GetCurrentMethod().Name);

            OSDMap GroupNotice;
            UUID GroupID;
            if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice))
            {
                GroupNoticeInfo data = new GroupNoticeInfo
                                           {
                                               GroupID = GroupID,
                                               Message = GroupNotice["Message"].AsString(),
                                               BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(),
                                               noticeData =
                                                   {
                                                       NoticeID = noticeID,
                                                       Timestamp = GroupNotice["TimeStamp"].AsUInteger(),
                                                       FromName = GroupNotice["FromName"].AsString(),
                                                       Subject = GroupNotice["Subject"].AsString(),
                                                       HasAttachment = GroupNotice["BinaryBucket"].AsBinary().Length > 0
                                                   }
                                           };
                if (data.noticeData.HasAttachment)
                {
                    data.noticeData.ItemID = GroupNotice["ItemID"].AsUUID();
                    data.noticeData.AssetType = (byte) GroupNotice["AssetType"].AsInteger();
                    data.noticeData.ItemName = GroupNotice["ItemName"].AsString();
                }

                if (data.Message == null)
                {
                    data.Message = string.Empty;
                }

                return data;
            }
            return null;
        }
Esempio n. 9
0
        protected OSDMap OnMessageReceived(OSDMap message)
        {
            //We need to check and see if this is an GroupSessionAgentUpdate
            if (message.ContainsKey("Method") && message["Method"] == "GroupSessionAgentUpdate")
            {
                //COMES IN ON AURORA.SERVER SIDE
                //Send it on to whomever it concerns
                OSDMap innerMessage = (OSDMap) message["Message"];
                if (innerMessage["message"] == "ChatterBoxSessionAgentListUpdates")
                    //ONLY forward on this type of message
                {
                    UUID agentID = message["AgentID"];
                    IEventQueueService eqs = m_registry.RequestModuleInterface<IEventQueueService>();
                    ICapsService caps = m_registry.RequestModuleInterface<ICapsService>();
                    if (caps != null)
                    {
                        IClientCapsService clientCaps = caps.GetClientCapsService(agentID);
                        if (clientCaps != null && clientCaps.GetRootCapsService() != null)
                            eqs.Enqueue(innerMessage, agentID, clientCaps.GetRootCapsService().RegionHandle);
                    }
                }
            }
            else if (message.ContainsKey("Method") && message["Method"] == "FixGroupRoleTitles")
            {
                //COMES IN ON AURORA.SERVER SIDE FROM REGION
                UUID groupID = message["GroupID"].AsUUID();
                UUID agentID = message["AgentID"].AsUUID();
                UUID roleID = message["RoleID"].AsUUID();
                byte type = (byte) message["Type"].AsInteger();
                IGroupsServiceConnector con = DataManager.RequestPlugin<IGroupsServiceConnector>();
                List<GroupRoleMembersData> members = con.GetGroupRoleMembers(agentID, groupID);
                List<GroupRolesData> roles = con.GetGroupRoles(agentID, groupID);
                GroupRolesData everyone = null;
#if (!ISWIN)
                foreach (GroupRolesData role in roles)
                {
                    if (role.Name == "Everyone") everyone = role;
                }
#else
                foreach (GroupRolesData role in roles.Where(role => role.Name == "Everyone"))
                    everyone = role;
#endif

                List<Interfaces.GridRegion> regionsToBeUpdated = new List<Interfaces.GridRegion>();
                foreach (GroupRoleMembersData data in members)
                {
                    if (data.RoleID == roleID)
                    {
                        //They were affected by the change
                        switch ((GroupRoleUpdate) type)
                        {
                            case GroupRoleUpdate.Create:
                            case GroupRoleUpdate.NoUpdate:
                                //No changes...
                                break;

                            case GroupRoleUpdate.UpdatePowers: //Possible we don't need to send this?
                            case GroupRoleUpdate.UpdateAll:
                            case GroupRoleUpdate.UpdateData:
                            case GroupRoleUpdate.Delete:
                                if (type == (byte) GroupRoleUpdate.Delete)
                                    //Set them to the most limited role since their role is gone
                                    con.SetAgentGroupSelectedRole(data.MemberID, groupID, everyone.RoleID);
                                //Need to update their title inworld
                                ICapsService caps = m_registry.RequestModuleInterface<ICapsService>();
                                if (caps != null)
                                {
                                    IClientCapsService clientCaps = caps.GetClientCapsService(agentID);
                                    if (clientCaps != null && clientCaps.GetRootCapsService() != null)
                                        regionsToBeUpdated.Add(clientCaps.GetRootCapsService().Region);
                                }
                                break;
                        }
                    }
                }
                if (regionsToBeUpdated.Count != 0)
                {
                    ISyncMessagePosterService messagePost = m_registry.RequestModuleInterface<ISyncMessagePosterService>();
                    if (messagePost != null)
                    {
                        foreach (Interfaces.GridRegion region in regionsToBeUpdated)
                        {
                            OSDMap outgoingMessage = new OSDMap();
                            outgoingMessage["Method"] = "ForceUpdateGroupTitles";
                            outgoingMessage["GroupID"] = groupID;
                            outgoingMessage["RoleID"] = roleID;
                            outgoingMessage["RegionID"] = region.RegionID;
                            messagePost.Post(region.ServerURI, outgoingMessage);
                        }
                    }
                }
            }
            else if (message.ContainsKey("Method") && message["Method"] == "ForceUpdateGroupTitles")
            {
                //COMES IN ON REGION SIDE FROM AURORA.SERVER
                UUID groupID = message["GroupID"].AsUUID();
                UUID roleID = message["RoleID"].AsUUID();
                UUID regionID = message["RegionID"].AsUUID();
                IGroupsModule gm = m_registry.RequestModuleInterface<IGroupsModule>();
                if (gm != null)
                    gm.UpdateUsersForExternalRoleUpdate(groupID, roleID, regionID);
            }
            else if (message.ContainsKey("Method") && message["Method"] == "SendGroupNoticeToUsers")
            {
                //COMES IN ON REGION SIDE FROM AURORA.SERVER
                GroupNoticeInfo notice = new GroupNoticeInfo();
                notice.FromOSD((OSDMap)message["Notice"]);
                IGroupsModule gm = m_registry.RequestModuleInterface<IGroupsModule>();
                if (gm != null)
                    gm.SendGroupNoticeToUsers(null, notice, true);
            }
            return null;
        }