From efa4a591dd1e98c48a2d8adacefecedbb5ad98be Mon Sep 17 00:00:00 2001 From: randoman <738b86bb93c44695854182cc459afcbb@lonestar.no> Date: Mon, 1 Feb 2021 18:38:33 +0100 Subject: [PATCH] Version 4.14.0 * FEATURE - New version of GoogleTranslate endpoint that supports new API. May replace replace old GoogleTranslate endpoint in the future * MISC - Made more log statements affected by silent mode * MISC - Changed behaviour of the copy to clipboard feature. Now it will always copy to clipboard when text is being translated on a text component * MISC - Support for older versions of UTAGE * MISC - Fixed some log statements to no longer indicate error in case an error did not occur during hooking * MISC - Updated user agents for API requests * MISC - Improved SpriteRenderer support * BUG FIX - Fixed a bug that could cause crash in older versions of the Unity Engine * BUG FIX - Fixed a bug that could occur during dynamic code generation in certain situations --- CHANGELOG.md | 1 + .../GoogleTranslateEndpointV2.cs | 6 +- .../AutoTranslationPlugin.cs | 118 +++++++++++++++--- .../CallOrigin.cs | 1 + .../Extensions/TextureComponentExtensions.cs | 28 +++-- .../Hooks/ImageHooks.cs | 37 ++++-- .../ImageTranslationInfo.cs | 18 ++- .../TextureTranslationInfo.cs | 2 + .../Utilities/ObjectReferenceMapperEx.cs | 9 +- 9 files changed, 182 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6969d13..7b90e606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * MISC - Support for older versions of UTAGE * MISC - Fixed some log statements to no longer indicate error in case an error did not occur during hooking * MISC - Updated user agents for API requests + * MISC - Improved SpriteRenderer support * BUG FIX - Fixed a bug that could cause crash in older versions of the Unity Engine * BUG FIX - Fixed a bug that could occur during dynamic code generation in certain situations diff --git a/src/Translators/GoogleTranslate/GoogleTranslateEndpointV2.cs b/src/Translators/GoogleTranslate/GoogleTranslateEndpointV2.cs index c4cf5e10..3137dc2e 100644 --- a/src/Translators/GoogleTranslate/GoogleTranslateEndpointV2.cs +++ b/src/Translators/GoogleTranslate/GoogleTranslateEndpointV2.cs @@ -86,7 +86,7 @@ private string FixLanguage( string lang ) public override void Initialize( IInitializationContext context ) { - var backendOverride = context.GetOrCreateSetting( "GoogleV2", "ServiceUrl", DefaultUserBackend ); + var backendOverride = context.GetOrCreateSetting( "GoogleV2", "ServiceUrl" ); if( !backendOverride.IsNullOrWhiteSpace() ) { _selectedUserBackend = backendOverride; @@ -97,7 +97,9 @@ public override void Initialize( IInitializationContext context ) } else { - throw new Exception( "ServiceUrl is empty." ); + _selectedUserBackend = DefaultUserBackend; + + _httpsServicePointTranslateTemplateUrl = _selectedUserBackend + HttpsServicePointTranslateTemplateUrl; } _translateRpcId = context.GetOrCreateSetting( "GoogleV2", "RPCID", "MkEWBc" ); diff --git a/src/XUnity.AutoTranslator.Plugin.Core/AutoTranslationPlugin.cs b/src/XUnity.AutoTranslator.Plugin.Core/AutoTranslationPlugin.cs index 9ec6933f..c25c7a9e 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/AutoTranslationPlugin.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/AutoTranslationPlugin.cs @@ -77,7 +77,6 @@ public class AutoTranslationPlugin : MonoBehaviour, IInternalTranslator, ITransl private bool _isInTranslatedMode = true; private bool _textHooksEnabled = true; - private bool _imageHooksEnabled = true; private float _batchOperationSecondCounter = 0; @@ -660,10 +659,24 @@ internal void Hook_TextChanged( object ui, bool onEnable ) internal void Hook_ImageChangedOnComponent( object source, ref Texture2D texture, bool isPrefixHooked, bool onEnable ) { - if( !_imageHooksEnabled ) return; + if( !CallOrigin.ImageHooksEnabled ) return; if( !source.IsKnownImageType() ) return; - HandleImage( source, ref texture, isPrefixHooked ); + Sprite _ = null; + HandleImage( source, ref _, ref texture, isPrefixHooked ); + + if( onEnable ) + { + CheckSpriteRenderer( source ); + } + } + + internal void Hook_ImageChangedOnComponent( object source, ref Sprite sprite, ref Texture2D texture, bool isPrefixHooked, bool onEnable ) + { + if( !CallOrigin.ImageHooksEnabled ) return; + if( !source.IsKnownImageType() ) return; + + HandleImage( source, ref sprite, ref texture, isPrefixHooked ); if( onEnable ) { @@ -673,10 +686,11 @@ internal void Hook_ImageChangedOnComponent( object source, ref Texture2D texture internal void Hook_ImageChanged( ref Texture2D texture, bool isPrefixHooked ) { - if( !_imageHooksEnabled ) return; + if( !CallOrigin.ImageHooksEnabled ) return; if( texture == null ) return; - HandleImage( null, ref texture, isPrefixHooked ); + Sprite _ = null; + HandleImage( null, ref _, ref texture, isPrefixHooked ); } private bool DiscoverComponent( object ui, TextTranslationInfo info ) @@ -852,7 +866,7 @@ private string TranslateOrQueueWebJob( object ui, string text, bool ignoreCompon tc ); } - private void HandleImage( object source, ref Texture2D texture, bool isPrefixHooked ) + private void HandleImage( object source, ref Sprite sprite, ref Texture2D texture, bool isPrefixHooked ) { if( Settings.EnableTextureDumping ) { @@ -870,7 +884,7 @@ private void HandleImage( object source, ref Texture2D texture, bool isPrefixHoo { try { - TranslateTexture( source, ref texture, isPrefixHooked, null ); + TranslateTexture( source, ref sprite, ref texture, isPrefixHooked, null ); } catch( Exception e ) { @@ -879,31 +893,45 @@ private void HandleImage( object source, ref Texture2D texture, bool isPrefixHoo } } + private void TranslateTexture( object ui, ref Sprite sprite, TextureReloadContext context ) + { + if( ui is Texture2D texture2d ) + { + TranslateTexture( null, ref sprite, ref texture2d, false, context ); + } + else + { + Texture2D _ = null; + TranslateTexture( ui, ref sprite, ref _, false, context ); + } + } + private void TranslateTexture( object ui, TextureReloadContext context ) { + Sprite __ = null; if( ui is Texture2D texture2d ) { - TranslateTexture( null, ref texture2d, false, context ); + TranslateTexture( null, ref __, ref texture2d, false, context ); } else { Texture2D _ = null; - TranslateTexture( ui, ref _, false, context ); + TranslateTexture( ui, ref __, ref _, false, context ); } } - private void TranslateTexture( object source, ref Texture2D texture, bool isPrefixHooked, TextureReloadContext context ) + private void TranslateTexture( object source, ref Sprite sprite, ref Texture2D texture, bool isPrefixHooked, TextureReloadContext context ) { try { - _imageHooksEnabled = false; + CallOrigin.ImageHooksEnabled = false; var previousTextureValue = texture; texture = texture ?? source.GetTexture(); if( texture == null ) return; var tti = texture.GetOrCreateTextureTranslationInfo(); - var iti = source.GetOrCreateImageTranslationInfo(); + var iti = source.GetOrCreateImageTranslationInfo( texture ); var key = tti.GetKey(); if( string.IsNullOrEmpty( key ) ) return; @@ -915,6 +943,52 @@ private void TranslateTexture( object source, ref Texture2D texture, bool isPref forceReload = context.RegisterTextureInContextAndDetermineWhetherToReload( texture ); } + if( Settings.EnableLegacyTextureLoading + && Settings.EnableSpriteRendererHooking + && iti?.IsTranslated == true + && source is SpriteRenderer sr ) + { + + var originalTexture = tti.Original.Target; + var translatedTexture = tti.Translated; + if( texture == originalTexture && tti.IsTranslated ) + { + // if the texture is the original, we update the sprite + if( tti.TranslatedSprite != null ) + { + if( isPrefixHooked ) + { + if( sprite != null ) + { + sprite = tti.TranslatedSprite; + } + } + else + { + sr.sprite = tti.TranslatedSprite; + } + } + } + else if( texture == translatedTexture ) // can only happen if && tti.IsTranslated + { + // if the texture is the translated, we do not need to do anything + } + else + { + // if the texture is neither the original or the translated, we must reset + + iti.Reset( texture ); + + if( tti.IsTranslated ) + { + if( isPrefixHooked && sprite != null && tti.TranslatedSprite != null ) + { + sprite = tti.TranslatedSprite; + } + } + } + } + if( TextureCache.TryGetTranslatedImage( key, out var newData ) ) { if( _isInTranslatedMode ) @@ -950,7 +1024,15 @@ private void TranslateTexture( object source, ref Texture2D texture, bool isPref { if( Settings.EnableLegacyTextureLoading ) { - source.SetTexture( tti.Translated ); + var newSprite = source.SetTexture( tti.Translated, sprite, isPrefixHooked ); + if( newSprite != null ) + { + tti.TranslatedSprite = newSprite; + if( isPrefixHooked && sprite != null ) + { + sprite = newSprite; + } + } } if( !isPrefixHooked ) @@ -1006,7 +1088,7 @@ private void TranslateTexture( object source, ref Texture2D texture, bool isPref var original = tti.Original.Target; if( Settings.EnableLegacyTextureLoading && original != null ) { - source.SetTexture( original ); + source.SetTexture( original, null, isPrefixHooked ); } if( !isPrefixHooked ) @@ -1061,7 +1143,7 @@ private void TranslateTexture( object source, ref Texture2D texture, bool isPref var original = tti.Original.Target; if( Settings.EnableLegacyTextureLoading && original != null ) { - source.SetTexture( original ); + source.SetTexture( original, null, isPrefixHooked ); } if( !isPrefixHooked ) @@ -1112,7 +1194,7 @@ private void TranslateTexture( object source, ref Texture2D texture, bool isPref } finally { - _imageHooksEnabled = true; + CallOrigin.ImageHooksEnabled = true; } } @@ -1120,7 +1202,7 @@ private void DumpTexture( object source, Texture2D texture ) { try { - _imageHooksEnabled = false; + CallOrigin.ImageHooksEnabled = false; texture = texture ?? source.GetTexture(); if( texture == null ) return; @@ -1151,7 +1233,7 @@ private void DumpTexture( object source, Texture2D texture ) } finally { - _imageHooksEnabled = true; + CallOrigin.ImageHooksEnabled = true; } } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/CallOrigin.cs b/src/XUnity.AutoTranslator.Plugin.Core/CallOrigin.cs index bc643fb4..d5ee7785 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/CallOrigin.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/CallOrigin.cs @@ -15,6 +15,7 @@ namespace XUnity.AutoTranslator.Plugin.Core { internal static class CallOrigin { + public static bool ImageHooksEnabled = true; public static bool ExpectsTextToBeReturned = false; public static IReadOnlyTextTranslationCache TextCache = null; diff --git a/src/XUnity.AutoTranslator.Plugin.Core/Extensions/TextureComponentExtensions.cs b/src/XUnity.AutoTranslator.Plugin.Core/Extensions/TextureComponentExtensions.cs index 4ff6b961..ba154a02 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/Extensions/TextureComponentExtensions.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/Extensions/TextureComponentExtensions.cs @@ -46,9 +46,9 @@ public static Texture2D GetTexture( this object ui ) } } - public static void SetTexture( this object ui, Texture2D texture ) + public static Sprite SetTexture( this object ui, Texture2D texture, Sprite sprite, bool isPrefixHooked ) { - if( ui == null ) return; + if( ui == null ) return null; var currentTexture = ui.GetTexture(); @@ -56,10 +56,13 @@ public static void SetTexture( this object ui, Texture2D texture ) { if( Settings.EnableSpriteRendererHooking && ui is SpriteRenderer sr ) { - var sprite = sr.sprite; - if( sprite != null ) + if( isPrefixHooked ) { - SafeSetSprite( sr, texture ); + return SafeCreateSprite( sr, sprite, texture ); + } + else + { + return SafeSetSprite( sr, sprite, texture ); } } else @@ -83,12 +86,21 @@ public static void SetTexture( this object ui, Texture2D texture ) } } } + + return null; } - private static void SafeSetSprite( SpriteRenderer sr, Texture2D texture ) + private static Sprite SafeSetSprite( SpriteRenderer sr, Sprite sprite, Texture2D texture ) { - var newSprite = Sprite.Create( texture, sr.sprite.rect, Vector2.zero ); + var newSprite = Sprite.Create( texture, sprite != null ? sprite.rect : sr.sprite.rect, Vector2.zero ); sr.sprite = newSprite; + return newSprite; + } + + private static Sprite SafeCreateSprite( SpriteRenderer sr, Sprite sprite, Texture2D texture ) + { + var newSprite = Sprite.Create( texture, sprite != null ? sprite.rect : sr.sprite.rect, Vector2.zero ); + return newSprite; } public static void SetAllDirtyEx( this object ui ) @@ -101,7 +113,7 @@ public static void SetAllDirtyEx( this object ui ) { ClrTypes.Graphic.CachedMethod( SetAllDirtyMethodName ).Invoke( ui ); } - else + else if( ui is not SpriteRenderer ) { AccessToolsShim.Method( type, MarkAsChangedMethodName )?.Invoke( ui, null ); } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/Hooks/ImageHooks.cs b/src/XUnity.AutoTranslator.Plugin.Core/Hooks/ImageHooks.cs index e2ee9f2a..0eeaed19 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/Hooks/ImageHooks.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/Hooks/ImageHooks.cs @@ -9,6 +9,7 @@ using XUnity.AutoTranslator.Plugin.Core.Extensions; using XUnity.Common.Constants; using XUnity.Common.Harmony; +using XUnity.Common.Logging; using XUnity.Common.MonoMod; namespace XUnity.AutoTranslator.Plugin.Core.Hooks @@ -135,24 +136,46 @@ static MethodBase TargetMethod( object instance ) return AccessToolsShim.Property( ClrTypes.SpriteRenderer, "sprite" )?.GetSetMethod(); } - public static void Postfix( object __instance ) + public static void Prefix( object __instance, ref Sprite value ) { - Texture2D _ = null; - AutoTranslationPlugin.Current.Hook_ImageChangedOnComponent( __instance, ref _, false, false ); + Texture2D texture; + var prev = CallOrigin.ImageHooksEnabled; + CallOrigin.ImageHooksEnabled = false; + try + { + texture = value.texture; + } + finally + { + CallOrigin.ImageHooksEnabled = prev; + } + AutoTranslationPlugin.Current.Hook_ImageChangedOnComponent( __instance, ref value, ref texture, true, false ); } - static Action _original; + //public static void Postfix( object __instance, ref Sprite value ) + //{ + // Texture2D _ = null; + // AutoTranslationPlugin.Current.Hook_ImageChangedOnComponent( __instance, ref _, false, false ); + //} + + static Action _original; static void MM_Init( object detour ) { - _original = detour.GenerateTrampolineEx>(); + _original = detour.GenerateTrampolineEx>(); } - static void MM_Detour( object __instance, object sprite ) + static void MM_Detour( object __instance, Sprite sprite ) { + //var prev = sprite; + Prefix( __instance, ref sprite ); + _original( __instance, sprite ); - Postfix( __instance ); + //if( prev != sprite ) + //{ + // Postfix( __instance, ref sprite ); + //} } } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/ImageTranslationInfo.cs b/src/XUnity.AutoTranslator.Plugin.Core/ImageTranslationInfo.cs index e4741537..011a1fe9 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/ImageTranslationInfo.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/ImageTranslationInfo.cs @@ -1,7 +1,23 @@ -namespace XUnity.AutoTranslator.Plugin.Core +using UnityEngine; +using XUnity.Common.Utilities; + +namespace XUnity.AutoTranslator.Plugin.Core { internal class ImageTranslationInfo { public bool IsTranslated { get; set; } + + public WeakReference Original { get; private set; } + + public void Initialize( Texture2D texture ) + { + Original = WeakReference.Create( texture ); + } + + public void Reset( Texture2D newTexture ) + { + IsTranslated = false; + Original = WeakReference.Create( newTexture ); + } } } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/TextureTranslationInfo.cs b/src/XUnity.AutoTranslator.Plugin.Core/TextureTranslationInfo.cs index ef14155e..0842b217 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/TextureTranslationInfo.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/TextureTranslationInfo.cs @@ -25,6 +25,8 @@ internal class TextureTranslationInfo public Texture2D Translated { get; private set; } + public Sprite TranslatedSprite { get; set; } + public bool IsTranslated { get; set; } public bool IsDumped { get; set; } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/Utilities/ObjectReferenceMapperEx.cs b/src/XUnity.AutoTranslator.Plugin.Core/Utilities/ObjectReferenceMapperEx.cs index f23148e7..cd88920a 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/Utilities/ObjectReferenceMapperEx.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/Utilities/ObjectReferenceMapperEx.cs @@ -35,9 +35,14 @@ public static TextTranslationInfo GetTextTranslationInfo( this object ui ) return null; } - public static ImageTranslationInfo GetOrCreateImageTranslationInfo( this object obj ) + public static ImageTranslationInfo GetOrCreateImageTranslationInfo( this object obj, Texture2D originalTexture ) { - return obj.GetOrCreateExtensionData(); + if( obj == null ) return null; + + var iti = obj.GetOrCreateExtensionData(); + if( iti.Original == null ) iti.Initialize( originalTexture ); + + return iti; } public static TextureTranslationInfo GetOrCreateTextureTranslationInfo( this Texture2D texture )