public bool Cross(ScenePresence agent, bool isFlying)
        {
            Scene scene = agent.Scene;
            Vector3 pos = agent.AbsolutePosition;
            Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
            uint neighbourx;
            uint neighboury;
            const float boundaryDistance = 1.7f;

            // assuming that the need for crossing was verified by callers

            int x, y;

            if (scene.RegionInfo.CombinedRegionHandle != 0) // we are a slave region send to main region
            {
                Utils.LongToUInts(scene.RegionInfo.CombinedRegionHandle, out neighbourx, out neighboury);

                agent.IsInTransit = true;

                Vector3 newposition = pos;
                newposition.X += ((int)scene.RegionInfo.RegionLocX * Constants.RegionSize - (int)neighbourx);
                newposition.Y += ((int)scene.RegionInfo.RegionLocY * Constants.RegionSize - (int)neighboury);
                agent.ControllingClient.SendAgentAlertMessage(
                    String.Format("Relocating you in root region"), false);

                InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
                return true;
            }

            if (pos.X - boundaryDistance < 0) // going W
            {
                x = -1;
                newpos.X = Constants.RegionSize + pos.X - boundaryDistance;
            }
            else // assume we are going E
            {
                x = ((int)(pos.X + boundaryDistance) / (int)Constants.RegionSize);
                newpos.X = pos.X - x * (int)Constants.RegionSize;
            }

            x += (int)scene.RegionInfo.RegionLocX;
            neighbourx = (uint)x;
            x *= (int)Constants.RegionSize;

            if (pos.Y - boundaryDistance < 0) // going S  SW or SE
            {
                y = -1;
                newpos.Y = Constants.RegionSize + pos.Y - boundaryDistance;
            }
            else // assume we are going N NW or NE
            {
                y = ((int)(pos.Y + boundaryDistance) / (int)Constants.RegionSize);
                newpos.Y = pos.Y - y * (int)Constants.RegionSize;
            }

            y += (int)scene.RegionInfo.RegionLocY;
            neighboury = (uint)y;
            y *= (int)Constants.RegionSize;


            //            int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);

            ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);

            ExpiringCache<ulong, DateTime> r;
            DateTime banUntil;

            if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
            {
                if (r.TryGetValue(neighbourHandle, out banUntil))
                {
                    if (DateTime.Now < banUntil)
                        return false;
                    r.Remove(neighbourHandle);
                }
            }
            else
            {
                r = null;
            }


            GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, x, y);

            if (neighbourRegion == null)
                return false;

            string reason;
            string version;
            if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
            {
                agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
                if (r == null)
                {
                    r = new ExpiringCache<ulong, DateTime>();
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));

                    m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
                }
                else
                {
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
                }
                return false;
            }

            agent.IsInTransit = true;

            CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
            d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);

            return true;
        }
Example #2
0
        public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
        {
            if (!(client.Scene is Scene))
            {
                return;
            }

            Scene         scene    = (Scene)(client.Scene);
            ScenePresence presence = scene.GetScenePresence(client.AgentId);

            message += "@" + m_ThisGridURL;

            m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);

            UUID sessionID = UUID.Random();

            GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
                                                          client.FirstName + " " + client.LastName, targetid,
                                                          (byte)InstantMessageDialog.RequestTeleport, false,
                                                          message, sessionID, false, presence.AbsolutePosition,
                                                          new Byte[0], true);

            m.RegionID = client.Scene.RegionInfo.RegionID.Guid;

            m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
            m_PendingLures.Add(sessionID, m, 7200); // 2 hours

            if (m_TransferModule != null)
            {
                m_TransferModule.SendInstantMessage(m,
                                                    delegate(bool success) { });
            }
        }
Example #3
0
        public UUID CreateCapability(CapsRequestCallback localHandler, bool clientCertRequired, object state, double ttlSeconds)
        {
            UUID           id         = UUID.Random();
            CapsRedirector redirector = new CapsRedirector(localHandler, null, clientCertRequired, state);

            lock (syncRoot)
                expiringCaps.Add(id, redirector, DateTime.Now + TimeSpan.FromSeconds(ttlSeconds));

            return(id);
        }
Example #4
0
        public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
        {
            IScenePresence presence = client.Scene.GetScenePresence(client.AgentId);
            UUID           dest     = Util.BuildFakeParcelID(
                client.Scene.RegionInfo.RegionHandle,
                (uint)presence.AbsolutePosition.X,
                (uint)presence.AbsolutePosition.Y,
                (uint)presence.AbsolutePosition.Z);

            string mainGridURL = GetMainGridURL();

            message += "@" + mainGridURL;//Add it to the message

            GridInstantMessage m;

            if (m_allowGodTeleports && client.Scene.Permissions.IsGod(client.AgentId) && presence.GodLevel > 0) //if we are an admin and are in god mode
            {
                if (client.Scene.Permissions.IsGod(targetid))                                                   //if they are an admin
                {
                    //Gods do not tp other gods
                    m = new GridInstantMessage(client.Scene, client.AgentId,
                                               client.FirstName + " " + client.LastName, targetid,
                                               (byte)InstantMessageDialog.RequestTeleport, false,
                                               message, dest, false, presence.AbsolutePosition,
                                               new Byte[0]);
                }
                else
                {
                    //God tp them
                    m = new GridInstantMessage(client.Scene, client.AgentId,
                                               client.FirstName + " " + client.LastName, targetid,
                                               (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
                                               "", dest, false, presence.AbsolutePosition,
                                               new Byte[0]);
                }
            }
            else
            {
                //Not a god, so no god tp
                m = new GridInstantMessage(client.Scene, client.AgentId,
                                           client.FirstName + " " + client.LastName, targetid,
                                           (byte)InstantMessageDialog.RequestTeleport, false,
                                           message, dest, false, presence.AbsolutePosition,
                                           new Byte[0]);
            }
            m_PendingLures.Add(m.imSessionID, m, 7200);  // 2 hours
            if (m_TransferModule != null)
            {
                m_TransferModule.SendInstantMessage(m);
            }
        }
        public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
        {
            //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
            //reason = string.Empty;

            //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
            //    membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
            ExtendedGroupRecord group = d();

            if (group == null)
            {
                return(UUID.Zero);
            }

            if (group.GroupID != UUID.Zero)
            {
                lock (m_Cache)
                {
                    m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
                    if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
                    {
                        m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
                    }
                }
            }

            return(group.GroupID);
        }
Example #6
0
        public bool HasGroupAccess(UUID avatar)
        {
            if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
            {
                ScenePresence sp;
                if (!m_scene.TryGetScenePresence(avatar, out sp))
                {
                    bool isMember;
                    if (m_groupMemberCache.TryGetValue(avatar, out isMember))
                    {
                        m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
                        return(isMember);
                    }

                    IGroupsModule groupsModule = m_scene.RequestModuleInterface <IGroupsModule>();
                    if (groupsModule == null)
                    {
                        return(false);
                    }

                    GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
                    if (membership == null || membership.Length == 0)
                    {
                        m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
                        return(false);
                    }

                    foreach (GroupMembershipData d in membership)
                    {
                        if (d.GroupID == LandData.GroupID)
                        {
                            m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
                            return(true);
                        }
                    }
                    m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
                    return(false);
                }

                return(sp.ControllingClient.IsGroupMember(LandData.GroupID));
            }
            return(false);
        }
Example #7
0
        void OnIncomingInstantMessage(GridInstantMessage im)
        {
            if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
            {
                UUID sessionID = new UUID(im.imSessionID);

                if (!m_PendingLures.Contains(sessionID))
                {
                    m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
                    m_PendingLures.Add(sessionID, im, 7200); // 2 hours
                }

                // Forward. We do this, because the IM module explicitly rejects
                // IMs of this type
                if (m_TransferModule != null)
                {
                    m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
                }
            }
        }
 public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
 {
     lock (m_FolderTypes)
     {
         Dictionary <AssetType, InventoryFolderBase> ff = null;
         if (!m_FolderTypes.TryGetValue(userID, out ff))
         {
             ff = new Dictionary <AssetType, InventoryFolderBase>();
             m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
         }
         if (!ff.ContainsKey(type))
         {
             ff.Add(type, folder);
         }
     }
 }
Example #9
0
        public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
        {
            Dictionary <AssetType, InventoryFolderBase> ff = null;

            if (!m_FolderTypes.TryGetValue(userID, out ff))
            {
                ff = new Dictionary <AssetType, InventoryFolderBase>();
                m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
            }

            // We need to lock here since two threads could potentially retrieve the same dictionary
            // and try to add a folder for that type simultaneously.  Dictionary<>.Add() is not described as thread-safe in the SDK
            // even if the folders are identical.
            lock (ff)
            {
                if (!ff.ContainsKey(type))
                {
                    ff.Add(type, folder);
                }
            }
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            int requestStartTick = Environment.TickCount;

            UUID fromAgentID = new UUID(im.fromAgentID);

            // Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
            // is not necessary.
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);

            int groupMembersCount = groupMembers.Count;

            PresenceInfo[] onlineAgents = null;

            // In V2 we always only send to online members.
            // Sending to offline members is not an option.

            // We cache in order not to overwhelm the presence service on large grids with many groups.  This does
            // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
            // (assuming this is the same across all grid simulators).
            if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();
                onlineAgents = m_presenceService.GetAgents(t1);
                m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
            }

            HashSet <string> onlineAgentsUuidSet = new HashSet <string>();

            Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));

            groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();

//            if (m_debugEnabled)
//                    m_log.DebugFormat(
//                        "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
//                        groupID, groupMembersCount, groupMembers.Count());

            im.imSessionID = groupID.Guid;
            im.fromGroup   = true;
            IClientAPI thisClient = GetActiveClient(fromAgentID);

            if (thisClient != null)
            {
                im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
            }

            if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
            {
                ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
                if (groupInfo != null)
                {
                    im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
                }
            }

            // Send to self first of all
            im.toAgentID = im.fromAgentID;
            im.fromGroup = true;
            ProcessMessageFromGroupSession(im);

            List <UUID> regions            = new List <UUID>();
            List <UUID> clientsAlreadySent = new List <UUID>();

            // Then send to everybody else
            foreach (GroupMembersData member in groupMembers)
            {
                if (member.AgentID.Guid == im.fromAgentID)
                {
                    continue;
                }

                if (clientsAlreadySent.Contains(member.AgentID))
                {
                    continue;
                }

                clientsAlreadySent.Add(member.AgentID);

                if (sendCondition != null)
                {
                    if (!sendCondition(member))
                    {
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
                                member.AgentID);
                        }

                        continue;
                    }
                }
                else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
                    }

                    continue;
                }

                im.toAgentID = member.AgentID.Guid;

                IClientAPI client = GetActiveClient(member.AgentID);
                if (client == null)
                {
                    // If they're not local, forward across the grid
                    // BUT do it only once per region, please! Sim would be even better!
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
                    }

                    bool reallySend = true;
                    if (onlineAgents != null)
                    {
                        PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
                        if (regions.Contains(presence.RegionID))
                        {
                            reallySend = false;
                        }
                        else
                        {
                            regions.Add(presence.RegionID);
                        }
                    }

                    if (reallySend)
                    {
                        // We have to create a new IM structure because the transfer module
                        // uses async send
                        GridInstantMessage msg = new GridInstantMessage(im, true);
                        m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
                    }
                }
                else
                {
                    // Deliver locally, directly
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
                    }

                    ProcessMessageFromGroupSession(im);
                }
            }

            if (m_debugEnabled)
            {
                m_log.DebugFormat(
                    "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
                    groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
            }
        }
Example #11
0
        public bool Cross(ScenePresence agent, bool isFlying)
        {
            Scene scene = agent.Scene;
            Vector3 pos = agent.AbsolutePosition;
            Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
            uint neighbourx = scene.RegionInfo.RegionLocX;
            uint neighboury = scene.RegionInfo.RegionLocY;
            const float boundaryDistance = 1.7f;
            Vector3 northCross = new Vector3(0, boundaryDistance, 0);
            Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
            Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
            Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);

            // distance to edge that will trigger crossing


            // distance into new region to place avatar
            const float enterDistance = 0.5f;

            if (scene.TestBorderCross(pos + westCross, Cardinals.W))
            {
                if (scene.TestBorderCross(pos + northCross, Cardinals.N))
                {
                    Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                    neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                }
                else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
                {
                    Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
                    if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
                    {
                        neighboury--;
                        newpos.Y = Constants.RegionSize - enterDistance;
                    }
                    else
                    {
                        agent.IsInTransit = true;

                        neighboury = b.TriggerRegionY;
                        neighbourx = b.TriggerRegionX;

                        Vector3 newposition = pos;
                        newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
                        newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
                        agent.ControllingClient.SendAgentAlertMessage(
                            String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
                        InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
                        return true;
                    }
                }

                Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
                if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
                {
                    neighbourx--;
                    newpos.X = Constants.RegionSize - enterDistance;
                }
                else
                {
                    agent.IsInTransit = true;

                    neighboury = ba.TriggerRegionY;
                    neighbourx = ba.TriggerRegionX;


                    Vector3 newposition = pos;
                    newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
                    newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
                    agent.ControllingClient.SendAgentAlertMessage(
                            String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
                    InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);


                    return true;
                }

            }
            else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
            {
                Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
                neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                newpos.X = enterDistance;

                if (scene.TestBorderCross(pos + southCross, Cardinals.S))
                {
                    Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
                    if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
                    {
                        neighboury--;
                        newpos.Y = Constants.RegionSize - enterDistance;
                    }
                    else
                    {
                        agent.IsInTransit = true;

                        neighboury = ba.TriggerRegionY;
                        neighbourx = ba.TriggerRegionX;
                        Vector3 newposition = pos;
                        newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
                        newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
                        agent.ControllingClient.SendAgentAlertMessage(
                            String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
                        InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
                        return true;
                    }
                }
                else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
                {
                    Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                    neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
                    newpos.Y = enterDistance;
                }


            }
            else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
            {
                Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
                if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
                {
                    neighboury--;
                    newpos.Y = Constants.RegionSize - enterDistance;
                }
                else
                {
                    agent.IsInTransit = true;

                    neighboury = b.TriggerRegionY;
                    neighbourx = b.TriggerRegionX;
                    Vector3 newposition = pos;
                    newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
                    newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
                    agent.ControllingClient.SendAgentAlertMessage(
                            String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
                    InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
                    return true;
                }
            }
            else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
            {

                Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                newpos.Y = enterDistance;
            }

            /*

            if (pos.X < boundaryDistance) //West
            {
                neighbourx--;
                newpos.X = Constants.RegionSize - enterDistance;
            }
            else if (pos.X > Constants.RegionSize - boundaryDistance) // East
            {
                neighbourx++;
                newpos.X = enterDistance;
            }

            if (pos.Y < boundaryDistance) // South
            {
                neighboury--;
                newpos.Y = Constants.RegionSize - enterDistance;
            }
            else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
            {
                neighboury++;
                newpos.Y = enterDistance;
            }
            */

            ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));

            int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);

            ExpiringCache<ulong, DateTime> r;
            DateTime banUntil;

            if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
            {
                if (r.TryGetValue(neighbourHandle, out banUntil))
                {
                    if (DateTime.Now < banUntil)
                        return false;
                    r.Remove(neighbourHandle);
                }
            }
            else
            {
                r = null;
            }

            GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);

            string reason;
            string version;
            if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
            {
                agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
                if (r == null)
                {
                    r = new ExpiringCache<ulong, DateTime>();
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));

                    m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
                }
                else
                {
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
                }
                return false;
            }

            agent.IsInTransit = true;

            CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
            d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);

            return true;
        }
        public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
        {
            version = String.Empty;
            newpos = new Vector3(pos.X, pos.Y, pos.Z);

//            m_log.DebugFormat(
//                "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);

            uint neighbourx = scene.RegionInfo.RegionLocX;
            uint neighboury = scene.RegionInfo.RegionLocY;
            const float boundaryDistance = 1.7f;
            Vector3 northCross = new Vector3(0, boundaryDistance, 0);
            Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
            Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
            Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);

            // distance into new region to place avatar
            const float enterDistance = 0.5f;

            if (scene.TestBorderCross(pos + westCross, Cardinals.W))
            {
                if (scene.TestBorderCross(pos + northCross, Cardinals.N))
                {
                    Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                    neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                }
                else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
                {
                    neighboury--;
                    newpos.Y = Constants.RegionSize - enterDistance;
                }

                neighbourx--;
                newpos.X = Constants.RegionSize - enterDistance;
            }
            else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
            {
                Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
                neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                newpos.X = enterDistance;

                if (scene.TestBorderCross(pos + southCross, Cardinals.S))
                {
                    neighboury--;
                    newpos.Y = Constants.RegionSize - enterDistance;
                }
                else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
                {
                    Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                    neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
                    newpos.Y = enterDistance;
                }
            }
            else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
            {
                Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
                neighboury--;
                newpos.Y = Constants.RegionSize - enterDistance;
            }
            else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
            {
                Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
                neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
                newpos.Y = enterDistance;
            }

            /*

            if (pos.X < boundaryDistance) //West
            {
                neighbourx--;
                newpos.X = Constants.RegionSize - enterDistance;
            }
            else if (pos.X > Constants.RegionSize - boundaryDistance) // East
            {
                neighbourx++;
                newpos.X = enterDistance;
            }

            if (pos.Y < boundaryDistance) // South
            {
                neighboury--;
                newpos.Y = Constants.RegionSize - enterDistance;
            }
            else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
            {
                neighboury++;
                newpos.Y = enterDistance;
            }
            */

            xDest = neighbourx;
            yDest = neighboury;

            int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);

            ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);

            ExpiringCache<ulong, DateTime> r;
            DateTime banUntil;

            if (m_bannedRegions.TryGetValue(agentID, out r))
            {
                if (r.TryGetValue(neighbourHandle, out banUntil))
                {
                    if (DateTime.Now < banUntil)
                        return null;
                    r.Remove(neighbourHandle);
                }
            }
            else
            {
                r = null;
            }

            GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);

            string reason;
            if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
            {
                if (r == null)
                {
                    r = new ExpiringCache<ulong, DateTime>();
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));

                    m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
                }
                else
                {
                    r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
                }
                return null;
            }

            return neighbourRegion;
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            int requestStartTick = Environment.TickCount;

            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID);
            int groupMembersCount = groupMembers.Count;
            HashSet <string> attemptDeliveryUuidSet = null;

            if (m_messageOnlineAgentsOnly)
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

                // We cache in order not to overwhlem the presence service on large grids with many groups.  This does
                // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
                // (assuming this is the same across all grid simulators).
                PresenceInfo[] onlineAgents;
                if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
                {
                    onlineAgents = m_presenceService.GetAgents(t1);
                    m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
                }

                attemptDeliveryUuidSet
                    = new HashSet <string>(Array.ConvertAll <PresenceInfo, string>(onlineAgents, pi => pi.UserID));
            }
            else
            {
                attemptDeliveryUuidSet
                    = new HashSet <string>(groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()));

                if (m_debugEnabled)
                {
                    m_log.DebugFormat(
                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
                        groupID, groupMembers.Count);
                }
            }

            foreach (GroupMembersData member in groupMembers)
            {
                if (sendCondition != null)
                {
                    if (!sendCondition(member))
                    {
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition",
                                member.AgentID);
                        }

                        continue;
                    }
                }
                else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat(
                            "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
                    }

                    continue;
                }

                // Copy Message
                GridInstantMessage msg = new GridInstantMessage();
                msg.imSessionID    = im.imSessionID;
                msg.fromAgentName  = im.fromAgentName;
                msg.message        = im.message;
                msg.dialog         = im.dialog;
                msg.offline        = im.offline;
                msg.ParentEstateID = im.ParentEstateID;
                msg.Position       = im.Position;
                msg.RegionID       = im.RegionID;
                msg.binaryBucket   = im.binaryBucket;
                msg.timestamp      = (uint)Util.UnixTimeSinceEpoch();

                msg.fromAgentID = im.fromAgentID;
                msg.fromGroup   = true;

                msg.toAgentID = member.AgentID.Guid;

                if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString()))
                {
                    IClientAPI client = GetActiveClient(member.AgentID);
                    if (client == null)
                    {
                        int startTick = Environment.TickCount;

                        // If they're not local, forward across the grid
                        m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });

                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms",
                                member.AgentID, Environment.TickCount - startTick);
                        }
                    }
                    else
                    {
                        int startTick = Environment.TickCount;

                        ProcessMessageFromGroupSession(msg, client);

                        // Deliver locally, directly
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms",
                                member.AgentID, Environment.TickCount - startTick);
                        }
                    }
                }
                else if (im.dialog != (byte)InstantMessageDialog.SessionAdd &&
                         im.dialog != (byte)InstantMessageDialog.SessionDrop)
                {
                    int startTick = Environment.TickCount;

                    m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { });

                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat(
                            "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms",
                            member.AgentID, Environment.TickCount - startTick);
                    }
                }
            }

            if (m_debugEnabled)
            {
                m_log.DebugFormat(
                    "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms",
                    groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick);
            }
        }
        public bool TryGetSessionInfo(Request request, out SessionInfo sinfo)
        {
            bool success = false;

            sinfo = new SessionInfo();
            if (request.Query.ContainsKey("sid"))
            {
                string sid = request.Query["sid"].ToString();
                if (m_Sessions.Contains(sid))
                {
                    SessionInfo session;
                    if (m_Sessions.TryGetValue(sid, out session) &&
                        session.IpAddress == request.IPEndPoint.Address.ToString())
                    {
                        sinfo = session;
                        m_Sessions.AddOrUpdate(sid, session, m_WebApp.SessionTimeout);
                        success = true;
                    }
                }
                else
                {
                    UUID sessionid = UUID.Zero;
                    if (UUID.TryParse(request.Query["sid"].ToString(), out sessionid))
                    {
                        PresenceInfo pinfo = m_PresenceService.GetAgent(sessionid);
                        if (pinfo != null)
                        {
                            m_log.DebugFormat("[Wifi]: User is present in the grid");
                            success = true;

                            UserAccount account = null;
                            if (request.Query.ContainsKey("uid"))
                            {
                                UUID userID = UUID.Zero;
                                if (UUID.TryParse(request.Query["uid"].ToString(), out userID))
                                {
                                    account = m_UserAccountService.GetUserAccount(UUID.Zero, userID);
                                }
                            }
                            else
                            {
                                m_log.DebugFormat("[Wifi]: No uid in Query");
                            }

                            sinfo.IpAddress = request.IPEndPoint.Address.ToString();
                            sinfo.Sid       = request.Query["sid"].ToString();
                            sinfo.Account   = account;
                            sinfo.Notify    = new NotificationData();

                            m_Sessions.Add(sinfo.Sid, sinfo, m_WebApp.SessionTimeout);
                        }
                        else
                        {
                            m_log.DebugFormat("[Wifi]: User is not present in the grid");
                        }
                    }
                    else
                    {
                        m_log.DebugFormat("[Wifi]: Unable o parse sid {0}", request.Query["sid"].ToString());
                    }
                }
            }
            //else
            //    m_log.DebugFormat("[Wifi]: no sid in Query");

            return(success);
        }
Example #15
0
        public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
        {
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID);
            int groupMembersCount = groupMembers.Count;

            if (m_messageOnlineAgentsOnly)
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

                // We cache in order not to overwhlem the presence service on large grids with many groups.  This does
                // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
                // (assuming this is the same across all grid simulators).
                PresenceInfo[] onlineAgents;
                if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
                {
                    onlineAgents = m_presenceService.GetAgents(t1);
                    m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
                }

                HashSet <string> onlineAgentsUuidSet = new HashSet <string>();
                Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));

                groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();

                //            if (m_debugEnabled)
//                    m_log.DebugFormat(
//                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
//                        groupID, groupMembersCount, groupMembers.Count());
            }
            else
            {
                if (m_debugEnabled)
                {
                    m_log.DebugFormat(
                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
                        groupID, groupMembers.Count);
                }
            }

            int requestStartTick = Environment.TickCount;

            foreach (GroupMembersData member in groupMembers)
            {
                if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
                    }
                    continue;
                }

                // Copy Message
                GridInstantMessage msg = new GridInstantMessage();
                msg.imSessionID    = groupID.Guid;
                msg.fromAgentName  = im.fromAgentName;
                msg.message        = im.message;
                msg.dialog         = im.dialog;
                msg.offline        = im.offline;
                msg.ParentEstateID = im.ParentEstateID;
                msg.Position       = im.Position;
                msg.RegionID       = im.RegionID;
                msg.binaryBucket   = im.binaryBucket;
                msg.timestamp      = (uint)Util.UnixTimeSinceEpoch();

                msg.fromAgentID = im.fromAgentID;
                msg.fromGroup   = true;

                msg.toAgentID = member.AgentID.Guid;

                IClientAPI client = GetActiveClient(member.AgentID);
                if (client == null)
                {
                    // If they're not local, forward across the grid
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID);
                    }
                    m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
                }
                else
                {
                    // Deliver locally, directly
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
                    }
                    ProcessMessageFromGroupSession(msg);
                }
            }

            // Temporary for assessing how long it still takes to send messages to large online groups.
            if (m_messageOnlineAgentsOnly)
            {
                m_log.DebugFormat(
                    "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
                    groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
            }
        }
        public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
        {
            ulong regionHandle = Util.UIntsToLong((uint)x, (uint)y);

            if (m_regionCache.Contains(regionHandle))
            {
                return((GridRegion)m_regionCache[regionHandle]);
            }

            Dictionary <string, object> sendData = new Dictionary <string, object>();

            sendData["SCOPEID"] = scopeID.ToString();
            sendData["X"]       = x.ToString();
            sendData["Y"]       = y.ToString();

            sendData["METHOD"] = "get_region_by_position";
            string reply = string.Empty;
            string uri   = m_ServerURI + "/grid";

            try
            {
                reply = SynchronousRestFormsRequester.MakeRequest("POST",
                                                                  uri,
                                                                  ServerUtils.BuildQueryString(sendData), m_Auth);
            }
            catch (Exception e)
            {
                m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message);
                return(null);
            }

            GridRegion rinfo = null;

            if (reply != string.Empty)
            {
                Dictionary <string, object> replyData = ServerUtils.ParseXmlResponse(reply);

                if ((replyData != null) && (replyData["result"] != null))
                {
                    if (replyData["result"] is Dictionary <string, object> )
                    {
                        rinfo = new GridRegion((Dictionary <string, object>)replyData["result"]);
                    }
                    //else
                    //    m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received no region",
                    //        scopeID, x, y);
                }
                else
                {
                    m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received null response",
                                      scopeID, x, y);
                }
            }
            else
            {
                m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply");
            }

            m_regionCache.Add(regionHandle, rinfo, TimeSpan.FromSeconds(600));

            return(rinfo);
        }