/// <summary>
        /// Callback for a client request for ParcelVoiceInfo
        /// </summary>
        /// <param name="scene">current scene object of the client</param>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param"></param>
        /// <param name="agentID"></param>
        /// <param name="caps"></param>
        /// <returns></returns>
        public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param,
                                             UUID agentID, Caps caps)
        {
            ScenePresence avatar = scene.GetScenePresence(agentID);
            string avatarName = avatar.Name;

            // - check whether we have a region channel in our cache
            // - if not: 
            //       create it and cache it
            // - send it to the client
            // - send channel_uri: as "sip:regionID@m_sipDomain"
            try
            {
                LLSDParcelVoiceInfoResponse parcelVoiceInfo;
                string channelUri;

                if (null == scene.LandChannel) 
                    throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
                                                      scene.RegionInfo.RegionName, avatarName));



                // get channel_uri: check first whether estate
                // settings allow voice, then whether parcel allows
                // voice, if all do retrieve or obtain the parcel
                // voice channel
                LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);

                m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
                                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);

                // TODO: EstateSettings don't seem to get propagated...
                // if (!scene.RegionInfo.EstateSettings.AllowVoice)
                // {
                //     m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings",
                //                       scene.RegionInfo.RegionName);
                //     channel_uri = String.Empty;
                // }
                // else

                if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0)
                {
                    m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel",
                                      scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName);
                    channelUri = String.Empty;
                }
                else
                {
                    channelUri = ChannelUri(scene, land);
                }

                // fill in our response to the client
                Hashtable creds = new Hashtable();
                creds["channel_uri"] = channelUri;

                parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
                string r = LLSDHelpers.SerializeLLSDReply(parcelVoiceInfo);

                m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", 
                                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
                return r;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", 
                                  scene.RegionInfo.RegionName, avatarName, e.Message);
                m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", 
                                  scene.RegionInfo.RegionName, avatarName, e.ToString());

                return "<llsd>undef</llsd>";
            }
        }
        /// <summary>
        /// Callback for a client request for ParcelVoiceInfo
        /// </summary>
        /// <param name="scene">current scene object of the client</param>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param"></param>
        /// <param name="agentID"></param>
        /// <param name="caps"></param>
        /// <returns></returns>
        public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param,
                                             UUID agentID, Caps caps)
        {
            ScenePresence avatar = scene.GetScenePresence(agentID);
            if (avatar == null) // seen on the main grid, perhaps on user disconnect or viewer crash
                return EMPTY_RESPONSE;

            string        avatarName = avatar.Name;

            // - check whether we have a region channel in our cache
            // - if not: 
            //       create it and cache it
            // - send it to the client
            // - send channel_uri: as "sip:regionID@m_sipDomain"
            try
            {
                LLSDParcelVoiceInfoResponse parcelVoiceInfo;
                string channel_uri;

                if (null == scene.LandChannel) 
                    throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
                                                      scene.RegionInfo.RegionName, avatarName));

                // If the avatar is in transit between regions, avatar.AbsolutePosition calls below can return undefined values.
                if (avatar.IsInTransit)
                {
                    m_log.WarnFormat("[VivoxVoice][PARCELVOICE]: Cannot process voice info request - avatar {0} is still in transit between regions.", avatarName);
                    return EMPTY_RESPONSE;
                }

                // get channel_uri: check first whether estate
                // settings allow voice, then whether parcel allows
                // voice, if all do retrieve or obtain the parcel
                // voice channel
                LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
                if (land == null)
                {
                    // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar\"{1}\" at ({2}): Land parcel not found.",
                    //                scene.RegionInfo.RegionName, avatarName, avatar.AbsolutePosition.ToString());
                    return EMPTY_RESPONSE;
                }

                // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
                //                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
                // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}",
                //                   avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);

                // TODO: EstateSettings don't seem to get propagated...
                if (!scene.RegionInfo.EstateSettings.AllowVoice)
                {
                    m_log.InfoFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings",
                                      scene.RegionInfo.RegionName);
                    channel_uri = String.Empty;
                }

                if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0)
                {
                    m_log.InfoFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel",
                                      scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName);
                    channel_uri = String.Empty;
                }
                else
                {
                    channel_uri = RegionGetOrCreateChannel(scene, land);
                }

                // fill in our response to the client
                Hashtable creds = new Hashtable();
                creds["channel_uri"] = channel_uri;

                parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
                string r = LLSDHelpers.SerializeLLSDReply(parcelVoiceInfo);

                // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", 
                //                   scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
                return r;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", 
                                  scene.RegionInfo.RegionName, avatarName, e.Message);
                m_log.ErrorFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} exception", 
                                  scene.RegionInfo.RegionName, avatarName, e.ToString());

                return EMPTY_RESPONSE;
            }
        }
Exemple #3
0
        /// Callback for a client request for ParcelVoiceInfo
        public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param,
                                             UUID agentID)
        {
            m_log.Debug("[MurmurVoice] Calling ParcelVoiceInfoRequest...");
            try
            {
                ScenePresence avatar = scene.GetScenePresence(agentID);

                string channel_uri = String.Empty;

                if (null == scene.LandChannel) 
                    throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
                                                      scene.RegionInfo.RegionName, avatar.Name));

                // get channel_uri: check first whether estate
                // settings allow voice, then whether parcel allows
                // voice, if all do retrieve or obtain the parcel
                // voice channel
                LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
                if (null == land) 
                    throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
                                                      scene.RegionInfo.RegionName, avatar.Name));

                m_log.DebugFormat("[MurmurVoice] region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
                                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatar.Name, request, path, param);

                if (((land.Flags & (uint)ParcelFlags.AllowVoiceChat) > 0) && scene.RegionInfo.EstateSettings.AllowVoice)
                {
                    ServerManager manager = GetServerManager(scene);
                    Agent agent = manager.Agent.GetOrCreate(agentID, scene);

                    if (agent == null)
                    {
                        m_log.ErrorFormat("[MurmurVoice] Agent not connected {0}", agentID);

                        return "<llsd><undef /></llsd>";
                    }

                    agent.channel = manager.Channel.GetOrCreate(ChannelName(scene, land));

                    // Wait for session connect
                    int retry = 0;
                    while (agent.session < 0)
                    {
                        if (++retry > 50)
                        {
                            m_log.ErrorFormat("[MurmurVoice] Connecting failed {0} (uid {1}) identified by {2}", agent.uuid.ToString(), agent.userid, agent.pass);

                            return "<llsd><undef /></llsd>";
                        }

                        Thread.Sleep(200);
                    }

                    // Host/port pair for voice server
                    channel_uri = String.Format("{0}:{1}", m_murmurd_host, m_murmurd_port);

                    Murmur.User state = manager.Server.getState(agent.session);
                    GetServerCallback(scene).AddUserToChan(state, agent.channel);

                    m_log.DebugFormat("[MurmurVoice] {0}", channel_uri);
                }
                else
                {
                    m_log.DebugFormat("[MurmurVoice] Voice not enabled.");
                }

                Hashtable creds = new Hashtable();
                creds["channel_uri"] = channel_uri;

                LLSDParcelVoiceInfoResponse parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
                string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
                m_log.DebugFormat("[MurmurVoice] Parcel: {0}", r);

                return r;
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("[MurmurVoice] Exception: " + e.ToString());
                return "<llsd><undef /></llsd>";
            }
        }