KnownHttpEndpoint.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using System;
  2. using System.Collections;
  3. using System.Net;
  4. using XUnity.AutoTranslator.Plugin.Core.Configuration;
  5. namespace XUnity.AutoTranslator.Plugin.Core.Web
  6. {
  7. public abstract class KnownHttpEndpoint : IKnownEndpoint
  8. {
  9. private static readonly TimeSpan MaxUnusedLifespan = TimeSpan.FromSeconds( 20 );
  10. private static int _runningTranslations = 0;
  11. private static int _maxConcurrency = 1;
  12. private static bool _isSettingUp = false;
  13. private UnityWebClient _client;
  14. private DateTime _clientLastUse = DateTime.UtcNow;
  15. public KnownHttpEndpoint()
  16. {
  17. }
  18. public bool IsBusy => _isSettingUp || _runningTranslations >= _maxConcurrency;
  19. public IEnumerator Translate( string untranslatedText, string from, string to, Action<string> success, Action failure )
  20. {
  21. _clientLastUse = DateTime.UtcNow;
  22. try
  23. {
  24. _isSettingUp = true;
  25. var setup = OnBeforeTranslate( Settings.TranslationCount );
  26. if( setup != null )
  27. {
  28. while( setup.MoveNext() )
  29. {
  30. yield return setup.Current;
  31. }
  32. }
  33. }
  34. finally
  35. {
  36. _isSettingUp = false;
  37. }
  38. var client = GetClient();
  39. var url = GetServiceUrl( untranslatedText, from, to );
  40. ApplyHeaders( client.Headers );
  41. var result = client.GetDownloadResult( new Uri( url ) );
  42. try
  43. {
  44. _runningTranslations++;
  45. yield return result;
  46. _runningTranslations--;
  47. if( result.Succeeded )
  48. {
  49. if( TryExtractTranslated( result.Result, out var translatedText ) )
  50. {
  51. translatedText = translatedText ?? string.Empty;
  52. success( translatedText );
  53. }
  54. else
  55. {
  56. Console.WriteLine( "[XUnity.AutoTranslator][ERROR]: Error occurred while extracting translation." );
  57. failure();
  58. }
  59. }
  60. else
  61. {
  62. Console.WriteLine( "[XUnity.AutoTranslator][ERROR]: Error occurred while retrieving translation." + Environment.NewLine + result.Error );
  63. failure();
  64. }
  65. }
  66. finally
  67. {
  68. _clientLastUse = DateTime.UtcNow;
  69. }
  70. }
  71. public virtual void OnUpdate()
  72. {
  73. var client = _client;
  74. if( client != null && DateTime.UtcNow - _clientLastUse > MaxUnusedLifespan )
  75. {
  76. _client = null;
  77. client.Dispose();
  78. }
  79. }
  80. public virtual bool ShouldGetSecondChanceAfterFailure()
  81. {
  82. return false;
  83. }
  84. public abstract string GetServiceUrl( string untranslatedText, string from, string to );
  85. public abstract void ApplyHeaders( WebHeaderCollection headers );
  86. public abstract bool TryExtractTranslated( string result, out string translated );
  87. public virtual void WriteCookies( HttpWebResponse response )
  88. {
  89. }
  90. public virtual CookieContainer ReadCookies()
  91. {
  92. return null;
  93. }
  94. public virtual IEnumerator OnBeforeTranslate( int translationCount )
  95. {
  96. return null;
  97. }
  98. public UnityWebClient GetClient()
  99. {
  100. if( _client == null )
  101. {
  102. _client = new UnityWebClient( this );
  103. _clientLastUse = DateTime.UtcNow;
  104. }
  105. return _client;
  106. }
  107. }
  108. }