feat: handle all of auto-translate

This commit is contained in:
Anna 2021-11-17 15:30:07 -05:00
parent 73e15f2b93
commit a45482cb0c
5 changed files with 17540 additions and 20 deletions

View File

@ -0,0 +1,85 @@
using System.Collections.Generic;
using Pidgin;
using static Pidgin.Parser;
using static Pidgin.Parser<char>;
namespace SourceGenerator {
internal static class AutoTranslate {
internal static Parser<char, (string name, Maybe<IEnumerable<ISelectorPart>> selector)> Parser() {
var sheetName = Any
.AtLeastOnceUntil(Lookahead(Char('[').IgnoreResult().Or(End)))
.Select(string.Concat)
.Labelled("sheetName");
var numPair = Map(
(first, second) => (ISelectorPart) new IndexRange(
uint.Parse(string.Concat(first)),
uint.Parse(string.Concat(second))
),
Digit.AtLeastOnce().Before(Char('-')),
Digit.AtLeastOnce()
)
.Labelled("numPair");
var singleRow = Digit
.AtLeastOnce()
.Select(string.Concat)
.Select(num => (ISelectorPart) new SingleRow(uint.Parse(num)));
var column = String("col-")
.Then(Digit.AtLeastOnce())
.Select(string.Concat)
.Select(num => (ISelectorPart) new ColumnSpecifier(uint.Parse(num)));
var noun = String("noun")
.Select(_ => (ISelectorPart) new NounMarker());
var selectorItems = OneOf(
Try(numPair),
singleRow,
column,
noun
)
.Separated(Char(','))
.Labelled("selectorItems");
var selector = selectorItems
.Between(Char('['), Char(']'))
.Labelled("selector");
return Map(
(name, selector) => (name, selector),
sheetName,
selector.Optional()
);
}
}
internal interface ISelectorPart {
}
internal class SingleRow : ISelectorPart {
public uint Row { get; }
public SingleRow(uint row) {
this.Row = row;
}
}
internal class IndexRange : ISelectorPart {
public uint Start { get; }
public uint End { get; }
public IndexRange(uint start, uint end) {
this.Start = start;
this.End = end;
}
}
internal class NounMarker : ISelectorPart {
}
internal class ColumnSpecifier : ISelectorPart {
public uint Column { get; }
public ColumnSpecifier(uint column) {
this.Column = column;
}
}
}

View File

@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Lumina;
using Lumina.Data;
using Lumina.Excel;
using Lumina.Excel.GeneratedSheets;
using Lumina.Text;
using Pidgin;
namespace SourceGenerator {
internal class Program {
@ -310,9 +312,100 @@ namespace SourceGenerator {
sb.Append("\nlazy_static::lazy_static! {\n");
sb.Append(" pub static ref AUTO_TRANSLATE: HashMap<(u32, u32), LocalisedText> = maplit::hashmap! {\n");
var parser = AutoTranslate.Parser();
foreach (var row in this.Data[Language.English].GetExcelSheet<Completion>()!) {
var lookup = row.LookupTable.TextValue();
if (lookup is not ("" or "@")) {
var (sheetName, selector) = parser.ParseOrThrow(lookup);
var sheetType = typeof(Completion)
.Assembly
.GetType($"Lumina.Excel.GeneratedSheets.{sheetName}")!;
var getSheet = this.Data[Language.English]
.GetType()
.GetMethod("GetExcelSheet", Type.EmptyTypes)!
.MakeGenericMethod(sheetType);
var sheets = this.Data.ToDictionary(
pair => pair.Key,
pair => {
var sheet = (ExcelSheetImpl) getSheet.Invoke(pair.Value, null)!;
return (sheet, sheet.EnumerateRowParsers().ToArray());
});
var columns = new List<int>();
var rows = new List<Range>();
if (selector.HasValue) {
columns.Clear();
rows.Clear();
foreach (var part in selector.Value) {
switch (part) {
case IndexRange range: {
var start = (int) range.Start;
var end = (int) (range.End + 1);
rows.Add(start..end);
break;
}
case SingleRow single: {
var idx = (int) single.Row;
rows.Add(idx..(idx + 1));
break;
}
case ColumnSpecifier col:
columns.Add((int) col.Column);
break;
}
}
}
if (columns.Count == 0) {
columns.Add(0);
}
if (rows.Count == 0) {
rows.Add(..);
}
var builder = new StringBuilder();
foreach (var range in rows) {
var validRows = sheets[Language.English]
.Item2
.Select(parser => parser.Row)
.ToArray();
for (var i = range.Start.Value; i < range.End.Value; i++) {
if (!validRows.Contains((uint) i)) {
continue;
}
builder.Clear();
builder.Append($" ({row.Group}, {i}) => LocalisedText {{\n");
var lines = 0;
foreach (var (lang, (_, parsers)) in sheets) {
// take the first column that works
foreach (var col in columns) {
var rowParser = parsers.FirstOrDefault(parser => parser.Row == i);
if (rowParser != null) {
var name = rowParser.ReadColumn<SeString>(col)!;
var text = name.TextValue().Replace("\"", "\\\"");
if (text.Length > 0) {
builder.Append($" {Languages[lang]}: \"{text}\",\n");
lines += 1;
break;
}
}
}
}
builder.Append(" },\n");
if (lines != 4) {
continue;
}
sb.Append(builder);
}
}
// TODO: do lookup
} else {
var text = this.GetLocalisedStruct<Completion>(row.RowId, row => row.Text, 8);

View File

@ -8,27 +8,28 @@ namespace SourceGenerator {
var payloads = str.Payloads
.Select(p => {
if (p is TextPayload text) {
return text.RawString;
return p.Data[0] == 0x03
? text.RawString[1..]
: text.RawString;
}
return p.Data.Length > 1 && p.Data[1] == 0x1F ? "-" : "";
if (p.Data.Length <= 1) {
return "";
}
if (p.Data[1] == 0x1F) {
return "-";
}
if (p.Data.Length > 2 && p.Data[1] == 0x20) {
var value = p.Data.Length > 4
? p.Data[3] - 1
: p.Data[2];
return ((char) (48 + value)).ToString();
}
return "";
});
// Produces:
// MainCommand[col-,1-36,41-42,44-44,56-62,64-70,72-82,84-99]
// TextCommand[col-,col-,1-31,33-211,213-321,323-455,459-611,613-629,632-632]
// TextCommand[col-,col-,1-31,33-211,213-321,323-455,459-611,613-629,632-632]
// Pet[,1-8,10-10,14-15,17-19]
// PetMirage[col-♥]
//
// foreach (var payload in str.Payloads) {
// if (payload is TextPayload) {
// continue;
// }
//
// if (payload.Data.Length > 1 && payload.Data[1] == 0x20) {
// Console.WriteLine(string.Join("", payloads));
// }
// }
return string.Join("", payloads);
}

View File

@ -7,8 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Lumina" Version="3.4.0" />
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
<PackageReference Include="Lumina" Version="3.4.1"/>
<PackageReference Include="Lumina.Excel" Version="5.50.0"/>
<PackageReference Include="Pidgin" Version="3.0.0"/>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff