123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using System;
- using System.Collections;
- using System.Net;
- using System.Threading;
- using UnityEngine;
- using XUnity.AutoTranslator.Plugin.Core.Configuration;
- namespace XUnity.AutoTranslator.Plugin.Core.Web
- {
- public abstract class KnownHttpEndpoint : IKnownEndpoint
- {
- private static readonly TimeSpan MaxUnusedLifespan = TimeSpan.FromSeconds( 50 );
- private ServicePoint[] _servicePoints;
- private bool _isBusy = false;
- private UnityWebClient _client;
- private DateTime? _clientLastUse = null;
- public KnownHttpEndpoint()
- {
- }
- public bool IsBusy => _isBusy;
- public virtual bool SupportsLineSplitting
- {
- get
- {
- return false;
- }
- }
- protected void SetupServicePoints( params string[] endpoints )
- {
- _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
- {
- var setup = OnBeforeTranslate( Settings.TranslationCount );
- if( setup != null )
- {
- while( setup.MoveNext() )
- {
- yield return setup.Current;
- }
- }
- Logger.Current.Debug( "Starting translation for: " + untranslatedText );
- DownloadResult downloadResult = null;
- try
- {
- var client = GetClient();
- var url = GetServiceUrl( untranslatedText, from, to );
- var request = GetRequestObject( untranslatedText, from, to );
- ApplyHeaders( client.Headers );
- if( request != null )
- {
- downloadResult = client.GetDownloadResult( new Uri( url ), request );
- }
- else
- {
- downloadResult = client.GetDownloadResult( new Uri( url ) );
- }
- }
- catch( Exception e )
- {
- Logger.Current.Error( e, "Error occurred while setting up translation request." );
- }
- if( downloadResult != null )
- {
- if( Features.SupportsCustomYieldInstruction )
- {
- yield return downloadResult;
- }
- else
- {
- while( !downloadResult.IsCompleted )
- {
- yield return new WaitForSeconds( 0.2f );
- }
- }
- try
- {
- if( downloadResult.Succeeded && downloadResult.Result != null )
- {
- if( TryExtractTranslated( downloadResult.Result, 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 retrieving translation." + Environment.NewLine + downloadResult.Error );
- failure();
- }
- }
- catch( Exception e )
- {
- Logger.Current.Error( e, "Error occurred while retrieving translation." );
- failure();
- }
- }
- else
- {
- failure();
- }
- }
- finally
- {
- _clientLastUse = DateTime.UtcNow;
- _isBusy = false;
- }
- }
- public virtual void OnUpdate()
- {
- if( !_isBusy && _clientLastUse.HasValue && DateTime.UtcNow - _clientLastUse > MaxUnusedLifespan && !_client.IsBusy
- && _servicePoints != null && _servicePoints.Length > 0 )
- {
- Logger.Current.Debug( $"Closing service points because they were not used for {(int)MaxUnusedLifespan.TotalSeconds} 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;
- }
- } );
- }
- }
- public virtual bool ShouldGetSecondChanceAfterFailure()
- {
- return false;
- }
- public abstract string GetServiceUrl( string untranslatedText, string from, string to );
- public abstract void ApplyHeaders( WebHeaderCollection headers );
- public abstract bool TryExtractTranslated( string result, out string translated );
- public virtual string GetRequestObject( string untranslatedText, string from, string to )
- {
- return null;
- }
- public virtual void WriteCookies( HttpWebResponse response )
- {
- }
- public virtual CookieContainer ReadCookies()
- {
- return null;
- }
- public virtual IEnumerator OnBeforeTranslate( int translationCount )
- {
- return null;
- }
- public UnityWebClient GetClient()
- {
- if( _client == null )
- {
- _client = new UnityWebClient( this );
- _clientLastUse = DateTime.UtcNow;
- }
- return _client;
- }
- }
- }
|