public override bool AddFolder(InventoryFolderBase folder)
        {
            //m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID);
            // Let's do a bit of sanity checking, more than the base service does
            // make sure the given folder's parent folder exists under the suitcase tree of this user

            if (!IsWithinSuitcaseTree(folder.Owner, folder.ParentID))
            {
                m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder: folder {0} is not within Suitcase tree", folder.ParentID);
                return(false);
            }

            // OK, it's legit
            if (base.AddFolder(folder))
            {
                List <XInventoryFolder> tree;
                if (m_SuitcaseTrees.TryGetValue(folder.Owner, out tree))
                {
                    tree.Add(ConvertFromOpenSim(folder));
                }

                return(true);
            }

            return(false);
        }
        public UserAccount Get(UUID userID, out bool inCache)
        {
            UserAccount account = null;

            inCache = false;
            if (m_UUIDCache.TryGetValue(userID, out account))
            {
                //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName);
                inCache = true;
                return(account);
            }

            return(null);
        }
Exemplo n.º 3
0
        public GridRegion Get(UUID scopeID, UUID regionID, out bool inCache)
        {
            inCache = false;

            GridRegion       rinfo = null;
            ScopedRegionUUID id    = new ScopedRegionUUID(scopeID, regionID);

            if (m_UUIDCache.TryGetValue(id, out rinfo))
            {
                inCache = true;
                return(rinfo);
            }

            return(null);
        }
        public UserAccount GetUserAccount(UUID scopeID, UUID userID)
        {
            // Cache check
            UserAccount account;

            if (m_accountCache.TryGetValue(userID, out account))
            {
                return(account);
            }

            NameValueCollection requestArgs = new NameValueCollection
            {
                { "RequestMethod", "GetUser" },
                { "UserID", userID.ToString() }
            };

            account = GetUser(requestArgs);

            if (account == null)
            {
                // Store null responses too, to avoid repeated lookups for missing accounts
                m_accountCache.AddOrUpdate(userID, null, CACHE_EXPIRATION_SECONDS);
            }

            return(account);
        }
Exemplo n.º 5
0
        public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
        {
            if (m_RemoteConnector.SetHome(userID, regionID, position, lookAt))
            {
                // Update the cache too
                GridUserInfo info = null;
                if (m_Infos.TryGetValue(userID, out info))
                {
                    info.HomeRegionID = regionID;
                    info.HomePosition = position;
                    info.HomeLookAt   = lookAt;
                }
                return(true);
            }

            return(false);
        }
        public void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback)
        {
            OpenJPEG.J2KLayerInfo[] result;

            // If it's cached, return the cached results
            if (m_decodedCache.TryGetValue(assetID, out result))
            {
//                m_log.DebugFormat(
//                    "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
//                    result.Length, assetID);

                callback(assetID, result);
            }
            else
            {
                // Not cached, we need to decode it.
                // Add to notify list and start decoding.
                // Next request for this asset while it's decoding will only be added to the notify list
                // once this is decoded, requests will be served from the cache and all clients in the notifylist will be updated
                bool decode = false;
                lock (m_notifyList)
                {
                    if (m_notifyList.ContainsKey(assetID))
                    {
                        m_notifyList[assetID].Add(callback);
                    }
                    else
                    {
                        List <DecodedCallback> notifylist = new List <DecodedCallback>();
                        notifylist.Add(callback);
                        m_notifyList.Add(assetID, notifylist);
                        decode = true;
                    }
                }

                // Do Decode!
                if (decode)
                {
                    Util.FireAndForget(delegate { Decode(assetID, j2kData); });
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Try to get an asset from the in-memory cache.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private AssetBase GetFromMemoryCache(string id)
        {
            AssetBase asset = null;

            if (m_MemoryCache.TryGetValue(GetAssetID(id), out asset))
            {
                m_MemoryHits++;
            }

            return(asset);
        }
Exemplo n.º 8
0
        public InventoryFolderBase GetRootFolder(UUID userID)
        {
            InventoryFolderBase root = null;

            if (m_RootFolders.TryGetValue(userID, out root))
            {
                return(root);
            }

            return(null);
        }
        private AvatarAppearance GetAppearance(UUID principalID)
        {
            AvatarAppearance a = null;

            if (m_Appearances.TryGetValue(principalID, out a))
            {
                return(a);
            }

            a = m_AvatarService.GetAppearance(principalID);
            m_Appearances.AddOrUpdate(principalID, a, 5 * 60); // 5minutes
            return(a);
        }
Exemplo n.º 10
0
        public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
        {
            InventoryCollection inv = null;
            InventoryCollection c;

            if (m_Inventories.TryGetValue(userID, out inv))
            {
                c         = new InventoryCollection();
                c.OwnerID = userID;

                c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
                {
                    return(f.ParentID == folderID);
                });
                c.Items = inv.Items.FindAll(delegate(InventoryItemBase i)
                {
                    return(i.Folder == folderID);
                });
                return(c);
            }
            return(null);
        }
Exemplo n.º 11
0
        public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
        {
            ThreadedClasses.RwLockedDictionary <AssetType, InventoryFolderBase> ff = null;
            if (m_FolderTypes.TryGetValue(userID, out ff))
            {
                InventoryFolderBase f = null;

                if (ff.TryGetValue(type, out f))
                {
                    return(f);
                }
            }

            return(null);
        }
Exemplo n.º 12
0
        public GridRegion Get(UUID scopeID, ulong handle, out bool inCache)
        {
            inCache = false;

            GridRegion           rinfo = null;
            ScopedRegionPosition pos   = new ScopedRegionPosition(scopeID, handle);

            if (m_PositionCache.TryGetValue(pos, out rinfo))
            {
                inCache = true;
                return(rinfo);
            }

            return(null);
        }
Exemplo n.º 13
0
        public UserAccount Get(string name, out bool inCache)
        {
            inCache = false;
            UserAccount account = null;
            UUID        uuid    = UUID.Zero;

            if (m_NameCache.TryGetValue(name, out uuid))
            {
                if (m_UUIDCache.TryGetValue(uuid, out account))
                {
                    inCache = true;
                    return(account);
                }
            }

            return(null);
        }
Exemplo n.º 14
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);
        }
        bool SendIMToRegion(PresenceInfo upd, GridInstantMessage im, UUID toAgentID, bool foreigner)
        {
            bool       imresult = false;
            GridRegion reginfo  = null;

            if (!m_RegionCache.TryGetValue(upd.RegionID, out reginfo))
            {
                reginfo = m_GridService.GetRegionByUUID(UUID.Zero /*!!!*/, upd.RegionID);
                if (reginfo != null)
                {
                    m_RegionCache.AddOrUpdate(upd.RegionID, reginfo, CACHE_EXPIRATION_SECONDS);
                }
            }

            if (reginfo != null)
            {
                imresult = InstantMessageServiceConnector.SendInstantMessage(reginfo.ServerURI, im);
            }
            else
            {
                m_log.DebugFormat("[HG IM SERVICE]: Failed to deliver message to {0}", reginfo.ServerURI);
                return(false);
            }

            if (imresult)
            {
                // IM delivery successful, so store the Agent's location in our local cache.
                m_UserLocationMap[toAgentID] = upd;
                return(true);
            }
            else
            {
                // try again, but lookup user this time.
                // Warning, this must call the Async version
                // of this method or we'll be making thousands of threads
                // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                // This is recursive!!!!!
                return(TrySendInstantMessage(im, upd, false, foreigner));
            }
        }
Exemplo n.º 16
0
        public GridRegion Get(UUID scopeID, string name, out bool inCache)
        {
            inCache = false;

            ScopedRegionName sname = new ScopedRegionName(scopeID, name);

            ScopedRegionUUID id;

            if (m_NameCache.TryGetValue(sname, out id))
            {
                GridRegion rinfo = null;
                if (m_UUIDCache.TryGetValue(id, out rinfo))
                {
                    inCache = true;
                    return(rinfo);
                }
            }

            return(null);
        }
Exemplo n.º 17
0
        public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
        {
            if (!(client.Scene is Scene))
            {
                return;
            }

//            Scene scene = (Scene)(client.Scene);

            GridInstantMessage im = null;

            if (m_PendingLures.TryGetValue(lureID, out im))
            {
                m_PendingLures.Remove(lureID);
                Lure(client, teleportFlags, im);
            }
            else
            {
                m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
            }
        }
Exemplo n.º 18
0
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            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.
            string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

            // 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))
            {
                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());

            int requestStartTick = Environment.TickCount;

            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);
            }
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, 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 (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;

                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, client);
                }
            }

            // 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);
            }
        }
        /// <summary>
        /// Encapsulate the XmlRpc call to standardize security and error handling.
        /// </summary>
        private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param)
        {
            XmlRpcResponse resp     = null;
            string         CacheKey = null;

            // Only bother with the cache if it isn't disabled.
            if (m_cacheTimeout > 0)
            {
                if (!function.StartsWith("groups.get"))
                {
                    // Any and all updates cause the cache to clear
                    m_memoryCache.Clear();
                }
                else
                {
                    StringBuilder sb = new StringBuilder(requestingAgentID + function);
                    foreach (object key in param.Keys)
                    {
                        if (param[key] != null)
                        {
                            sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString());
                        }
                    }

                    CacheKey = sb.ToString();
                    m_memoryCache.TryGetValue(CacheKey, out resp);
                }
            }

            if (resp == null)
            {
                if (m_debugEnabled)
                {
                    m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Cache miss for key {0}", CacheKey);
                }

                string UserService;
                UUID   SessionID;
                GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID);

                param.Add("RequestingAgentID", requestingAgentID.ToString());
                param.Add("RequestingAgentUserService", UserService);
                param.Add("RequestingSessionID", SessionID.ToString());
                param.Add("ReadKey", m_groupReadKey);
                param.Add("WriteKey", m_groupWriteKey);

                IList parameters = new ArrayList();
                parameters.Add(param);

                ConfigurableKeepAliveXmlRpcRequest req;
                req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive);

                try
                {
                    resp = req.Send(m_groupsServerURI, 10000);

                    if ((m_cacheTimeout > 0) && (CacheKey != null))
                    {
                        m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout));
                    }
                }
                catch (Exception e)
                {
                    m_log.ErrorFormat(
                        "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}",
                        function, m_groupsServerURI);

                    m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace);

                    foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
                    {
                        m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine);
                    }

                    foreach (string key in param.Keys)
                    {
                        m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString());
                    }

                    Hashtable respData = new Hashtable();
                    respData.Add("error", e.ToString());
                    return(respData);
                }
            }

            if (resp.Value is Hashtable)
            {
                Hashtable respData = (Hashtable)resp.Value;
                if (respData.Contains("error") && !respData.Contains("succeed"))
                {
                    LogRespDataToConsoleError(requestingAgentID, function, param, respData);
                }

                return(respData);
            }

            m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString());

            if (resp.Value is ArrayList)
            {
                ArrayList al = (ArrayList)resp.Value;
                m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count);

                foreach (object o in al)
                {
                    m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString());
                }
            }
            else
            {
                m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString());
            }

            Hashtable error = new Hashtable();

            error.Add("error", "invalid return value");
            return(error);
        }
Exemplo n.º 21
0
        /// <summary>
        /// Send updated position information about an agent in this region to a neighbor
        /// This operation may be called very frequently if an avatar is moving about in
        /// the region.
        /// </summary>
        public bool UpdateAgent(GridRegion destination, AgentPosition data)
        {
            bool v = true;

            if (_failedSims.TryGetValue(destination.ServerURI, out v))
            {
                return(false);
            }

            // The basic idea of this code is that the first thread that needs to
            // send an update for a specific avatar becomes the worker for any subsequent
            // requests until there are no more outstanding requests. Further, only send the most
            // recent update; this *should* never be needed but some requests get
            // slowed down and once that happens the problem with service end point
            // limits kicks in and nothing proceeds
            string uri = destination.ServerURI + AgentPath() + data.AgentID + "/";

            lock (m_updateAgentQueue)
            {
                if (m_updateAgentQueue.ContainsKey(uri))
                {
                    // Another thread is already handling
                    // updates for this simulator, just update
                    // the position and return, overwrites are
                    // not a problem since we only care about the
                    // last update anyway
                    m_updateAgentQueue[uri] = data;
                    return(true);
                }

                // Otherwise update the reference and start processing
                m_updateAgentQueue[uri] = data;
            }

            AgentPosition pos     = null;
            bool          success = true;

            while (success)
            {
                lock (m_updateAgentQueue)
                {
                    // save the position
                    AgentPosition lastpos = pos;

                    pos = m_updateAgentQueue[uri];

                    // this is true if no one put a new
                    // update in the map since the last
                    // one we processed, if thats the
                    // case then we are done
                    if (pos == lastpos)
                    {
                        m_updateAgentQueue.Remove(uri);
                        return(true);
                    }
                }

                success = UpdateAgent(destination, (IAgentData)pos, 10000);
            }
            // we get here iff success == false
            // blacklist sim for 2 minutes
            lock (m_updateAgentQueue)
            {
                _failedSims.AddOrUpdate(destination.ServerURI, true, 120);
                m_updateAgentQueue.Remove(uri);
            }
            return(false);
        }