Skip to content

Commit

Permalink
JSON changes, error changes, refactor
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
NBKRedSpy committed Mar 29, 2023
1 parent 34c7eb4 commit a0c8925
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 84 deletions.
4 changes: 2 additions & 2 deletions CardSurvival-Localization/CardSurvival-Localization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<RootNamespace>CardSurvival_Localization</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<FileVersion>1.1.0</FileVersion>
<AssemblyVersion>1.1.0</AssemblyVersion>
<FileVersion>1.2.0</FileVersion>
<AssemblyVersion>1.2.0</AssemblyVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions CardSurvival-Localization/LocalizationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<LocalizationInfo>
Expand Down
38 changes: 0 additions & 38 deletions CardSurvival-Localization/LocalizationKeyExtrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -17,49 +15,13 @@ namespace CardSurvival_Localization
public class LocalizationKeyExtrator
{

//public List<LocalizationInfo> 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<LocalizationInfo> Extract(string json)
{
//JsonDocument doc = JsonDocument.Parse(json);


List<LocalizationInfo> localizationEntries = new();


JObject doc = JObject.Parse(json);

//IEnumerable<JToken> match = doc.SelectTokens("$..[?(@.DefaultText.length>0)]");
IEnumerable<JToken> match = doc.SelectTokens(@"$..[?(@.DefaultText!='')]");

foreach (JToken token in match)
Expand Down
70 changes: 40 additions & 30 deletions CardSurvival-Localization/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static void Main(string[] args)
{
List<LocalizationInfo> result = localizationKeyExtrator.Extract(File.ReadAllText(file));

localizationInfos.ForEach(x => x.FileName = file);
result.ForEach(x => x.FileName = file);
localizationInfos.AddRange(result);
}

Expand All @@ -42,54 +42,64 @@ static void Main(string[] args)
// Note - Keys are case insensitive. Currently CSTI-ModLoader is case sensitive.
List<IGrouping<string, LocalizationInfo>> 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<IGrouping<string, LocalizationInfo>> 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("-----");
}
}

}
}
10 changes: 5 additions & 5 deletions CardSurvival-Localization/TestData/Test.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}


Expand Down
4 changes: 2 additions & 2 deletions Package.ps1
Original file line number Diff line number Diff line change
@@ -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
48 changes: 41 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,80 @@ 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
The utility goes through every .json file in a ModLoader based mod's folder and extracts every DefaultText and related LocalizationKey.
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.
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
Expand Down

0 comments on commit a0c8925

Please sign in to comment.