minor patching to outdated vivox suport. This can't be updated without proper API spec, that vivox is refusing to provide to me
							parent
							
								
									e4f7a1c07a
								
							
						
					
					
						commit
						c172adbaec
					
				|  | @ -77,7 +77,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         public const double CHAN_ROLL_OFF_DEFAULT            = 2.0;  // rate of attenuation |         public const double CHAN_ROLL_OFF_DEFAULT            = 2.0;  // rate of attenuation | ||||||
|         public const double CHAN_ROLL_OFF_MIN                = 1.0; |         public const double CHAN_ROLL_OFF_MIN                = 1.0; | ||||||
|         public const double CHAN_ROLL_OFF_MAX                = 4.0; |         public const double CHAN_ROLL_OFF_MAX                = 4.0; | ||||||
|         public const int    CHAN_MAX_RANGE_DEFAULT           = 80;   // distance at which channel is silent |         public const int    CHAN_MAX_RANGE_DEFAULT           = 60;   // distance at which channel is silent | ||||||
|         public const int    CHAN_MAX_RANGE_MIN               = 0; |         public const int    CHAN_MAX_RANGE_MIN               = 0; | ||||||
|         public const int    CHAN_MAX_RANGE_MAX               = 160; |         public const int    CHAN_MAX_RANGE_MAX               = 160; | ||||||
|         public const int    CHAN_CLAMPING_DISTANCE_DEFAULT   = 10;   // distance before attenuation applies |         public const int    CHAN_CLAMPING_DISTANCE_DEFAULT   = 10;   // distance before attenuation applies | ||||||
|  | @ -197,7 +197,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                         break; |                         break; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 m_vivoxVoiceAccountApi = String.Format("http://{0}/api2", m_vivoxServer); |  | ||||||
| 
 | 
 | ||||||
|                 // Admin interface required values |                 // Admin interface required values | ||||||
|                 if (String.IsNullOrEmpty(m_vivoxServer) || |                 if (String.IsNullOrEmpty(m_vivoxServer) || | ||||||
|  | @ -210,6 +209,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 m_vivoxVoiceAccountApi = String.Format("https://{0}:443/api2", m_vivoxServer); // fs seems to not like https here | ||||||
|  |                 if (!Uri.TryCreate(m_vivoxVoiceAccountApi, UriKind.Absolute, out Uri accoutURI)) | ||||||
|  |                 { | ||||||
|  |                     m_log.Error("[VivoxVoice] invalid vivox server"); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if (!Uri.TryCreate("http://" + m_vivoxSipUri, UriKind.Absolute, out Uri spiURI)) | ||||||
|  |                 { | ||||||
|  |                     m_log.Error("[VivoxVoice] invalid vivox sip server"); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|                 m_log.InfoFormat("[VivoxVoice] using vivox server {0}", m_vivoxServer); |                 m_log.InfoFormat("[VivoxVoice] using vivox server {0}", m_vivoxServer); | ||||||
| 
 | 
 | ||||||
|                 // Get admin rights and cleanup any residual channel definition |                 // Get admin rights and cleanup any residual channel definition | ||||||
|  | @ -234,7 +246,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             { |             { | ||||||
|                 lock (vlock) |                 lock (vlock) | ||||||
|                 { |                 { | ||||||
|                     string channelId; |                     string channelId = String.Empty; | ||||||
| 
 | 
 | ||||||
|                     string sceneUUID  = scene.RegionInfo.RegionID.ToString(); |                     string sceneUUID  = scene.RegionInfo.RegionID.ToString(); | ||||||
|                     string sceneName  = scene.RegionInfo.RegionName; |                     string sceneName  = scene.RegionInfo.RegionName; | ||||||
|  | @ -245,6 +257,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                     // This assumes that there is just one directory per |                     // This assumes that there is just one directory per | ||||||
|                     // region. |                     // region. | ||||||
| 
 | 
 | ||||||
|  |                     /* this is not working, can not fix without api spec that vivox is refusing  | ||||||
|  | 
 | ||||||
|                     if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) |                     if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) | ||||||
|                     { |                     { | ||||||
|                         m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", |                         m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", | ||||||
|  | @ -276,6 +290,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                             channelId = String.Empty; |                             channelId = String.Empty; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     */ | ||||||
| 
 | 
 | ||||||
|                     // Create a dictionary entry unconditionally. This eliminates the |                     // Create a dictionary entry unconditionally. This eliminates the | ||||||
|                     // need to check for a parent in the core code. The end result is |                     // need to check for a parent in the core code. The end result is | ||||||
|  | @ -464,18 +479,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                 string        avatarName = null; |                 string        avatarName = null; | ||||||
| 
 | 
 | ||||||
|                 if (scene == null) |                 if (scene == null) | ||||||
|                     throw new Exception("[VivoxVoice][PROVISIONVOICE]: Invalid scene"); |                     return "<llsd><undef /></llsd>"; | ||||||
| 
 | 
 | ||||||
|                 avatar = scene.GetScenePresence(agentID); |                 avatar = scene.GetScenePresence(agentID); | ||||||
|                 while (avatar == null) |                 int nretries = 10; | ||||||
|  |                 while (avatar == null && nretries-- > 0) | ||||||
|                 { |                 { | ||||||
|                     Thread.Sleep(100); |                     Thread.Sleep(100); | ||||||
|                     avatar = scene.GetScenePresence(agentID); |                     avatar = scene.GetScenePresence(agentID); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 if(avatar == null) | ||||||
|  |                     return "<llsd><undef /></llsd>"; | ||||||
|  | 
 | ||||||
|                 avatarName = avatar.Name; |                 avatarName = avatar.Name; | ||||||
| 
 | 
 | ||||||
|                 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID); |                 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene.Name, agentID); | ||||||
| //                    m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | //                    m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | ||||||
| //                                      request, path, param); | //                                      request, path, param); | ||||||
| 
 | 
 | ||||||
|  | @ -579,14 +598,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                 // Unconditionally change the password on each request |                 // Unconditionally change the password on each request | ||||||
|                 VivoxPassword(agentname, password); |                 VivoxPassword(agentname, password); | ||||||
| 
 | 
 | ||||||
|                 LLSDVoiceAccountResponse voiceAccountResponse = |                 // fast foward encode | ||||||
|                     new LLSDVoiceAccountResponse(agentname, password, m_vivoxSipUri, m_vivoxVoiceAccountApi); |                 StringBuilder lsl = LLSDxmlEncode.Start(512); | ||||||
|  |                 LLSDxmlEncode.AddMap(lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("username", agentname, lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("password", password, lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("voice_sip_uri_hostname", m_vivoxSipUri, lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("voice_account_server_name", m_vivoxVoiceAccountApi, lsl); | ||||||
|  |                 LLSDxmlEncode.AddEndMap(lsl); | ||||||
| 
 | 
 | ||||||
|                 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |                 return LLSDxmlEncode.End(lsl); | ||||||
| 
 |  | ||||||
| //                    m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); |  | ||||||
| 
 |  | ||||||
|                 return r; |  | ||||||
|             } |             } | ||||||
|             catch (Exception e) |             catch (Exception e) | ||||||
|             { |             { | ||||||
|  | @ -619,7 +640,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             // - send channel_uri: as "sip:regionID@m_sipDomain" |             // - send channel_uri: as "sip:regionID@m_sipDomain" | ||||||
|             try |             try | ||||||
|             { |             { | ||||||
|                 LLSDParcelVoiceInfoResponse parcelVoiceInfo; |  | ||||||
|                 string channel_uri; |                 string channel_uri; | ||||||
| 
 | 
 | ||||||
|                 if (null == scene.LandChannel) |                 if (null == scene.LandChannel) | ||||||
|  | @ -636,20 +656,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                     return "<llsd><undef /></llsd>"; |                     return "<llsd><undef /></llsd>"; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| //                    m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", |                 // 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); |                 //     scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); | ||||||
|                 // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}", |                 // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}", | ||||||
|                 //                   avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); |                 //                   avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); | ||||||
| 
 | 
 | ||||||
|                 // TODO: EstateSettings don't seem to get propagated... |  | ||||||
|                 if (!scene.RegionInfo.EstateSettings.AllowVoice) |                 if (!scene.RegionInfo.EstateSettings.AllowVoice) | ||||||
|                 { |                 { | ||||||
|                     //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings", |                     //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings", | ||||||
|                     //                  scene.RegionInfo.RegionName); |                     //                  scene.RegionInfo.RegionName); | ||||||
|                     channel_uri = String.Empty; |                     channel_uri = String.Empty; | ||||||
|                 } |                 } | ||||||
| 
 |                 else if (!scene.RegionInfo.EstateSettings.TaxFree && (land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) | ||||||
|                 if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) |  | ||||||
|                 { |                 { | ||||||
|                     //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", |                     //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", | ||||||
|                     //                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); |                     //                  scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); | ||||||
|  | @ -660,16 +678,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|                     channel_uri = RegionGetOrCreateChannel(scene, land); |                     channel_uri = RegionGetOrCreateChannel(scene, land); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // fill in our response to the client |                 // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", | ||||||
|                 Hashtable creds = new Hashtable(); |                 //      scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); | ||||||
|                 creds["channel_uri"] = channel_uri; |                 // fast foward encode | ||||||
|  |                 StringBuilder lsl = LLSDxmlEncode.Start(512); | ||||||
|  |                 LLSDxmlEncode.AddMap(lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("parcel_local_id", land.LocalID, lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("region_name", scene.Name, lsl); | ||||||
|  |                 LLSDxmlEncode.AddMap("voice_credentials",lsl); | ||||||
|  |                 LLSDxmlEncode.AddElem("channel_uri", channel_uri, lsl); | ||||||
|  |                 //LLSDxmlEncode.AddElem("channel_credentials", channel_credentials, lsl); | ||||||
|  |                 LLSDxmlEncode.AddEndMap(lsl); | ||||||
|  |                 LLSDxmlEncode.AddEndMap(lsl); | ||||||
| 
 | 
 | ||||||
|                 parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); |                 return LLSDxmlEncode.End(lsl); | ||||||
|                 string r = LLSDHelpers.SerialiseLLSDReply(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) |             catch (Exception e) | ||||||
|             { |             { | ||||||
|  | @ -717,7 +739,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
| 
 | 
 | ||||||
|             // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same |             // Create parcel voice channel. If no parcel exists, then the voice channel ID is the same | ||||||
|             // as the directory ID. Otherwise, it reflects the parcel's ID. |             // as the directory ID. Otherwise, it reflects the parcel's ID. | ||||||
|             if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) |             if ((land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0) | ||||||
|             { |             { | ||||||
|                 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); |                 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); | ||||||
|                 landUUID = land.GlobalID.ToString(); |                 landUUID = land.GlobalID.ToString(); | ||||||
|  | @ -749,7 +771,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             return channelUri; |             return channelUri; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxLoginPath = "http://{0}/api2/viv_signin.php?userid={1}&pwd={2}"; |         private static readonly string m_vivoxLoginPath = "https://{0}/api2/viv_signin.php?userid={1}&pwd={2}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Perform administrative login for Vivox. |         /// Perform administrative login for Vivox. | ||||||
|  | @ -761,7 +783,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             return VivoxCall(requrl, false); |             return VivoxCall(requrl, false); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxLogoutPath = "http://{0}/api2/viv_signout.php?auth_token={1}"; |         private static readonly string m_vivoxLogoutPath = "https://{0}/api2/viv_signout.php?auth_token={1}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Perform administrative logout for Vivox. |         /// Perform administrative logout for Vivox. | ||||||
|  | @ -773,7 +795,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxGetAccountPath = "http://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}"; |         private static readonly string m_vivoxGetAccountPath = "https://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Retrieve account information for the specified user. |         /// Retrieve account information for the specified user. | ||||||
|  | @ -786,7 +808,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxNewAccountPath = "http://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}"; |         private static readonly string m_vivoxNewAccountPath = "https://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Creates a new account. |         /// Creates a new account. | ||||||
|  | @ -801,7 +823,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxPasswordPath = "http://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}"; |         private static readonly string m_vivoxPasswordPath = "https://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Change the user's password. |         /// Change the user's password. | ||||||
|  | @ -813,7 +835,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxChannelPath = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}"; |         private static readonly string m_vivoxChannelPath = "https://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Create a channel. |         /// Create a channel. | ||||||
|  | @ -864,6 +886,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         private bool VivoxTryCreateDirectory(string dirId, string description, out string channelId) |         private bool VivoxTryCreateDirectory(string dirId, string description, out string channelId) | ||||||
|         { |         { | ||||||
|  |             /* this is not working, and can not fix without api spec, that vivox is refusing me | ||||||
|  | 
 | ||||||
|             string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", dirId, m_authToken); |             string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", dirId, m_authToken); | ||||||
| 
 | 
 | ||||||
|             // if (parent != null && parent != String.Empty) |             // if (parent != null && parent != String.Empty) | ||||||
|  | @ -880,12 +904,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             XmlElement resp = VivoxCall(requrl, true); |             XmlElement resp = VivoxCall(requrl, true); | ||||||
|             if (IsOK(resp) && XmlFind(resp, "response.level0.body.chan_id", out channelId)) |             if (IsOK(resp) && XmlFind(resp, "response.level0.body.chan_id", out channelId)) | ||||||
|                 return true; |                 return true; | ||||||
| 
 |             */ | ||||||
|             channelId = String.Empty; |             channelId = String.Empty; | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxChannelSearchPath = "http://{0}/api2/viv_chan_search.php?cond_channame={1}&auth_token={2}"; |         private static readonly string m_vivoxChannelSearchPath = "https://{0}/api2/viv_chan_search.php?cond_channame={1}&auth_token={2}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Retrieve a channel. |         /// Retrieve a channel. | ||||||
|  | @ -1040,7 +1064,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|         //         return VivoxCall(requrl, true); |         //         return VivoxCall(requrl, true); | ||||||
|         // } |         // } | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxChannelDel = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; |         private static readonly string m_vivoxChannelDel = "https://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Delete a channel. |         /// Delete a channel. | ||||||
|  | @ -1064,7 +1088,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice | ||||||
|             return VivoxCall(requrl, true); |             return VivoxCall(requrl, true); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private static readonly string m_vivoxChannelSearch = "http://{0}/api2/viv_chan_search.php?&cond_chanparent={1}&auth_token={2}"; |         private static readonly string m_vivoxChannelSearch = "https://{0}/api2/viv_chan_search.php?&cond_chanparent={1}&auth_token={2}"; | ||||||
| 
 | 
 | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Return information on channels in the given directory |         /// Return information on channels in the given directory | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 UbitUmarov
						UbitUmarov