diff --git a/CHANGELOG.md b/CHANGELOG.md index 165ffbba..8347ed99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -### 4.6.3 +### 4.6.4 + * BUG FIX - Fixed bug where the OutputFile was not always loaded with lowest priority during initialization + * BUG FIX - Fixed a bug where redirected resources could not be located under certain circumstances (again) + +### 4.6.3 * MISC - Disable all translator endpoints if output language is the same as the source language ### 4.6.2 diff --git a/README.md b/README.md index f8fcb65a..c459e759 100644 --- a/README.md +++ b/README.md @@ -467,11 +467,11 @@ Often other mods UI are implemented through IMGUI. As you can see above, this is This may seem like a nice feature to have enabled by default but **never redistribute the mod with this enabled**. The reason here being that IMGUI has a very spammy nature. This does not mean that IMGUI in general will spam the endpoint, just that it is more likely to cause spam (and therefore cause the plugin to shutdown). ## Manual Translations -When you use this plugin, you can always go to the file `Translation\_AutoGeneratedTranslations.{lang}.txt` (OutputFile) to edit any auto generated translations and they will show up the next time you run the game. Or you can press (ALT+R) to reload the translation immediately. +When you use this plugin, you can always go to the file `Translation\{Lang}\Text\_AutoGeneratedTranslations.txt` (OutputFile) to edit any auto generated translations and they will show up the next time you run the game. Or you can press (ALT+R) to reload the translation immediately. It is also worth noting that this plugin will read all text files (*.txt) in the `Translation` (Directory), so if you want to provide a manual translation, you can simply cut out texts from the `Translation\_AutoGeneratedTranslations.{lang}.txt` (OutputFile) and place them in new text files in order to replace them with a manual translation. These text files can also be placed in standard .zip archives. -In this context, the `Translation\_AutoGeneratedTranslations.{lang}.txt` (OutputFile) will always have the lowest priority when reading translations. So if the same translation is present in two places, it will not be the one from the (OutputFile) that is used. +In this context, the `Translation\{Lang}\Text\_AutoGeneratedTranslations.txt` (OutputFile) will always have the lowest priority when reading translations. So if the same translation is present in two places, it will not be the one from the (OutputFile) that is used. In some ADV engines text 'scrolls' into place slowly. Different techniques are used for this and in some instances if you want the translated text to be scrolling in instead of the untranslated text, you may need to set `GeneratePartialTranslations=True`. This should not be turned on unless required by the game. @@ -587,9 +587,9 @@ Example configuration that seperates translations for each executable: ``` [Files] -Directory=Translation\{GameExeName} -OutputFile=Translation\{GameExeName}\_AutoGeneratedTranslations.{lang}.txt -SubstitutionFile=Translation\{GameExeName}\_Substitutions.{lang}.txt +Directory=Translation\{GameExeName}\{Lang}\Text +Directory=Translation\{GameExeName}\{Lang}\Text\_AutoGeneratedTranslations.txt +Directory=Translation\{GameExeName}\{Lang}\Text\_Substitutions.txt ``` So when should use scope your translations? Well that depends on the type of scope: @@ -673,7 +673,7 @@ ZIP files that are placed in the `PreferredStoragePath` will be indexed during s ## Regarding Redistribution Redistributing this plugin for various games is absolutely encouraged. However, if you do so, please keep the following in mind: - * **Distribute the _AutoGeneratedTranslations.{lang}.txt file along with the redistribution with as many translations as possible to ensure the online translator is hit as little as possible.** + * **Distribute the _AutoGeneratedTranslations.txt file along with the redistribution with as many translations as possible to ensure the online translator is hit as little as possible.** * **Test your redistribution with logging/console enabled to ensure the game does not exhibit undesirable behaviour such as spamming the endpoints.** * Ensure you keep the plugin up-to-date, as much as reasonably possible. * If you use image loading feature, make sure you read [this section](#texture-translation). diff --git a/src/XUnity.AutoTranslator.Patcher/Patcher.cs b/src/XUnity.AutoTranslator.Patcher/Patcher.cs index d56e1e14..a4f08cd4 100644 --- a/src/XUnity.AutoTranslator.Patcher/Patcher.cs +++ b/src/XUnity.AutoTranslator.Patcher/Patcher.cs @@ -29,7 +29,7 @@ public override string Version { get { - return "4.6.2"; + return "4.6.4"; } } diff --git a/src/XUnity.AutoTranslator.Plugin.BepIn-5x/XUnity.AutoTranslator.Plugin.BepIn-5x.csproj b/src/XUnity.AutoTranslator.Plugin.BepIn-5x/XUnity.AutoTranslator.Plugin.BepIn-5x.csproj index 26abe95d..f534d985 100644 --- a/src/XUnity.AutoTranslator.Plugin.BepIn-5x/XUnity.AutoTranslator.Plugin.BepIn-5x.csproj +++ b/src/XUnity.AutoTranslator.Plugin.BepIn-5x/XUnity.AutoTranslator.Plugin.BepIn-5x.csproj @@ -2,7 +2,7 @@ net35 - 4.6.3 + 4.6.4 diff --git a/src/XUnity.AutoTranslator.Plugin.BepIn/AutoTranslatorPlugin.cs b/src/XUnity.AutoTranslator.Plugin.BepIn/AutoTranslatorPlugin.cs index fb6fe0c9..bbb478f7 100644 --- a/src/XUnity.AutoTranslator.Plugin.BepIn/AutoTranslatorPlugin.cs +++ b/src/XUnity.AutoTranslator.Plugin.BepIn/AutoTranslatorPlugin.cs @@ -20,7 +20,8 @@ public class AutoTranslatorPlugin : BaseUnityPlugin, IPluginEnvironment public AutoTranslatorPlugin() { - _dataPath = "BepInEx"; + // BepInEx 4.x paths cannot be trusted! + _dataPath = Path.Combine( Common.Constants.Paths.GameRoot, "BepInEx" ); _configPath = Path.Combine( _dataPath, "AutoTranslatorConfig.ini" ); //XuaLogger.Current = new BepInLogger(); } diff --git a/src/XUnity.AutoTranslator.Plugin.BepIn/XUnity.AutoTranslator.Plugin.BepIn.csproj b/src/XUnity.AutoTranslator.Plugin.BepIn/XUnity.AutoTranslator.Plugin.BepIn.csproj index d62df328..587d1e12 100644 --- a/src/XUnity.AutoTranslator.Plugin.BepIn/XUnity.AutoTranslator.Plugin.BepIn.csproj +++ b/src/XUnity.AutoTranslator.Plugin.BepIn/XUnity.AutoTranslator.Plugin.BepIn.csproj @@ -2,7 +2,7 @@ net35 - 4.6.3 + 4.6.4 diff --git a/src/XUnity.AutoTranslator.Plugin.Core/AssetRedirection/UnzippedDirectory.cs b/src/XUnity.AutoTranslator.Plugin.Core/AssetRedirection/UnzippedDirectory.cs index 4740d1c9..696fe923 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/AssetRedirection/UnzippedDirectory.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/AssetRedirection/UnzippedDirectory.cs @@ -21,6 +21,7 @@ internal class UnzippedDirectory : IDisposable public UnzippedDirectory( string root, bool cacheNormalFiles ) { + _cacheNormalFiles = cacheNormalFiles; _zipFiles = new List(); Directory.CreateDirectory( root ); @@ -33,9 +34,7 @@ public UnzippedDirectory( string root, bool cacheNormalFiles ) { _root = Path.Combine( _loweredCurrentDirectory, root.ToLowerInvariant() ); } - Initialize(); - _cacheNormalFiles = cacheNormalFiles; } public IEnumerable GetFiles( string path, params string[] extensions ) @@ -44,25 +43,15 @@ public IEnumerable GetFiles( string path, params string[] ex { if( Directory.Exists( path ) ) { - if( extensions == null || extensions.Length == 0 ) + var noExtensions = extensions == null || extensions.Length == 0; + var files = Directory.GetFiles( path, "*", SearchOption.TopDirectoryOnly ); + foreach( var file in files ) { - var files = Directory.GetFiles( path, "*", SearchOption.TopDirectoryOnly ); - foreach( var file in files ) + if( noExtensions || extensions.Any( x => file.EndsWith( x, StringComparison.OrdinalIgnoreCase ) ) ) { yield return new RedirectedResource( () => File.OpenRead( file ), null, file ); } } - else - { - foreach( var extension in extensions ) - { - var files = Directory.GetFiles( path, "*" + extension, SearchOption.TopDirectoryOnly ); - foreach( var file in files ) - { - yield return new RedirectedResource( () => File.OpenRead( file ), null, file ); - } - } - } } } @@ -118,7 +107,7 @@ public IEnumerable GetFile( string path ) .OrderBy( x => x.IsZipped ) .ThenBy( x => x.ContainerFile ) .ThenBy( x => x.FullPath ); - + foreach( var entry in entries ) { if( entry.IsZipped ) @@ -135,6 +124,8 @@ public IEnumerable GetFile( string path ) public bool DirectoryExists( string path ) { + var originalPath = path; + var exists = false; if( _rootZipDir != null ) { @@ -148,11 +139,13 @@ public bool DirectoryExists( string path ) exists = _rootZipDir.DirectoryExists( path ); } - return exists || ( !_cacheNormalFiles && Directory.Exists( path ) ); + return exists || ( !_cacheNormalFiles && Directory.Exists( originalPath ) ); } public bool FileExists( string path ) { + var originalPath = path; + var exists = false; if( _rootZipDir != null ) { @@ -166,7 +159,7 @@ public bool FileExists( string path ) exists = _rootZipDir.FileExists( path ); } - return exists || ( !_cacheNormalFiles && File.Exists( path ) ); + return exists || ( !_cacheNormalFiles && File.Exists( originalPath ) ); } private void Initialize() @@ -182,66 +175,65 @@ private void Initialize() foreach( var file in files ) { - if( !_cacheNormalFiles && !file.EndsWith( ".zip", StringComparison.OrdinalIgnoreCase ) ) - { - // skip any files that are not .zip files if we do not cache them all - continue; - } - - var current = _rootZipDir; - var relativePath = file.ToLowerInvariant().MakeRelativePath( _root ); - var parts = relativePath.Split( PathSeparators, StringSplitOptions.RemoveEmptyEntries ); + var isZip = file.EndsWith( ".zip", StringComparison.OrdinalIgnoreCase ); - for( int i = 0; i < parts.Length; i++ ) + if( isZip || ( _cacheNormalFiles && !isZip ) ) { - var part = parts[ i ]; + var current = _rootZipDir; + var relativePath = file.ToLowerInvariant().MakeRelativePath( _root ); + var parts = relativePath.Split( PathSeparators, StringSplitOptions.RemoveEmptyEntries ); - if( i == parts.Length - 1 ) + for( int i = 0; i < parts.Length; i++ ) { - if( part.EndsWith( ".zip", StringComparison.OrdinalIgnoreCase ) ) + var part = parts[ i ]; + + if( i == parts.Length - 1 ) { - // this is the zip file, read the metadata! - var start = current; + if( part.EndsWith( ".zip", StringComparison.OrdinalIgnoreCase ) ) + { + // this is the zip file, read the metadata! + var start = current; - var zf = new ZipFile( file ); - _zipFiles.Add( zf ); + var zf = new ZipFile( file ); + _zipFiles.Add( zf ); - foreach( ZipEntry entry in zf ) - { - current = start; - var internalPath = entry.Name.Replace( '/', '\\' ).ToLowerInvariant(); - var internalParts = internalPath.Split( PathSeparators, StringSplitOptions.RemoveEmptyEntries ); - for( int j = 0; j < internalParts.Length; j++ ) + foreach( ZipEntry entry in zf ) { - var internalPart = internalParts[ j ]; - if( j == internalParts.Length - 1 ) + current = start; + var internalPath = entry.Name.Replace( '/', '\\' ).ToLowerInvariant(); + var internalParts = internalPath.Split( PathSeparators, StringSplitOptions.RemoveEmptyEntries ); + for( int j = 0; j < internalParts.Length; j++ ) { - if( entry.IsFile ) + var internalPart = internalParts[ j ]; + if( j == internalParts.Length - 1 ) { - current.AddFile( internalPart, new FileEntry( internalPath, file, zf, entry ) ); + if( entry.IsFile ) + { + current.AddFile( internalPart, new FileEntry( internalPath, file, zf, entry ) ); + } + else + { + current = current.GetOrCreateChildPath( internalPart ); + } } else { current = current.GetOrCreateChildPath( internalPart ); } } - else - { - current = current.GetOrCreateChildPath( internalPart ); - } - } + } + } + else + { + current.AddFile( part, new FileEntry( file ) ); } } else { - current.AddFile( part, new FileEntry( file ) ); + current = current.GetOrCreateChildPath( part ); } } - else - { - current = current.GetOrCreateChildPath( part ); - } } } } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/Configuration/Settings.cs b/src/XUnity.AutoTranslator.Plugin.Core/Configuration/Settings.cs index 3b124f0c..89cdf752 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/Configuration/Settings.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/Configuration/Settings.cs @@ -219,7 +219,7 @@ public static void Configure() LogAllLoadedResources = PluginEnvironment.Current.Preferences.GetOrDefault( "ResourceRedirector", "LogAllLoadedResources", false ); EnableDumping = PluginEnvironment.Current.Preferences.GetOrDefault( "ResourceRedirector", "EnableDumping", false ); CacheMetadataForAllFiles = PluginEnvironment.Current.Preferences.GetOrDefault( "ResourceRedirector", "CacheMetadataForAllFiles", true ); - + if( CacheMetadataForAllFiles && EnableDumping ) { XuaLogger.AutoTranslator.Warn( "'EnableDumping' and 'CacheMetadataForAllOnStartup' cannot be enabled at the same time. Disabling 'CacheMetadataForAllOnStartup'..." ); diff --git a/src/XUnity.AutoTranslator.Plugin.Core/Constants/PluginData.cs b/src/XUnity.AutoTranslator.Plugin.Core/Constants/PluginData.cs index baf0ac88..5b140109 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/Constants/PluginData.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/Constants/PluginData.cs @@ -23,6 +23,6 @@ public static class PluginData /// /// Gets the version of the plugin. /// - public const string Version = "4.6.2"; + public const string Version = "4.6.4"; } } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/TextTranslationCache.cs b/src/XUnity.AutoTranslator.Plugin.Core/TextTranslationCache.cs index 120601cc..a52ef9b0 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/TextTranslationCache.cs +++ b/src/XUnity.AutoTranslator.Plugin.Core/TextTranslationCache.cs @@ -59,7 +59,8 @@ private static IEnumerable GetTranslationFiles() return Directory.GetFiles( Settings.TranslationsPath, $"*", SearchOption.AllDirectories ) .Where( x => x.EndsWith( ".txt", StringComparison.OrdinalIgnoreCase ) || x.EndsWith( ".zip", StringComparison.OrdinalIgnoreCase ) ) .Select( x => x.Replace( "/", "\\" ) ) - .Where( x => !x.EndsWith( "resizer.txt", StringComparison.OrdinalIgnoreCase ) ); + .Where( x => !x.EndsWith( "resizer.txt", StringComparison.OrdinalIgnoreCase ) ) + .Select( x => new FileInfo( x ).FullName ); } internal void LoadTranslationFiles() @@ -84,11 +85,11 @@ internal void LoadTranslationFiles() _scopedTranslations.Clear(); Settings.Replacements.Clear(); - var mainTranslationFile = Settings.AutoTranslationsFilePath; - var substitutionFile = Settings.SubstitutionFilePath; + var mainTranslationFile = new FileInfo( Settings.AutoTranslationsFilePath ).FullName; + var substitutionFile = new FileInfo( Settings.SubstitutionFilePath ).FullName; LoadTranslationsInFile( substitutionFile, true, false ); LoadTranslationsInFile( mainTranslationFile, false, true ); - foreach( var fullFileName in GetTranslationFiles().Reverse().Except( new[] { mainTranslationFile, substitutionFile } ) ) + foreach( var fullFileName in GetTranslationFiles().Reverse().Except( new[] { mainTranslationFile, substitutionFile }, StringComparer.OrdinalIgnoreCase ) ) { LoadTranslationsInFile( fullFileName, false, false ); } diff --git a/src/XUnity.AutoTranslator.Plugin.Core/XUnity.AutoTranslator.Plugin.Core.csproj b/src/XUnity.AutoTranslator.Plugin.Core/XUnity.AutoTranslator.Plugin.Core.csproj index 1c431552..1e70e225 100644 --- a/src/XUnity.AutoTranslator.Plugin.Core/XUnity.AutoTranslator.Plugin.Core.csproj +++ b/src/XUnity.AutoTranslator.Plugin.Core/XUnity.AutoTranslator.Plugin.Core.csproj @@ -2,7 +2,7 @@ net35 - 4.6.3 + 4.6.4 latest diff --git a/src/XUnity.AutoTranslator.Plugin.IPA/AutoTranslatorPlugin.cs b/src/XUnity.AutoTranslator.Plugin.IPA/AutoTranslatorPlugin.cs index 9028c7a1..ff505a97 100644 --- a/src/XUnity.AutoTranslator.Plugin.IPA/AutoTranslatorPlugin.cs +++ b/src/XUnity.AutoTranslator.Plugin.IPA/AutoTranslatorPlugin.cs @@ -20,7 +20,7 @@ public class AutoTranslatorPlugin : IPlugin, IPluginEnvironment public AutoTranslatorPlugin() { - _dataPath = "Plugins"; + _dataPath = Path.Combine( Common.Constants.Paths.GameRoot, "Plugins" ); _configPath = Path.Combine( _dataPath, "AutoTranslatorConfig.ini" ); } diff --git a/src/XUnity.AutoTranslator.Plugin.IPA/XUnity.AutoTranslator.Plugin.IPA.csproj b/src/XUnity.AutoTranslator.Plugin.IPA/XUnity.AutoTranslator.Plugin.IPA.csproj index 490a8014..5ade85b2 100644 --- a/src/XUnity.AutoTranslator.Plugin.IPA/XUnity.AutoTranslator.Plugin.IPA.csproj +++ b/src/XUnity.AutoTranslator.Plugin.IPA/XUnity.AutoTranslator.Plugin.IPA.csproj @@ -2,7 +2,7 @@ net35 - 4.6.3 + 4.6.4 diff --git a/src/XUnity.AutoTranslator.Plugin.UnityInjector/XUnity.AutoTranslator.Plugin.UnityInjector.csproj b/src/XUnity.AutoTranslator.Plugin.UnityInjector/XUnity.AutoTranslator.Plugin.UnityInjector.csproj index 07d2d0e8..6838da61 100644 --- a/src/XUnity.AutoTranslator.Plugin.UnityInjector/XUnity.AutoTranslator.Plugin.UnityInjector.csproj +++ b/src/XUnity.AutoTranslator.Plugin.UnityInjector/XUnity.AutoTranslator.Plugin.UnityInjector.csproj @@ -2,7 +2,7 @@ net35 - 4.6.3 + 4.6.4 diff --git a/src/XUnity.AutoTranslator.Setup/XUnity.AutoTranslator.Setup.csproj b/src/XUnity.AutoTranslator.Setup/XUnity.AutoTranslator.Setup.csproj index d24874cb..57853f3b 100644 --- a/src/XUnity.AutoTranslator.Setup/XUnity.AutoTranslator.Setup.csproj +++ b/src/XUnity.AutoTranslator.Setup/XUnity.AutoTranslator.Setup.csproj @@ -4,7 +4,7 @@ Exe net40 SetupReiPatcherAndAutoTranslator - 4.6.3 + 4.6.4 icon.ico diff --git a/src/XUnity.ResourceRedirector.BepIn-5x/XUnity.ResourceRedirector.BepIn-5x.csproj b/src/XUnity.ResourceRedirector.BepIn-5x/XUnity.ResourceRedirector.BepIn-5x.csproj index e22987f2..288c8689 100644 --- a/src/XUnity.ResourceRedirector.BepIn-5x/XUnity.ResourceRedirector.BepIn-5x.csproj +++ b/src/XUnity.ResourceRedirector.BepIn-5x/XUnity.ResourceRedirector.BepIn-5x.csproj @@ -20,4 +20,14 @@ + + + + + + + + + +