Jelajahi Sumber

BUG FIX - Interacting with UI now blocks input to game

randoman 6 tahun lalu
induk
melakukan
eb7313a5a2

+ 4 - 1
CHANGELOG.md

@@ -1,4 +1,7 @@
-### 3.1.0
+### 3.1.1
+ * BUG FIX - Interacting with UI now blocks input to game
+
+### 3.1.0
  * FEATURE - Support for games with 'netstandard2.0' API surface through config option 'EnableExperimentalHooks'
  * BUG FIX - Bug fixes and improvements to Utage hooking implementation - EnableUtage config option also removed (always on now)
  * BUG FIX - Rich text parser bug fixes when only a single tag with no ending was used

+ 20 - 14
src/XUnity.AutoTranslator.Plugin.Core/AutoTranslationPlugin.cs

@@ -281,8 +281,22 @@ namespace XUnity.AutoTranslator.Plugin.Core
          LoadTranslations();
          LoadStaticTranslations();
 
+         UnityTextParsers.Initialize( text => IsTranslatable( text ) && IsBelowMaxLength( text ) );
+
+         // start a thread that will periodically removed unused references
+         var t1 = new Thread( MaintenanceLoop );
+         t1.IsBackground = true;
+         t1.Start();
+
+         // start a thread that will periodically save new translations
+         var t2 = new Thread( SaveTranslationsLoop );
+         t2.IsBackground = true;
+         t2.Start();
+
          try
          {
+            DisableAutoTranslator();
+
             _window = new XuaWindow(
                new List<ToggleViewModel>
                {
@@ -313,18 +327,10 @@ namespace XUnity.AutoTranslator.Plugin.Core
          {
             XuaLogger.Current.Error( e, "An error occurred while setting up UI." );
          }
-
-         UnityTextParsers.Initialize( text => IsTranslatable( text ) && IsBelowMaxLength( text ) );
-
-         // start a thread that will periodically removed unused references
-         var t1 = new Thread( MaintenanceLoop );
-         t1.IsBackground = true;
-         t1.Start();
-
-         // start a thread that will periodically save new translations
-         var t2 = new Thread( SaveTranslationsLoop );
-         t2.IsBackground = true;
-         t2.Start();
+         finally
+         {
+            EnableAutoTranslator();
+         }
 
          XuaLogger.Current.Info( $"Loaded XUnity.AutoTranslator into Unity [{Application.unityVersion}] game." );
       }
@@ -1570,6 +1576,7 @@ namespace XUnity.AutoTranslator.Plugin.Core
          {
             info?.Reset( text );
 
+            //var textKey = new TranslationKey( ui, text, !ui.SupportsStabilization(), false );
             var textKey = new TranslationKey( ui, text, ui.IsSpammingComponent(), false );
 
             // if we already have translation loaded in our _translatios dictionary, simply load it and set text
@@ -1622,12 +1629,11 @@ namespace XUnity.AutoTranslator.Plugin.Core
          // Ensure that we actually want to translate this text and its owning UI element. 
          if( !string.IsNullOrEmpty( text ) && IsTranslatable( text ) && ShouldTranslateTextComponent( ui, ignoreComponentState ) && !IsCurrentlySetting( info ) )
          {
-            //Logger.Current.Debug( "START: " + ui.GetType().Name + ": " + text );
-
             info?.Reset( originalText );
             var isSpammer = ui.IsSpammingComponent();
             if( isSpammer && !IsBelowMaxLength( text ) ) return null; // avoid templating long strings every frame for IMGUI, important!
 
+            //var textKey = new TranslationKey( ui, text, !supportsStabilization, context != null );
             var textKey = new TranslationKey( ui, text, isSpammer, context != null );
 
             // if we already have translation loaded in our _translatios dictionary, simply load it and set text

+ 1 - 0
src/XUnity.AutoTranslator.Plugin.Core/Constants/ClrTypes.cs

@@ -25,6 +25,7 @@ namespace XUnity.AutoTranslator.Plugin.Core.Constants
       public static readonly Type UIInput = FindType( "UIInput" );
 
       // Unity
+      public static readonly Type GUIContent = FindType( "UnityEngine.GUIContent" );
       public static readonly Type WWW = FindType( "UnityEngine.WWW" );
       public static readonly Type InputField = FindType( "UnityEngine.UI.InputField" );
       public static readonly Type Text = FindType( "UnityEngine.UI.Text" );

+ 20 - 1
src/XUnity.AutoTranslator.Plugin.Core/Extensions/TextComponentExtensions.cs

@@ -13,6 +13,12 @@ namespace XUnity.AutoTranslator.Plugin.Core.Extensions
 {
    internal static class TextComponentExtensions
    {
+      //private static readonly GUIContent[] TemporaryGUIContents = ClrTypes.GUIContent
+      //   .GetFields( BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic )
+      //   .Where( x => x.DeclaringType == typeof( GUIContent ) && ( x.Name == "s_Text" || x.Name == "s_TextImage" ) )
+      //   .Select( x => (GUIContent)x.GetValue( null ) )
+      //   .ToArray();
+
       private static readonly string RichTextPropertyName = "richText";
       private static readonly string TextPropertyName = "text";
 
@@ -46,7 +52,20 @@ namespace XUnity.AutoTranslator.Plugin.Core.Extensions
          if( ui == null ) return false;
 
          // shortcircuit for spammy component, to avoid reflective calls
-         if( ui is GUIContent ) return false;
+         if( ui is GUIContent )
+         {
+            return false;
+
+            //var len = TemporaryGUIContents.Length;
+            //for( int i = 0; i < len; i++ )
+            //{
+            //   if( ReferenceEquals( ui, TemporaryGUIContents[ i ] ) )
+            //   {
+            //      return false;
+            //   }
+            //}
+            //return true;
+         }
 
          var type = ui.GetType();
 

+ 106 - 0
src/XUnity.AutoTranslator.Plugin.Core/Hooks/IMGUIHooks.cs

@@ -5,6 +5,7 @@ using System.Reflection;
 using System.Text;
 using Harmony;
 using UnityEngine;
+using XUnity.AutoTranslator.Plugin.Core.Constants;
 using static UnityEngine.GUI;
 
 namespace XUnity.AutoTranslator.Plugin.Core.Hooks.IMGUI
@@ -14,6 +15,11 @@ namespace XUnity.AutoTranslator.Plugin.Core.Hooks.IMGUI
       public static bool HooksOverriden = false;
 
       public static readonly Type[] All = new[] {
+         //typeof( GUIContent_text_Hook ),
+         //typeof( GUIContent_Temp_Hook1 ),
+         //typeof( GUIContent_Temp_Hook2 ),
+         //typeof( GUIContent_Temp_Hook3 ),
+
          typeof( GUI_BeginGroup_Hook ),
          typeof( GUI_Box_Hook ),
          typeof( GUI_DoRepeatButton_Hook ),
@@ -27,6 +33,106 @@ namespace XUnity.AutoTranslator.Plugin.Core.Hooks.IMGUI
       };
    }
 
+
+   //[Harmony, HarmonyPriority( Priority.Last )]
+   //internal static class GUIContent_text_Hook
+   //{
+   //   static bool Prepare( HarmonyInstance instance )
+   //   {
+   //      return ClrTypes.GUIContent != null;
+   //   }
+
+   //   static MethodBase TargetMethod( HarmonyInstance instance )
+   //   {
+   //      return AccessTools.Property( ClrTypes.GUIContent, "text" )?.GetSetMethod();
+   //   }
+
+   //   static void Postfix( GUIContent __instance )
+   //   {
+   //      if( !IMGUIHooks.HooksOverriden )
+   //      {
+   //         AutoTranslationPlugin.Current.Hook_TextChanged( __instance, false );
+   //      }
+   //   }
+   //}
+
+   //[Harmony, HarmonyPriority( Priority.Last )]
+   //internal static class GUIContent_Temp_Hook1
+   //{
+   //   static bool Prepare( HarmonyInstance instance )
+   //   {
+   //      return ClrTypes.GUIContent != null;
+   //   }
+
+   //   static MethodBase TargetMethod( HarmonyInstance instance )
+   //   {
+   //      return AccessTools.Method( ClrTypes.GUIContent, "Temp", new[] { typeof( string ) } );
+   //   }
+
+   //   static void Postfix( GUIContent __result )
+   //   {
+   //      if( !IMGUIHooks.HooksOverriden )
+   //      {
+   //         AutoTranslationPlugin.Current.Hook_TextChanged( __result, false );
+   //      }
+   //   }
+   //}
+
+   //[Harmony, HarmonyPriority( Priority.Last )]
+   //internal static class GUIContent_Temp_Hook2
+   //{
+   //   static bool Prepare( HarmonyInstance instance )
+   //   {
+   //      return ClrTypes.GUIContent != null;
+   //   }
+
+   //   static MethodBase TargetMethod( HarmonyInstance instance )
+   //   {
+   //      return AccessTools.Method( ClrTypes.GUIContent, "Temp", new[] { typeof( string ), typeof( string ) } );
+   //   }
+
+   //   static void Postfix( GUIContent __result )
+   //   {
+   //      if( !IMGUIHooks.HooksOverriden )
+   //      {
+   //         AutoTranslationPlugin.Current.Hook_TextChanged( __result, false );
+   //      }
+   //   }
+   //}
+
+   //[Harmony, HarmonyPriority( Priority.Last )]
+   //internal static class GUIContent_Temp_Hook3
+   //{
+   //   static bool Prepare( HarmonyInstance instance )
+   //   {
+   //      return ClrTypes.GUIContent != null;
+   //   }
+
+   //   static MethodBase TargetMethod( HarmonyInstance instance )
+   //   {
+   //      return AccessTools.Method( ClrTypes.GUIContent, "Temp", new[] { typeof( string ), typeof( Texture ) } );
+   //   }
+
+   //   static void Postfix( GUIContent __result )
+   //   {
+   //      if( !IMGUIHooks.HooksOverriden )
+   //      {
+   //         AutoTranslationPlugin.Current.Hook_TextChanged( __result, false );
+   //      }
+   //   }
+   //}
+
+
+
+
+
+
+
+
+
+
+
+
    [Harmony, HarmonyPriority( Priority.Last )]
    internal static class GUI_BeginGroup_Hook
    {

+ 22 - 0
src/XUnity.AutoTranslator.Plugin.Core/UI/GUIUtil.cs

@@ -85,5 +85,27 @@ namespace XUnity.AutoTranslator.Plugin.Core.UI
 
          return WindowBackgroundStyle;
       }
+
+      public static bool IsAnyMouseButtonOrScrollWheelDown
+      {
+         get
+         {
+            return Input.mouseScrollDelta.y > 0f
+               || Input.GetMouseButtonDown( 0 )
+               || Input.GetMouseButtonDown( 1 )
+               || Input.GetMouseButtonDown( 2 );
+         }
+      }
+
+      public static bool IsAnyMouseButtonOrScrollWheel
+      {
+         get
+         {
+            return Input.mouseScrollDelta.y > 0f
+               || Input.GetMouseButton( 0 )
+               || Input.GetMouseButton( 1 )
+               || Input.GetMouseButton( 2 );
+         }
+      }
    }
 }

+ 28 - 20
src/XUnity.AutoTranslator.Plugin.Core/UI/XuaWindow.cs

@@ -9,6 +9,7 @@ namespace XUnity.AutoTranslator.Plugin.Core.UI
 {
    internal class XuaWindow
    {
+      private const int WindowId = 5464332;
       private const int WindowHeight = 480;
       private const int WindowWidth = 320;
 
@@ -18,30 +19,19 @@ namespace XUnity.AutoTranslator.Plugin.Core.UI
       private Rect _windowRect = new Rect( 20, 20, WindowWidth, WindowHeight );
 
       private DropdownGUI<TranslatorDropdownOptionViewModel, ConfiguredEndpoint> _endpointDropdown;
-
-      private bool _isShown;
       private List<ToggleViewModel> _toggles;
       private List<TranslatorDropdownOptionViewModel> _endpointOptions;
       private List<ButtonViewModel> _commandButtons;
       private List<LabelViewModel> _labels;
+      private bool _isMouseDownOnWindow = false;
 
-      public bool IsShown
-      {
-         get
-         {
-            return _isShown;
-         }
-         set
-         {
-            _isShown = value;
-         }
-      }
+      public bool IsShown { get; set; }
 
       public XuaWindow(
-         List<ToggleViewModel> toggles,
-         List<TranslatorDropdownOptionViewModel> endpoints,
-         List<ButtonViewModel> commandButtons,
-         List<LabelViewModel> labels )
+       List<ToggleViewModel> toggles,
+       List<TranslatorDropdownOptionViewModel> endpoints,
+       List<ButtonViewModel> commandButtons,
+       List<LabelViewModel> labels )
       {
          _toggles = toggles;
          _endpointOptions = endpoints;
@@ -53,7 +43,25 @@ namespace XUnity.AutoTranslator.Plugin.Core.UI
       {
          GUI.Box( _windowRect, GUIContent.none, GUIUtil.GetWindowBackgroundStyle() );
 
-         _windowRect = GUI.Window( 5464332, _windowRect, CreateWindowUI, "---- XUnity.AutoTranslator UI ----" );
+         _windowRect = GUI.Window( WindowId, _windowRect, CreateWindowUI, "---- XUnity.AutoTranslator UI ----" );
+
+         if( GUIUtil.IsAnyMouseButtonOrScrollWheelDown )
+         {
+            var point = new Vector2( Input.mousePosition.x, Screen.height - Input.mousePosition.y );
+            _isMouseDownOnWindow = _windowRect.Contains( point );
+         }
+
+         if( !_isMouseDownOnWindow || !GUIUtil.IsAnyMouseButtonOrScrollWheel )
+            return;
+
+         // make sure window is focused if scroll wheel is used to indicate we consumed that event
+         GUI.FocusWindow( WindowId );
+
+         var point1 = new Vector2( Input.mousePosition.x, Screen.height - Input.mousePosition.y );
+         if( !_windowRect.Contains( point1 ) )
+            return;
+
+         Input.ResetInputAxes();
       }
 
       private void CreateWindowUI( int id )
@@ -100,9 +108,9 @@ namespace XUnity.AutoTranslator.Plugin.Core.UI
          GUI.Label( GUIUtil.R( col1x, posy, col12, GUIUtil.LabelHeight ), "---- Command Panel ----", GUIUtil.LabelCenter );
          posy += GUIUtil.RowHeight + GUIUtil.ComponentSpacing;
 
-         for( int row = 0 ; row < rows ; row++ )
+         for( int row = 0; row < rows; row++ )
          {
-            for( int col = 0 ; col < buttonsPerRow ; col++ )
+            for( int col = 0; col < buttonsPerRow; col++ )
             {
                int idx = ( row * buttonsPerRow ) + col;
                if( idx >= _commandButtons.Count ) break;