/// <summary> /// Gets the preferred path to store the resource at if a specific file name is required. /// </summary> /// <param name="context"></param> /// <param name="asset"></param> /// <param name="fileName"></param> /// <returns></returns> public static string GetPreferredFilePathWithCustomFileName(this IAssetOrResourceLoadedContext context, UnityEngine.Object asset, string fileName) { string parentDirectory; if (context is AssetLoadedContext) { parentDirectory = "assets"; } else if (context is ResourceLoadedContext) { parentDirectory = "resources"; } else { throw new ArgumentException("context"); } var path = Path.Combine(Path.Combine(Settings.RedirectedResourcesPath, parentDirectory), context.GetUniqueFileSystemAssetPath(asset)); if (fileName != null) { path = Path.Combine(path, fileName); } return(path); }
protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref T asset, IAssetOrResourceLoadedContext context) { var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty && !DisableEmptyCacheCheck) { return(false); } var result = false; foreach (var entry in GetParams(asset)) { if (UpdateParam(calculatedModificationPath, cache, entry)) { result = true; } } return(result); }
protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref T asset, IAssetOrResourceLoadedContext context) { var result = false; var start = Time.realtimeSinceStartup; try { var cache = GetTranslationCache(calculatedModificationPath, asset, context); if (cache.IsEmpty && !DisableEmptyCacheCheck) { return(false); } foreach (var entry in GetParams(asset)) { if (UpdateParam(calculatedModificationPath, cache, entry)) { result = true; } } return(result); } finally { Logger.DebugLogDebug("{0}.{1}: {2} => {3} ({4} seconds)", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath, result, Time.realtimeSinceStartup - start); } }
public static bool IsPathAllowed(this IPathListBoundHandler handler, Object asset, IAssetOrResourceLoadedContext context) { var pth = PathList.Normalize(context.GetUniqueFileSystemAssetPath(asset).Replace(".unity3d", string.Empty)); return(IsPathAllowed(handler, pth, true)); }
internal static bool DefaultShouldHandleAsset <THandler, TAsset>(this THandler handler, TAsset asset, IAssetOrResourceLoadedContext context) where TAsset : UnityEngine.Object where THandler : IRedirectorHandler <TAsset> { var logger = handler.GetLogger(); logger?.DebugLogDebug("{0}({1}, {2}[{3}])?", nameof(DefaultShouldHandleAsset), handler.GetType(), asset.name, asset.GetType()); var result = false; try { if (!handler.Enabled || !handler.ShouldHandleAssetForContext(asset, context)) { return(false); } if (handler is IPathListBoundHandler pathListBoundHandler) { return(result = pathListBoundHandler.IsPathAllowed(asset, context)); } return(result = true); } finally { logger?.DebugLogDebug("{0}({1}, {2}[{3}]) => {4}", nameof(DefaultShouldHandleAsset), handler.GetType(), asset.name, asset.GetType(), result); } }
protected override bool DumpAsset(string calculatedModificationPath, ExcelData asset, IAssetOrResourceLoadedContext context) { var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var cache = new SimpleTextTranslationCache( defaultTranslationFile, false); var columnsToDump = new HashSet <int>(TextResourceHelper.GetSupportedExcelColumns(calculatedModificationPath, asset)); for (var i = 1; i < asset.list.Count; i++) { var row = asset.GetRow(i); var rowColumns = Enumerable.Range(0, row.Count); if (columnsToDump.Count > 0) { rowColumns = rowColumns.Where(columnsToDump.Contains); } foreach (var key in rowColumns.Select(j => row[j]) .Where(k => !k.IsNullOrEmpty() && LanguageHelper.IsTranslatable(k))) { cache.AddTranslationToCache(key, key); } } return(true); }
public override TextAndEncoding TranslateTextAsset(string calculatedModificationPath, TextAsset asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()} attempt to handle {calculatedModificationPath}"); var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath} (no cache)"); return(null); } var obj = LoadFromAsset(asset); if (obj != null && TranslateObject(ref obj, cache, calculatedModificationPath)) { Logger.DebugLogDebug($"{GetType()} handled {calculatedModificationPath}"); return(StoreAsset(obj)); } Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath}"); return(null); }
public override TextAndEncoding TranslateTextAsset(string calculatedModificationPath, TextAsset asset, IAssetOrResourceLoadedContext context) { if (TextAssetMessagePackHelper.CanHandleAsset(asset, context, out var handler)) { //return new TextAndEncoding(asset.bytes, null); var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { Logger.LogDebug($"{GetType()} unable to handle {calculatedModificationPath} (no cache)"); return(null); } var obj = handler.Load(asset); if (obj != null && handler.Translate(ref obj, cache, calculatedModificationPath)) { Logger.LogDebug($"{GetType()} handled {calculatedModificationPath}"); return(handler.Store(obj)); } } return(null); }
public static ResourceMappingPath FromAssetContext(string calculatedModificationPath, UnityEngineObject asset, IAssetOrResourceLoadedContext context) { return(new ResourceMappingPath( context.GetUniqueFileSystemAssetPath(asset).Replace(".unity3d", string.Empty), calculatedModificationPath, allPathsNormalized: true)); }
/// <summary> /// Caches forward and reverse translation of assets as they're loaded, but does not apply them. /// to avoid breaking code that relies on original names being present. /// </summary> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref MapInfo asset, IAssetOrResourceLoadedContext context) { var result = false; var start = Time.realtimeSinceStartup; try { // updating the MapInfo assets directly breaks places that are doing lookups by mapName // instead of id, so we just register this as a place to lookup MapInfo translations and // return true so it appears handled Hooks.Init(); // register new translations with helper without replacing var cache = GetTranslationCache(calculatedModificationPath, asset, context); if (cache.IsEmpty) { return(result = true); } var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); // register with helper or dump without translating here foreach (var key in asset.param .Select(entry => TextResourceHelper.GetSpecializedKey(entry, GetMapName(entry))) .Where(k => !string.IsNullOrEmpty(k))) { if (cache.TryGetTranslation(key, true, out var translated)) { if (string.IsNullOrEmpty(translated)) { continue; } _mapLookup[key] = translated; _reverseMapLookup[translated] = key; if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && !string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, key); } } GameSpecificReplaceOrUpdateAsset(calculatedModificationPath, ref asset, context, cache, shouldTrack); return(result = true); } finally { Logger.DebugLogDebug("{0}.{1}: {2} => {3} ({4} seconds)", GetType(), nameof(ReplaceOrUpdateAsset), calculatedModificationPath, result, Time.realtimeSinceStartup - start); } }
protected override bool ShouldHandleAsset(TextAsset asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}])?"); var result = base.ShouldHandleAsset(asset, context) && TextAssetTableHelper.IsTable(asset); Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}]) => {result}"); return(result); }
protected override bool ShouldHandleAsset(TextAsset asset, IAssetOrResourceLoadedContext context) { var result = Enabled && TextAssetMessagePackHelper.CanHandleAsset(asset, context) && !context.HasReferenceBeenRedirectedBefore(asset); Logger.LogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}]) => {result}"); return(result); }
protected override bool ShouldHandleAsset(ScenarioData asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}])?"); var result = base.ShouldHandleAsset(asset, context); Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}]) => {result}"); return(result); }
protected override bool ShouldHandleAsset(TextAsset asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}])?"); var result = Enabled && !context.HasReferenceBeenRedirectedBefore(asset) && this.IsPathAllowed(asset, context) && asset.bytes != null; Logger.DebugLogDebug($"{GetType()}.ShouldHandleAsset({asset.name}[{asset.GetType()}]) => {result}"); return(result); }
public static bool CanHandleAsset(TextAsset textAsset, IAssetOrResourceLoadedContext context, out IHandler handler) { handler = null; if (textAsset.bytes?.Length > 0) { handler = GetHandler(textAsset, context); } return(handler != null); }
public static bool CanHandleAsset <T>(TextAsset textAsset, IAssetOrResourceLoadedContext context, out Handler <T> handler) where T : class { handler = null; if (textAsset.bytes != null) { handler = GetHandler <T>(textAsset, context); } return(handler != null); }
private void Handle(IAssetOrResourceLoadedContext context) { if (context.Asset is TAsset castedAsset && ShouldHandleAsset(castedAsset, context)) { var unqiuePath = context.GetUniqueFileSystemAssetPath(castedAsset); var modificationFilePath = CalculateModificationFilePath(castedAsset, context); if ((CheckDirectory && Directory.Exists(modificationFilePath)) || (!CheckDirectory && File.Exists(modificationFilePath))) // IO, ewww! { try { bool handled = ReplaceOrUpdateAsset(modificationFilePath, ref castedAsset, context); if (handled) { XuaLogger.AutoTranslator.Debug($"Replaced or updated resource file: '{unqiuePath}'."); } else { XuaLogger.AutoTranslator.Debug($"Did not replace or update resource file: '{unqiuePath}'."); } context.Complete( skipRemainingPostfixes: handled); } catch (Exception e) { XuaLogger.AutoTranslator.Error(e, $"An error occurred while replacing or updating resource file: '{unqiuePath}'."); } } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled) { try { bool handled = DumpAsset(modificationFilePath, castedAsset, context); if (handled) { XuaLogger.AutoTranslator.Debug($"Dumped resource file: '{unqiuePath}'."); } else { XuaLogger.AutoTranslator.Debug($"Did not dump resource file: '{unqiuePath}'."); } context.Complete( skipRemainingPostfixes: handled); } catch (Exception e) { XuaLogger.AutoTranslator.Error(e, $"An error occurred while dumping resource file: '{unqiuePath}'."); } } if (!ReferenceEquals(castedAsset, context.Asset)) { context.Asset = castedAsset; } } }
protected override string CalculateModificationFilePath(TextAsset asset, IAssetOrResourceLoadedContext context) { var path = asset.DefaultCalculateModificationFilePath(context); if (AllowTranslationRegistration && TextResourceHelper.IsRandomNameListAsset(asset.name)) { ExcludePathFromTranslationRegistration(path); } return(path); }
/// <summary> /// Gets the preferred path to store the resource at if a specific file name is required. /// </summary> /// <param name="context"></param> /// <param name="parentDirectory"></param> /// <param name="asset"></param> /// <param name="fileName"></param> /// <returns></returns> public static string GetPreferredFilePathWithCustomFileName(this IAssetOrResourceLoadedContext context, string parentDirectory, UnityEngine.Object asset, string fileName) { var path = Path.Combine(parentDirectory, context.GetUniqueFileSystemAssetPath(asset)); if (fileName != null) { path = Path.Combine(path, fileName); } return(path); }
/// <summary> /// Caches forward and reverse translation of assets as they're loaded, but does not apply them. /// to avoid breaking code that relies on original names being present. /// </summary> protected override bool ReplaceOrUpdateAsset(string calculatedModificationPath, ref MapInfo asset, IAssetOrResourceLoadedContext context) { // updating the MapInfo assets directly breaks places that are doing lookups by mapName // instead of id, so we just register this as a place to lookup MapInfo translations and // return true so it appears handled Hooks.Init(); // register new translations with helper without replacing var defaultTranslationFile = Path.Combine(calculatedModificationPath, "translation.txt"); var redirectedResources = RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".txt"); var streams = redirectedResources.Select(x => x.OpenStream()); var cache = new SimpleTextTranslationCache( defaultTranslationFile, streams, false, true); if (cache.IsEmpty) { return(true); } var shouldTrack = IsTranslationRegistrationAllowed(calculatedModificationPath); // register with helper or dump without translating here foreach (var key in asset.param .Select(entry => TextResourceHelper.GetSpecializedKey(entry, GetMapName(entry))) .Where(k => !string.IsNullOrEmpty(k))) { if (cache.TryGetTranslation(key, true, out var translated)) { if (string.IsNullOrEmpty(translated)) { continue; } _mapLookup[key] = translated; _reverseMapLookup[translated] = key; if (shouldTrack) { TrackReplacement(calculatedModificationPath, key, translated); } TranslationHelper.RegisterRedirectedResourceTextToPath(translated, calculatedModificationPath); } else if (AutoTranslatorSettings.IsDumpingRedirectedResourcesEnabled && !string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, key); } } return(true); }
protected override bool DumpAsset(string calculatedModificationPath, ScenarioData asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); foreach (var param in asset.list) { TextResourceHelper.DumpScenarioParam(param, cache); } return(true); }
protected override bool DumpAsset(string calculatedModificationPath, TextAsset asset, IAssetOrResourceLoadedContext context) { if (asset?.bytes == null) { return(false); } var defaultFile = Path.Combine(calculatedModificationPath, "translation.bytes"); File.WriteAllBytes(defaultFile, asset.bytes); return(true); }
public virtual bool CanHandleAsset(TextAsset textAsset, IAssetOrResourceLoadedContext context) { var pth = context.GetUniqueFileSystemAssetPath(textAsset).Replace(".unity3d", string.Empty); if (ObjectMark == null || !this.IsPathAllowed(pth, true)) { return(false); } var searchLength = SearchLength != -1 ? SearchLength : ObjectMark.Count() * 3; IEnumerable <byte> haystack = null; textAsset.SafeProc(a => a.bytes.SafeProc(b => haystack = b.Take(searchLength))); return(haystack != null && TextResourceHelper.Helpers.ArrayContains(haystack, ObjectMark)); }
private void GetTableRules(string calculatedModificationPath, TextAsset asset, IAssetOrResourceLoadedContext context, out Predicate <int> rowAllowed, out Predicate <int> colAllowed) { Predicate <int> BuildAllowedPredicate(HashSet <int> whitelist, HashSet <int> blacklist) { var haveWhitelist = whitelist != null && whitelist.Count > 0; var haveBlacklist = blacklist != null && blacklist.Count > 0; if (haveWhitelist) { if (!haveBlacklist) { return(whitelist.Contains); } if (blacklist.Count > whitelist.Count) { return(r => whitelist.Contains(r) && !blacklist.Contains(r)); } return(r => !blacklist.Contains(r) && whitelist.Contains(r)); } if (haveBlacklist) { return(((Predicate <int>)blacklist.Contains).Not); } return(null); } foreach (var getter in TableRulesGetters) { var handled = getter(calculatedModificationPath, asset, context, out var rowWhitelist, out var rowBlacklist, out var colWhitelist, out var colBlacklist); if (!handled) { continue; } rowAllowed = BuildAllowedPredicate(rowWhitelist, rowBlacklist); colAllowed = BuildAllowedPredicate(colWhitelist, colBlacklist); return; } rowAllowed = null; colAllowed = null; }
internal static bool DefaultShouldHandleAsset <THandler, TAsset>(this THandler handler, TAsset asset, IAssetOrResourceLoadedContext context) where TAsset : UnityEngine.Object where THandler : IRedirectorHandler <TAsset> { if (!handler.Enabled || context.HasReferenceBeenRedirectedBefore(asset)) { return(false); } if (handler is IPathListBoundHandler pathListBoundHandler) { return(pathListBoundHandler.IsPathAllowed(asset, context)); } return(true); }
public virtual bool CanHandleAsset(TextAsset textAsset, IAssetOrResourceLoadedContext context) { var pth = context.GetUniqueFileSystemAssetPath(textAsset).Replace(".unity3d", string.Empty); if (ObjectMark != null && this.IsPathAllowed(pth, true)) { var searchLength = SearchLength != -1 ? SearchLength : ObjectMark.Count() * 3; var haystack = textAsset?.bytes?.Take(searchLength); if (haystack != null) { return(TextResourceHelper.Helpers.ArrayContains(haystack, ObjectMark)); } } return(false); }
protected override bool DumpAsset(string calculatedModificationPath, NickName asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); foreach (var entry in asset.param) { var key = TextResourceHelper.GetSpecializedKey(entry, entry.Name); if (!string.IsNullOrEmpty(key) && LanguageHelper.IsTranslatable(key)) { cache.AddTranslationToCache(key, entry.Name); } } return(true); }
protected override bool DumpAsset(string calculatedModificationPath, T asset, IAssetOrResourceLoadedContext context) { var cache = GetDumpCache(calculatedModificationPath, asset, context); var result = false; foreach (var entry in GetParams(asset)) { if (DumpParam(cache, entry)) { result = true; } } return(result); }
public override TextAndEncoding TranslateTextAsset(string calculatedModificationPath, TextAsset asset, IAssetOrResourceLoadedContext context) { Logger.DebugLogDebug($"{GetType()} attempt to handle {calculatedModificationPath}"); if (!Enabled || asset.bytes == null) { Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath}"); return(null); } byte[] bytes = null; var defaultFile = Path.Combine(calculatedModificationPath, "translation.bytes"); if (File.Exists(defaultFile)) { bytes = File.ReadAllBytes(defaultFile); } if (bytes == null || bytes.Length == 0) { foreach (var entry in RedirectedDirectory.GetFilesInDirectory(calculatedModificationPath, ".bytes")) { using (var stream = entry.OpenStream()) { bytes = ReadBytes(stream); } if (bytes.Length > 0) { break; } } } if (bytes == null || bytes.Length == 0) { Logger.DebugLogDebug($"{GetType()} unable to handle {calculatedModificationPath}: no .bytes files"); return(null); } Logger.DebugLogDebug($"{GetType()} handled {calculatedModificationPath}"); return(new TextAndEncoding(bytes, _textResourceHelper.TableHelper.TextAssetEncoding)); }
/// <summary> /// Gets the default resource and preferred path to store the redirected resource at. /// </summary> /// <param name="context"></param> /// <param name="asset"></param> /// <param name="extension"></param> /// <returns></returns> public static string GetPreferredFilePath(this IAssetOrResourceLoadedContext context, UnityEngine.Object asset, string extension) { string parentDirectory; if (context is AssetLoadedContext) { parentDirectory = "assets"; } else if (context is ResourceLoadedContext) { parentDirectory = "resources"; } else { throw new ArgumentException("context"); } return(Path.Combine(Path.Combine(Settings.RedirectedResourcesPath, parentDirectory), context.GetUniqueFileSystemAssetPath(asset)) + extension); }