diff --git a/CardSurvival-Localization/CardSurvival-Localization.csproj b/CardSurvival-Localization/CardSurvival-Localization.csproj
index 1e694d2..7f80554 100644
--- a/CardSurvival-Localization/CardSurvival-Localization.csproj
+++ b/CardSurvival-Localization/CardSurvival-Localization.csproj
@@ -6,8 +6,8 @@
CardSurvival_Localization
enable
enable
- 1.2.0
- 1.2.0
+ 2.0.0
+ 2.0.0
diff --git a/CardSurvival-Localization/Program.cs b/CardSurvival-Localization/Program.cs
index 7f4ad9d..7e367a4 100644
--- a/CardSurvival-Localization/Program.cs
+++ b/CardSurvival-Localization/Program.cs
@@ -4,78 +4,119 @@
using CsvHelper;
using CsvHelper.Configuration;
+
namespace CardSurvival_Localization
{
internal class Program
{
- static void Main(string[] args)
+ static int Main(string[] args)
{
- if (args.Length < 1)
+ try
{
+ if (ShowUsage(args))
+ {
+ return -2;
+ }
- Console.Error.WriteLine("Must be at least 1 argument: SearchPath [OutputFile]");
- return;
- }
- Utilities.ThrowIfNull(args[0]);
+ string sourceDirectory;
- //---Extract info from .json files
- string[] files = Directory.GetFiles(Path.GetDirectoryName(args[0])!, Path.GetFileName(args[0])!, SearchOption.AllDirectories);
+ if (!Directory.Exists(args[0]))
+ {
+ throw new ArgumentException($"Mod Directory does not exist: {args[0]}");
+ }
- LocalizationKeyExtrator localizationKeyExtrator = new();
- List localizationInfos = new();
+ Console.WriteLine("Processing...");
- foreach (string file in files)
- {
- List result = localizationKeyExtrator.Extract(File.ReadAllText(file));
+ sourceDirectory = args[0];
- result.ForEach(x => x.FileName = file);
- localizationInfos.AddRange(result);
- }
+ //---Extract info from .json files
+ string[] files = Directory.GetFiles(sourceDirectory, "*.json", SearchOption.AllDirectories);
+ LocalizationKeyExtrator localizationKeyExtrator = new();
+ List localizationInfos = new();
- //---- Remove exact duplicates
+ foreach (string file in files)
+ {
+ List result = localizationKeyExtrator.Extract(File.ReadAllText(file));
- //Remove exact key/text (case insensitive) duplicates.
- //Group by items that have more than one text for the same key.
- // 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)
- .GroupBy(x => x.LocalizationKey)
- .OrderBy(x => x.Key)
- .ToList();
+ result.ForEach(x => x.FileName = file);
+ localizationInfos.AddRange(result);
+ }
- bool isConsole = args.Length < 2;
+ //---- Remove exact duplicates
- TextWriter outputWriter = isConsole ? Console.Out : new StreamWriter(args[1]);
- using (outputWriter)
- {
+ //Remove exact key/text (case insensitive) duplicates.
+ //Group by items that have more than one text for the same key.
+ // 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)
+ .GroupBy(x => x.LocalizationKey)
+ .OrderBy(x => x.Key)
+ .ToList();
+
+ //---Write Output Errors to file.
+
+ StringWriter sw = new StringWriter();
+ GetErrorText(sw, groupedInfo);
+
+ string errors = sw.ToString();
- //---- Output warnings to stderr
- WriteErrors(outputWriter, groupedInfo);
+ const string errorFileName = "SimpEn_Errors.txt";
- //---- Write to output
- using (CsvWriter csvWriter = new CsvWriter(outputWriter, CultureInfo.InvariantCulture))
+ if (errors.Length >0)
{
- foreach (var item in groupedInfo.SelectMany(x => x.ToList()))
+ File.WriteAllText(errorFileName ,errors);
+ Console.WriteLine($"One or more translation errors occurred. See {errorFileName}");
+ }
+
+ const string localizationFilePath = "SimpEn.csv";
+
+ using (var outputWriter = new StreamWriter(localizationFilePath))
+ {
+ //---- Write to output
+ using (CsvWriter csvWriter = new CsvWriter(outputWriter, CultureInfo.InvariantCulture))
{
- //The game's example SimpCn.csv shows new lines to be escaped.
- string encodedText = item.DefaultText.Replace("\n", "\\n");
+ foreach (var item in groupedInfo.SelectMany(x => x.ToList()))
+ {
+ //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.WriteField(item.LocalizationKey);
+ csvWriter.WriteField("");
+ csvWriter.WriteField(encodedText);
- csvWriter.NextRecord();
+ csvWriter.NextRecord();
+ }
}
}
+
+ Console.WriteLine("Translation Completed.");
+
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error: {ex.Message}");
+ return -1;
}
}
- private static void WriteErrors(TextWriter output, List> groupedInfo)
+ private static bool ShowUsage(string[] args)
+ {
+ if(args.Length != 1 || args[0].Trim() == "-h" || args[0].Trim() == "/?" || args[0].Trim() == "--help")
+ {
+ Console.WriteLine("Usage: CardSurvival-Localization ");
+ Console.WriteLine();
+ return true;
+ }
+
+ return false;
+ }
+ private static void GetErrorText(TextWriter output, List> groupedInfo)
{
var multiDefinedInfo = groupedInfo.Where(x => x.Count() > 1);
diff --git a/CardSurvival-Localization/Properties/launchSettings.json b/CardSurvival-Localization/Properties/launchSettings.json
index f8846b5..322aa98 100644
--- a/CardSurvival-Localization/Properties/launchSettings.json
+++ b/CardSurvival-Localization/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"CardSurvival-Localization": {
"commandName": "Project",
- "commandLineArgs": "$(ProjectDir)TestData/Test.json"
+ "commandLineArgs": "$(ProjectDir)TestData/"
}
}
}
\ No newline at end of file
diff --git a/CardSurvival-Localization/TestData/Test.json b/CardSurvival-Localization/TestData/Test.json
index 07e8a4d..549931e 100644
--- a/CardSurvival-Localization/TestData/Test.json
+++ b/CardSurvival-Localization/TestData/Test.json
@@ -9,7 +9,7 @@
},
"Description": {
"DefaultText": "test",
- "LocalizationKey": "test_key",
+ "LocalizationKey": "test_key1",
"ParentObjectID": "577682ed932c11ed892404ea56599bd2",
"subTest": {
"DefaultText": "some \"text\"",
diff --git a/README.md b/README.md
index 97a31d3..2c731b6 100644
--- a/README.md
+++ b/README.md
@@ -22,16 +22,17 @@ This mod parses all the .json files and extracts the card translation key and re
To translate a mod based on CSTI-ModLoader to English, the process is as follows:
* Run the tool, pointing to the mod's folder.
- * Example: `CardSurvival-Localization.exe "E:\Mods\Apocalypse-43-1-39-1679945367\*.json" ".\SimpEn.csv"`
+ * Example: `CardSurvival-Localization.exe "E:\Mods\Apocalypse-43-1-39-1679945367\`
+ * If there are errors, there will be a file named SimpEn_Errors.txt.
* Translate the SimpEnv.csv output file manually or with a translator such as translate.google.com or DeepL.com.
* Put the text translated from the third column into the second column.
-* Fix any errors listed at the top of the output.
-* Remove the error info at the top of the file.
-* Copy the file into the Mod's Localization folder as SimpEn.csv.
+* Fix any errors listed in the SimpEn_Errors.txt file.
+* Copy the SimpEn.csv into the Mod's Localization folder.
## Example Output
### Output From Tool
+SimpEn_Errors.txt
```
Error: Multiple keys exist with different text
Key: "Bp_ConservatoriesNc_CardDescription"
@@ -42,8 +43,10 @@ Key: "Bp_ConservatoriesNc_CardDescription"
Text: 保护植物并加速生长
File: .\example.json
JSON Path: CardDescription2
+```
------
+SimpEn.csv
+```
Bp_ConservatoriesNc_CardDescription,,为植物生长提供一个温馨的家园。
Bp_ConservatoriesNc_CardDescription,,保护植物并加速生长
Bp_ConservatoriesNc_Two_CardName,,二号温室
@@ -59,12 +62,12 @@ Bp_ConservatoriesNc_Two_CardName,Greenhouse No. 2,二号温室
# Spreadsheet Recommended Workflow
My recommendation would be to do as follows:
* Run the tool to create the SimpEn.csv output.
-* Import the CSV part of the document into Excel or Google Sheets, excluding any errors at the top of the output.
+* Import the CSV part of the document into Excel or Google Sheets.
* Copy the entirety of the third column (which will be in Chinese) and run it through a translator like translate.google.com or deepl.com.
* Alternatively, Google Sheets has a function called GoogleTranslate that can translate text in the spreadsheet. For example Chinese to English is `=GOOGLETRANSLATE(C1,"zh","en")`.
* Paste those results into the spreadsheet's second column.
* Save the spreadsheet as SimpEn.csv.
-* With the newly created SimpEn.csv file, fix any errors that were listed at the top of the original output.
+* With the newly created SimpEn.csv file, if there is an SimpEn_Error.txt file, fix any errors indicated in that file.
* Copy the SimpEn.csv file to the Mod's Localization directory.
When starting the game, the Mod's text should now reflect the translated text.
@@ -80,8 +83,7 @@ A couple of things I've noticed in the current mods.
# Command Line Parameters
|Arguments|Description|
|--|--|
-|File Pattern|The full path to the mod with *.json at the end. For example: "SomeModLoaderMod\\\*.json"|
-|Output File|If not provided, will output to the console. Otherwise, it will write to the path specified. It is recommended to use this argument since the console can corrupt Chinese characters.|
+|File Pattern|The full path to the mod|
## Source and Releases for this Utility
https://github.com/NBKRedSpy/CardSurvival-Localization
@@ -95,6 +97,15 @@ https://github.com/dop-lm/CSTI-ModLoader (Currently the NoReflection branch has
# Version
+## 2.0.0
+
+### Upgrade Notes
+For users that have used a previous version of the app, the arguments have changed. The application now only requires the path to the target mod and will automatically create a SimpEx.csv and SimpEx_Errors.txt in the current working directory.
+### Changes
+* Changed arguments to only require path.
+* Changed to output errors to SimpEn_Errors.txt instead of in the translated file.
+* Removed second parameter. Now always exports to SimpEn.csv in the current working folder.
+
## 1.2.0
* Moved errors to output instead of stderr.
* Added File Name and JSON path to errors.