169 lines
5.7 KiB
C#
169 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using AibisDream.UI;
|
|
using UnityEditor;
|
|
using UnityEditor.Build;
|
|
using UnityEditor.Build.Reporting;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.EditorTools.Localization
|
|
{
|
|
public readonly struct LocalizedObjSpriteValidationIssue
|
|
{
|
|
public LocalizedObjSpriteValidationIssue(string assetPath, string message)
|
|
{
|
|
AssetPath = assetPath;
|
|
Message = message;
|
|
}
|
|
|
|
public string AssetPath { get; }
|
|
public string Message { get; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"{AssetPath}: {Message}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates localized Obj sprite groups without depending on Yarn references or
|
|
/// Unity Localization asset tables. A group becomes localized as soon as one
|
|
/// supported non-Chinese suffix is present.
|
|
/// </summary>
|
|
public static class LocalizedObjSpriteValidator
|
|
{
|
|
internal const string DefaultObjSpriteRoot = "Assets/RawResources/Art/Obj";
|
|
private const string MenuPath =
|
|
"Tools/AIBIS/Localization/Validate Localized Obj Sprites";
|
|
|
|
[MenuItem(MenuPath)]
|
|
public static void ValidateFromMenu()
|
|
{
|
|
IReadOnlyList<LocalizedObjSpriteValidationIssue> issues = Validate();
|
|
LogIssues(issues);
|
|
if (issues.Count == 0)
|
|
{
|
|
Debug.Log(
|
|
"[LocalizedObjSpriteValidator] Validation passed. " +
|
|
"All detected localized Obj sprite groups are complete.");
|
|
}
|
|
}
|
|
|
|
public static IReadOnlyList<LocalizedObjSpriteValidationIssue> Validate(
|
|
string rootPath = DefaultObjSpriteRoot)
|
|
{
|
|
var issues = new List<LocalizedObjSpriteValidationIssue>();
|
|
if (!Directory.Exists(rootPath))
|
|
{
|
|
issues.Add(new LocalizedObjSpriteValidationIssue(
|
|
ToAssetPath(rootPath),
|
|
"Obj sprite root does not exist."));
|
|
return issues;
|
|
}
|
|
|
|
var localizedGroups = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (string filePath in Directory.EnumerateFiles(
|
|
rootPath,
|
|
"*.png",
|
|
SearchOption.AllDirectories))
|
|
{
|
|
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
|
if (!LocalizedObjSpriteNaming.TryParseLocalizedVariant(
|
|
fileName,
|
|
out string logicalName,
|
|
out _))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(logicalName))
|
|
{
|
|
issues.Add(new LocalizedObjSpriteValidationIssue(
|
|
ToAssetPath(filePath),
|
|
"Localized variant has an empty logical name."));
|
|
continue;
|
|
}
|
|
|
|
string directory = Path.GetDirectoryName(filePath) ?? rootPath;
|
|
localizedGroups.Add(Path.Combine(directory, logicalName));
|
|
}
|
|
|
|
foreach (string groupPath in localizedGroups.OrderBy(
|
|
path => path,
|
|
StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
ValidateRequiredFile(
|
|
$"{groupPath}.png",
|
|
LocalizedObjSpriteNaming.DefaultLocaleCode,
|
|
issues);
|
|
|
|
foreach (string localeCode in
|
|
LocalizedObjSpriteNaming.NonDefaultLocaleCodes)
|
|
{
|
|
ValidateRequiredFile(
|
|
$"{groupPath}-{localeCode}.png",
|
|
localeCode,
|
|
issues);
|
|
}
|
|
}
|
|
|
|
return issues;
|
|
}
|
|
|
|
internal static void LogIssues(
|
|
IReadOnlyList<LocalizedObjSpriteValidationIssue> issues)
|
|
{
|
|
foreach (LocalizedObjSpriteValidationIssue issue in issues)
|
|
Debug.LogError($"[LocalizedObjSpriteValidator] {issue}");
|
|
}
|
|
|
|
private static void ValidateRequiredFile(
|
|
string filePath,
|
|
string localeCode,
|
|
ICollection<LocalizedObjSpriteValidationIssue> issues)
|
|
{
|
|
if (File.Exists(filePath))
|
|
return;
|
|
|
|
issues.Add(new LocalizedObjSpriteValidationIssue(
|
|
ToAssetPath(filePath),
|
|
$"Missing required '{localeCode}' sprite variant."));
|
|
}
|
|
|
|
private static string ToAssetPath(string path)
|
|
{
|
|
return path.Replace('\\', '/');
|
|
}
|
|
}
|
|
|
|
public sealed class LocalizedObjSpriteBuildValidator : IPreprocessBuildWithReport
|
|
{
|
|
// Run before build preprocessors that mutate version information.
|
|
public int callbackOrder => -1000;
|
|
|
|
public void OnPreprocessBuild(BuildReport report)
|
|
{
|
|
IReadOnlyList<LocalizedObjSpriteValidationIssue> issues =
|
|
LocalizedObjSpriteValidator.Validate();
|
|
if (issues.Count == 0)
|
|
return;
|
|
|
|
LocalizedObjSpriteValidator.LogIssues(issues);
|
|
string summary = string.Join(
|
|
Environment.NewLine,
|
|
issues.Take(20).Select(issue => issue.ToString()));
|
|
if (issues.Count > 20)
|
|
{
|
|
summary += Environment.NewLine +
|
|
$"... and {issues.Count - 20} more issue(s).";
|
|
}
|
|
|
|
throw new BuildFailedException(
|
|
"Localized Obj sprite validation failed:" +
|
|
Environment.NewLine + summary);
|
|
}
|
|
}
|
|
}
|