From a0c89257dda93b9e3aa7428c1119f6ec95ad8f12 Mon Sep 17 00:00:00 2001 From: NBKRedSpy <54865934+NBKRedSpy@users.noreply.github.com> Date: Tue, 28 Mar 2023 23:23:07 -0400 Subject: [PATCH] JSON changes, error changes, refactor * Moved errors to output instead of stderr * Added File Name and JSON path to errors * Moved some code to a function * Escapes new lines as \n in the text. * Fixed packaging not using Release build --- .../CardSurvival-Localization.csproj | 4 +- CardSurvival-Localization/LocalizationInfo.cs | 2 + .../LocalizationKeyExtrator.cs | 38 ---------- CardSurvival-Localization/Program.cs | 70 +++++++++++-------- CardSurvival-Localization/TestData/Test.json | 10 +-- Package.ps1 | 4 +- README.md | 48 +++++++++++-- 7 files changed, 92 insertions(+), 84 deletions(-) diff --git a/CardSurvival-Localization/CardSurvival-Localization.csproj b/CardSurvival-Localization/CardSurvival-Localization.csproj index 73bc85d..1e694d2 100644 --- a/CardSurvival-Localization/CardSurvival-Localization.csproj +++ b/CardSurvival-Localization/CardSurvival-Localization.csproj @@ -6,8 +6,8 @@ CardSurvival_Localization enable enable - 1.1.0 - 1.1.0 + 1.2.0 + 1.2.0 diff --git a/CardSurvival-Localization/LocalizationInfo.cs b/CardSurvival-Localization/LocalizationInfo.cs index ffdbe44..52717d9 100644 --- a/CardSurvival-Localization/LocalizationInfo.cs +++ b/CardSurvival-Localization/LocalizationInfo.cs @@ -15,6 +15,8 @@ public class LocalizationInfo public string JsonPath { get; set; } = ""; public string DefaultText { get; set; } = ""; public string LocalizationKey { get; set; } = ""; + + } public class LocalizationGroupCompare : IEqualityComparer diff --git a/CardSurvival-Localization/LocalizationKeyExtrator.cs b/CardSurvival-Localization/LocalizationKeyExtrator.cs index 19af1de..3588da3 100644 --- a/CardSurvival-Localization/LocalizationKeyExtrator.cs +++ b/CardSurvival-Localization/LocalizationKeyExtrator.cs @@ -3,8 +3,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -//using System.Text.Json; -//using System.Text.Json.Nodes; using System.IO; using System.ComponentModel.DataAnnotations; using System.Data; @@ -17,49 +15,13 @@ namespace CardSurvival_Localization public class LocalizationKeyExtrator { - //public List Extract(string json) - //{ - - // JsonDocument doc = JsonDocument.Parse(json); - - - // //Search for DefaultText != "" - // //Error if "LocalizationKey" == "" - - // //If object or array, search those. - - // foreach (JsonProperty item in doc.RootElement.EnumerateObject()) - // { - // if(item.Value.ValueKind == JsonValueKind.Object) - // { - // //sub iterator. - // } - // else if(item.Value.ValueKind == JsonValueKind.String) - // { - - // } - // else if (item.Value.ValueKind == JsonValueKind.Array) - // { - - // } - - // } - - // throw new NotImplementedException(); - //} - - public List Extract(string json) { - //JsonDocument doc = JsonDocument.Parse(json); - - List localizationEntries = new(); JObject doc = JObject.Parse(json); - //IEnumerable match = doc.SelectTokens("$..[?(@.DefaultText.length>0)]"); IEnumerable match = doc.SelectTokens(@"$..[?(@.DefaultText!='')]"); foreach (JToken token in match) diff --git a/CardSurvival-Localization/Program.cs b/CardSurvival-Localization/Program.cs index 0ca704f..7f4ad9d 100644 --- a/CardSurvival-Localization/Program.cs +++ b/CardSurvival-Localization/Program.cs @@ -30,7 +30,7 @@ static void Main(string[] args) { List result = localizationKeyExtrator.Extract(File.ReadAllText(file)); - localizationInfos.ForEach(x => x.FileName = file); + result.ForEach(x => x.FileName = file); localizationInfos.AddRange(result); } @@ -42,54 +42,64 @@ static void Main(string[] args) // Note - Keys are case insensitive. Currently CSTI-ModLoader is case sensitive. List> groupedInfo = localizationInfos .Distinct(new LocalizationGroupCompare()) - .OrderBy(x=> x.LocalizationKey) - .ThenBy(x=> x.DefaultText) + .OrderBy(x => x.LocalizationKey) + .ThenBy(x => x.DefaultText) .GroupBy(x => x.LocalizationKey) - .OrderBy(x=> x.Key) + .OrderBy(x => x.Key) .ToList(); - //---- Output warnings to stderr - var multiDefinedInfo = groupedInfo.Where(x => x.Count() > 1); + bool isConsole = args.Length < 2; - if(multiDefinedInfo.Count() > 0) + TextWriter outputWriter = isConsole ? Console.Out : new StreamWriter(args[1]); + using (outputWriter) { - Console.Error.WriteLine("Error: Multiple keys exist with different text"); - foreach (var multiGroup in multiDefinedInfo) - { - Console.Error.WriteLine($"Key: \"{multiGroup.Key}\""); + //---- Output warnings to stderr + WriteErrors(outputWriter, groupedInfo); - foreach (var info in multiGroup) + //---- Write to output + using (CsvWriter csvWriter = new CsvWriter(outputWriter, CultureInfo.InvariantCulture)) + { + foreach (var item in groupedInfo.SelectMany(x => x.ToList())) { - Console.Error.WriteLine($"\t{info.DefaultText}"); + //The game's example SimpCn.csv shows new lines to be escaped. + string encodedText = item.DefaultText.Replace("\n", "\\n"); + + csvWriter.WriteField(item.LocalizationKey); + csvWriter.WriteField(""); + csvWriter.WriteField(encodedText); + + csvWriter.NextRecord(); } } - - Console.Error.WriteLine("-----"); - Console.Error.WriteLine(); } + } - //---- Write to output - bool isConsole = args.Length < 2; - - TextWriter outputWriter = isConsole ? Console.Out : new StreamWriter(args[1]); + private static void WriteErrors(TextWriter output, List> groupedInfo) + { + var multiDefinedInfo = groupedInfo.Where(x => x.Count() > 1); - using (outputWriter) - using (CsvWriter csvWriter = new CsvWriter(outputWriter, CultureInfo.InvariantCulture)) + if (multiDefinedInfo.Count() > 0) { - foreach (var item in groupedInfo.SelectMany(x=> x.ToList())) + + output.WriteLine("Error: Multiple keys exist with different text"); + + foreach (var multiGroup in multiDefinedInfo) { - //CsvHelper.CsvWriter csvWriter = new CsvWriter() - string result = string.Join(',', item.LocalizationKey, "", item.DefaultText); + output.WriteLine($"Key: \"{multiGroup.Key}\""); - csvWriter.WriteField(item.LocalizationKey); - csvWriter.WriteField(""); - csvWriter.WriteField(item.DefaultText); + foreach (var info in multiGroup) + { + output.WriteLine($"\tText: {info.DefaultText}"); + output.WriteLine($"\tFile: {info.FileName}"); + output.WriteLine($"\tJSON Path: {info.JsonPath }"); + output.WriteLine(); - csvWriter.NextRecord(); + } } + + output.WriteLine("-----"); } } - } } \ No newline at end of file diff --git a/CardSurvival-Localization/TestData/Test.json b/CardSurvival-Localization/TestData/Test.json index fde9bac..07e8a4d 100644 --- a/CardSurvival-Localization/TestData/Test.json +++ b/CardSurvival-Localization/TestData/Test.json @@ -12,16 +12,16 @@ "LocalizationKey": "test_key", "ParentObjectID": "577682ed932c11ed892404ea56599bd2", "subTest": { - "DefaultText": " \"quoted test\"", + "DefaultText": "some \"text\"", "LocalizationKey": "test_key" }, "subTest1": { - "DefaultText": "duplicate test", - "LocalizationKey": "dupe_test" + "DefaultText": "exact duplicate test", + "LocalizationKey": "exact_dupe_test" }, "subTest3": { - "DefaultText": "duplicate test", - "LocalizationKey": "dupe_test2" + "DefaultText": "exact duplicate test", + "LocalizationKey": "exact_dupe_test" } diff --git a/Package.ps1 b/Package.ps1 index c2ba137..a266b58 100644 --- a/Package.ps1 +++ b/Package.ps1 @@ -1,5 +1,5 @@ -dotnet publish +dotnet publish -c Release # Get the file name from the C# project name $ProjectName = "CardSurvival-Localization" -Compress-Archive -Path "./CardSurvival-Localization/bin/Debug/net6.0/publish/*" -Force -DestinationPath ./$ProjectName.zip +Compress-Archive -Path "./CardSurvival-Localization/bin/Release/net6.0/publish*" -Force -DestinationPath ./$ProjectName.zip diff --git a/README.md b/README.md index 2e8d76e..f07af09 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Useful for creating an English translation for Chinese ModLoader mods that do no https://www.nexusmods.com/cardsurvivaltropicalisland/mods/23 -https://github.com/dop-lm/CSTI-ModLoader (Out of date. 2.0.1b was released on NexusMods on 3/28/2023, but the repository doesn't currently reflect the change) +https://github.com/dop-lm/CSTI-ModLoader (Out of date. 2.0.1c was released on NexusMods on 3/28/2023, but the repository doesn't currently reflect the change) # Operation @@ -16,31 +16,58 @@ The utility goes through every .json file in a ModLoader based mod's folder and The output is a CSV in the same format as SimpCn.csv The result can be exported to the console or a file. -If there are any errors or warnings, they would be outputted to stderr. For example, multiple entries of the same key with different text. +If there are any errors or warnings, they would be added to the start of the output. For example, multiple entries of the same key with different text. # Usage: Run the exe, passing in the folder with *.json at the end. For example: + Assuming the target mod is located at `E:\Mods\Apocalypse-43-1-39-1679945367` and is not in zip format. `CardSurvival-Localization.exe "E:\Mods\Apocalypse-43-1-39-1679945367\*.json" "c:\work\SimpCn.csv"` +## Example Output: + +``` +Error: Multiple keys exist with different text +Key: "test_key" + Text: some "text" + File: <..>\TestData\Test.json + JSON Path: DefaultStatusName.Description.subTest + + Text: test + File: <..>\TestData\Test.json + JSON Path: DefaultStatusName.Description + +----- +exact_dupe_test,,exact duplicate test +Gs_Hail_IceCool_Descriptions,,冰爽的感觉 +test_key,,"some ""text""" +test_key,,test + +``` + + |Arguments|Description| |--|--| -|File Pattern|Use the full path with *.json at the end. For example: "SomeModLoaderMod\\\*.json"| +|File Pattern|Use the full path with a search pattern at the end *.json at the end. For example: "SomeModLoaderMod\\\*.json"| |Output File|If not provided, will output to the console. Otherwise will write to the path specified| # Output: -Creates a CSV output text file with the following columns: +Creates a CSV output text file with the following: + -Localization Key +Any errors +---- + +The data in CSV format: +Localization Key Empty The DefaultText for that key. +If the output is showing unicode characters as ?'s, supply a file name as the second parameter. -## Example: -Bp_Hail_IceCoolBall.LogText,,冰晶球完成了 ## Translation An easy way to translate is using Google Sheets with the translate function. @@ -48,6 +75,13 @@ For example, translating Chinese to English: `=GOOGLETRANSLATE(C1,"zh","en")` # Version +## 1.2.0 +* Moved errors to output instead of stderr +* Added File Name and JSON path to errors +* Moved some code to a function +* Escapes new lines as \n in the text. +* Fixed packaging not using Release build + ## 1.1.0 * Added CSV encoding * Remove duplicates based on key/text