Scrublord1336 6 жил өмнө
parent
commit
c8fc496cf7

+ 5 - 0
src/XUnity.AutoTranslator.Plugin.Core/Web/GoogleTranslateEndpoint.cs

@@ -31,13 +31,17 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
       public GoogleTranslateEndpoint()
       {
          _cookieContainer = new CookieContainer();
+
+         // Configure service points / service point manager
          ServicePointManager.ServerCertificateValidationCallback += Security.AlwaysAllowByHosts( "translate.google.com", "translate.googleapis.com" );
+         SetupServicePoints( "https://translate.googleapis.com", "https://translate.google.com" );
       }
 
       public override void ApplyHeaders( WebHeaderCollection headers )
       {
          headers[ HttpRequestHeader.UserAgent ] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36";
          headers[ HttpRequestHeader.Accept ] = "*/*";
+         headers[ HttpRequestHeader.Referer ] = "https://translate.google.com/";
       }
 
       public override IEnumerator OnBeforeTranslate( int translationCount )
@@ -67,6 +71,7 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
          try
          {
             ApplyHeaders( client.Headers );
+            client.Headers.Remove( HttpRequestHeader.Referer );
             downloadResult = client.GetDownloadResult( new Uri( HttpsTranslateUserSite ) );
          }
          catch( Exception e )

+ 60 - 43
src/XUnity.AutoTranslator.Plugin.Core/Web/KnownHttpEndpoint.cs

@@ -1,34 +1,43 @@
 using System;
 using System.Collections;
 using System.Net;
+using System.Threading;
 using XUnity.AutoTranslator.Plugin.Core.Configuration;
 
 namespace XUnity.AutoTranslator.Plugin.Core.Web
 {
    public abstract class KnownHttpEndpoint : IKnownEndpoint
    {
-      private static readonly TimeSpan MaxUnusedLifespan = TimeSpan.FromSeconds( 20 );
+      private static readonly TimeSpan MaxUnusedLifespan = TimeSpan.FromSeconds( 25 );
 
-      private static int _runningTranslations = 0;
-      private static int _maxConcurrency = 1;
-      private static bool _isSettingUp = false;
+      private ServicePoint[] _servicePoints;
+      private bool _isBusy = false;
       private UnityWebClient _client;
-      private DateTime _clientLastUse = DateTime.UtcNow;
+      private DateTime? _clientLastUse = null;
 
       public KnownHttpEndpoint()
       {
       }
 
-      public bool IsBusy => _isSettingUp || _runningTranslations >= _maxConcurrency;
+      public bool IsBusy => _isBusy;
 
-      public IEnumerator Translate( string untranslatedText, string from, string to, Action<string> success, Action failure )
+      protected void SetupServicePoints( params string[] endpoints )
       {
-         _clientLastUse = DateTime.UtcNow;
+         _servicePoints = new ServicePoint[ endpoints.Length ];
+         
+         for( int i = 0 ; i < endpoints.Length ; i++ )
+         {
+            var endpoint = endpoints[ i ];
+            var servicePoint = ServicePointManager.FindServicePoint( new Uri( endpoint ) );
+            _servicePoints[ i ] = servicePoint;
+         }
+      }
 
+      public IEnumerator Translate( string untranslatedText, string from, string to, Action<string> success, Action failure )
+      {
+         _isBusy = true;
          try
          {
-            _isSettingUp = true;
-
             var setup = OnBeforeTranslate( Settings.TranslationCount );
             if( setup != null )
             {
@@ -37,33 +46,23 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
                   yield return setup.Current;
                }
             }
-         }
-         finally
-         {
-            _isSettingUp = false;
-         }
-
-         Logger.Current.Debug( "Starting translation for: " + untranslatedText );
-         DownloadResult result = null;
-         try
-         {
-            var client = GetClient();
-            var url = GetServiceUrl( untranslatedText, from, to );
-            ApplyHeaders( client.Headers );
-            result = client.GetDownloadResult( new Uri( url ) );
-         }
-         catch( Exception e )
-         {
-            Logger.Current.Error( e, "Error occurred while setting up translation request." );
-         }
-
-         if( result != null )
-         {
+            Logger.Current.Debug( "Starting translation for: " + untranslatedText );
+            DownloadResult result = null;
             try
             {
-               _runningTranslations++;
+               var client = GetClient();
+               var url = GetServiceUrl( untranslatedText, from, to );
+               ApplyHeaders( client.Headers );
+               result = client.GetDownloadResult( new Uri( url ) );
+            }
+            catch( Exception e )
+            {
+               Logger.Current.Error( e, "Error occurred while setting up translation request." );
+            }
+
+            if( result != null )
+            {
                yield return result;
-               _runningTranslations--;
 
                try
                {
@@ -94,25 +93,43 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
                   failure();
                }
             }
-            finally
+            else
             {
-               _clientLastUse = DateTime.UtcNow;
+               failure();
             }
          }
-         else
+         finally
          {
-            failure();
+            _clientLastUse = DateTime.UtcNow;
+            _isBusy = false;
          }
       }
 
       public virtual void OnUpdate()
       {
-         var client = _client;
-         if( client != null && DateTime.UtcNow - _clientLastUse > MaxUnusedLifespan && !client.IsBusy )
+         if( !_isBusy && _clientLastUse.HasValue && DateTime.UtcNow - _clientLastUse > MaxUnusedLifespan && !_client.IsBusy
+            && _servicePoints != null && _servicePoints.Length > 0 )
          {
-            _client = null;
-            client.Dispose();
-            Logger.Current.Debug( "Disposing WebClient because it was not used for 20 seconds." );
+            Logger.Current.Debug( "Closing service points because they were not used for 25 seconds." );
+
+            _isBusy = true;
+            _clientLastUse = null;
+
+            ThreadPool.QueueUserWorkItem( delegate ( object state )
+            {
+               // never do a job like this on the game loop thread
+               try
+               {
+                  foreach( var servicePoint in _servicePoints )
+                  {
+                     servicePoint.CloseConnectionGroup( MyWebClient.ConnectionGroupName );
+                  }
+               }
+               finally
+               {
+                  _isBusy = false;
+               }
+            } );
          }
       }
 

+ 58 - 63
src/XUnity.AutoTranslator.Plugin.Core/Web/KnownWwwEndpoint.cs

@@ -13,22 +13,19 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
    {
       protected static readonly ConstructorInfo WwwConstructor = Constants.Types.WWW.GetConstructor( new[] { typeof( string ), typeof( byte[] ), typeof( Dictionary<string, string> ) } );
 
-      private static int _runningTranslations = 0;
-      private static int _maxConcurrency = 1;
-      private static bool _isSettingUp = false;
+      private bool _isBusy = false;
 
       public KnownWwwEndpoint()
       {
       }
 
-      public bool IsBusy => _isSettingUp || _runningTranslations >= _maxConcurrency;
+      public bool IsBusy => _isBusy;
 
       public IEnumerator Translate( string untranslatedText, string from, string to, Action<string> success, Action failure )
       {
+         _isBusy = true;
          try
          {
-            _isSettingUp = true;
-
             var setup = OnBeforeTranslate( Settings.TranslationCount );
             if( setup != null )
             {
@@ -37,84 +34,82 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
                   yield return setup.Current;
                }
             }
-         }
-         finally
-         {
-            _isSettingUp = false;
-         }
-
-         Logger.Current.Debug( "Starting translation for: " + untranslatedText );
-         object www = null;
-         try
-         {
-            var headers = new Dictionary<string, string>();
-            ApplyHeaders( headers );
-            var url = GetServiceUrl( untranslatedText, from, to );
-            www = WwwConstructor.Invoke( new object[] { url, null, headers } );
-         }
-         catch( Exception e )
-         {
-            Logger.Current.Error( e, "Error occurred while setting up translation request." );
-         }
-
-         if( www != null )
-         {
-            _runningTranslations++;
-            yield return www;
-            _runningTranslations--;
 
+            Logger.Current.Debug( "Starting translation for: " + untranslatedText );
+            object www = null;
             try
             {
-               string error = null;
-               try
-               {
-                  error = (string)AccessTools.Property( Constants.Types.WWW, "error" ).GetValue( www, null );
-               }
-               catch( Exception e )
-               {
-                  error = e.ToString();
-               }
+               var headers = new Dictionary<string, string>();
+               ApplyHeaders( headers );
+               var url = GetServiceUrl( untranslatedText, from, to );
+               www = WwwConstructor.Invoke( new object[] { url, null, headers } );
+            }
+            catch( Exception e )
+            {
+               Logger.Current.Error( e, "Error occurred while setting up translation request." );
+            }
 
-               if( error != null )
-               {
-                  Logger.Current.Error( "Error occurred while retrieving translation." + Environment.NewLine + error );
-                  failure();
-               }
-               else
+            if( www != null )
+            {
+               yield return www;
+
+               try
                {
-                  var text = (string)AccessTools.Property( Constants.Types.WWW, "text" ).GetValue( www, null ); ;
+                  string error = null;
+                  try
+                  {
+                     error = (string)AccessTools.Property( Constants.Types.WWW, "error" ).GetValue( www, null );
+                  }
+                  catch( Exception e )
+                  {
+                     error = e.ToString();
+                  }
 
-                  if( text != null )
+                  if( error != null )
                   {
-                     if( TryExtractTranslated( text, out var translatedText ) )
-                     {
-                        Logger.Current.Debug( $"Translation for '{untranslatedText}' succeded. Result: {translatedText}" );
+                     Logger.Current.Error( "Error occurred while retrieving translation." + Environment.NewLine + error );
+                     failure();
+                  }
+                  else
+                  {
+                     var text = (string)AccessTools.Property( Constants.Types.WWW, "text" ).GetValue( www, null ); ;
 
-                        translatedText = translatedText ?? string.Empty;
-                        success( translatedText );
+                     if( text != null )
+                     {
+                        if( TryExtractTranslated( text, out var translatedText ) )
+                        {
+                           Logger.Current.Debug( $"Translation for '{untranslatedText}' succeded. Result: {translatedText}" );
+
+                           translatedText = translatedText ?? string.Empty;
+                           success( translatedText );
+                        }
+                        else
+                        {
+                           Logger.Current.Error( "Error occurred while extracting translation." );
+                           failure();
+                        }
                      }
                      else
                      {
-                        Logger.Current.Error( "Error occurred while extracting translation." );
+                        Logger.Current.Error( "Error occurred while extracting text from response." );
                         failure();
                      }
                   }
-                  else
-                  {
-                     Logger.Current.Error( "Error occurred while extracting text from response." );
-                     failure();
-                  }
+               }
+               catch( Exception e )
+               {
+                  Logger.Current.Error( e, "Error occurred while retrieving translation." );
+                  failure();
                }
             }
-            catch( Exception e )
+            else
             {
-               Logger.Current.Error( e, "Error occurred while retrieving translation." );
                failure();
             }
          }
-         else
+         finally
          {
-            failure();
+            _isBusy = false;
          }
       }
 

+ 6 - 1
src/XUnity.AutoTranslator.Plugin.Core/Web/MyWebClient.cs

@@ -84,8 +84,10 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
       }
    }
 
-   public class MyWebClient : Component
+   public class MyWebClient
    {
+      public static readonly string ConnectionGroupName = Guid.NewGuid().ToString();
+
       private bool async;
       private Uri baseAddress;
       private string baseString;
@@ -268,6 +270,8 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
             WebResponse webResponse = this.GetWebResponse( request );
             Stream responseStream = webResponse.GetResponseStream();
             buffer = this.ReadAll( responseStream, (int)webResponse.ContentLength, userToken );
+            responseStream.Close();
+            webResponse.Close();
          }
          catch( ThreadInterruptedException )
          {
@@ -880,6 +884,7 @@ namespace XUnity.AutoTranslator.Plugin.Core.Web
       private WebRequest SetupRequest( Uri uri )
       {
          WebRequest webRequest = this.GetWebRequest( uri );
+         webRequest.ConnectionGroupName = ConnectionGroupName;
          if( this.Proxy != null )
          {
             webRequest.Proxy = this.Proxy;