+EA 23.306 Nightly - Plugin.BaseCore โ
May 14, 2026
7 files modified.
Important Changes โ
None.
ExcelParser โ
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NPOI.SS.UserModel;
using UnityEngine;cs
public static IRow rowDefault;
public static IRow rowHeader;
public static bool IsNull(ICell cell)
{
if (cell != null && cell.CellType != CellType.Blank)public static int GetInt(int id)
cs
}
if (!int.TryParse(str, out var result))
{
if (float.TryParse(str, out var result2))
{
return (int)result2;
}
ReportIllFormat<int>(id);
}
return result;public static int[] GetIntArray(int id)
cs
{
if (!int.TryParse(array[i], out array2[i]))
{
if (float.TryParse(array[i], out var result))
{
array2[i] = (int)result;
continue;
}
ReportIllFormat<int>(id);
array2[i] = 0;
}public static void ReportIllFormat<T>(int id)
cs
ICell cell = row?.Cells.TryGet(id, returnNull: true);
IRow obj = row;
string value = ((obj != null && obj.RowNum >= 3) ? $", default:'{rowDefault?.Cells.TryGet(id, returnNull: true)}'" : ", SourceData begins at the 4th row. 3rd row is the default value row.");
stringBuilder.AppendLine("$source ill-format file: " + path);
stringBuilder.AppendLine("#source ill-format file: " + path);
object[] array = new object[5];
IRow obj2 = row;
array[0] = ((obj2 != null) ? new int?(obj2.RowNum + 1) : null);public static void ReportIllFormat<T>(int id)
cs
array[2] = ToLetterId(id);
array[3] = name;
array[4] = cell;
stringBuilder.Append(string.Format("row#{0}, cell'{1}'/'{2}', expected:'{3}', read:'{4}'", array));
stringBuilder.Append(string.Format("row#{0}, cell#{1}/#{2}, expected:'{3}', read:'{4}'", array));
stringBuilder.AppendLine(value);
Debug.LogError(stringBuilder);
Debug.LogWarning(stringBuilder);
}
public static string GetRowHeaderDiff(IReadOnlyDictionary<string, int> mapping, IReadOnlyDictionary<string, int> header)
{
StringBuilder stringBuilder = new StringBuilder();
List<KeyValuePair<string, int>> list = mapping.OrderBy((KeyValuePair<string, int> c) => c.Value).ToList();
int num = list.Max((KeyValuePair<string, int> c) => c.Key.Length);
foreach (KeyValuePair<string, int> item in list)
{
item.Deconstruct(out var key, out var value);
string text = key;
int index = value;
int value2;
bool num2 = header.TryGetValue(text, out value2);
string text2 = ((num2 && value2 != index) ? $"maybe {value2 + 1,2}/{ToLetterId(value2)} {text}" : "");
if (!num2)
{
text2 = "<missing>";
}
string text3 = header.FirstOrDefault((KeyValuePair<string, int> c) => c.Value == index).Key ?? "<missing>";
text3 = text3.PadRight(num + 3);
string text4 = text.PadRight(num);
stringBuilder.AppendLine($"{index + 1,2}/{ToLetterId(index),2}: {text4} -> {text3} {text2}");
}
return stringBuilder.ToString();
}
public static void ClearStaticRows()
{
row = null;
rowDefault = null;
rowHeader = null;
}
}LangGame โ
cs
using System;
using System.Collections.Generic;
public class LangGame : SourceLang<LangGame.Row>
{cs
public override string GetAlias => "n";
}
public static readonly IReadOnlyDictionary<string, int> RowMapping = new Dictionary<string, int>
{
["id"] = 0,
["filter"] = 1,
["group"] = 2,
["color"] = 3,
["logColor"] = 4,
["sound"] = 5,
["effect"] = 6,
["text_JP"] = 7,
["text"] = 8
};
public override Row CreateRow()
{
return new Rowpublic override Row CreateRow()
cs
};
}
public override Row CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return new Row
{
id = SourceData.GetString(mapping["id"]),
filter = SourceData.GetString(mapping["filter"]),
group = SourceData.GetString(mapping["group"]),
color = SourceData.GetString(mapping["color"]),
logColor = SourceData.GetString(mapping["logColor"]),
sound = SourceData.GetString(mapping["sound"]),
effect = SourceData.GetString(mapping["effect"]),
text_JP = SourceData.GetString(mapping["text_JP"]),
text = SourceData.GetString(mapping["text"])
};
}
public override void SetRow(Row r)
{
map[r.id] = r;
}
public override IReadOnlyDictionary<string, int> GetRowMapping()
{
return RowMapping;
}
public static bool Has(string id)
{
return Lang.Game.map.ContainsKey(id);LangGeneral โ
cs
using System;
using System.Collections.Generic;
public class LangGeneral : SourceLang<LangGeneral.Row>
{cs
public override string GetAlias => "n";
}
public static readonly IReadOnlyDictionary<string, int> RowMapping = new Dictionary<string, int>
{
["id"] = 0,
["filter"] = 1,
["text_JP"] = 2,
["text"] = 3
};
public override Row CreateRow()
{
return new Rowpublic override Row CreateRow()
cs
};
}
public override Row CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return new Row
{
id = SourceData.GetString(mapping["id"]),
filter = SourceData.GetString(mapping["filter"]),
text_JP = SourceData.GetString(mapping["text_JP"]),
text = SourceData.GetString(mapping["text"])
};
}
public override void SetRow(Row r)
{
map[r.id] = r;
}
public override IReadOnlyDictionary<string, int> GetRowMapping()
{
return RowMapping;
}
}LangList โ
cs
using System;
using System.Collections.Generic;
public class LangList : SourceDataString<LangList.Row>
{cs
public override string GetAlias => "n";
}
public static readonly IReadOnlyDictionary<string, int> RowMapping = new Dictionary<string, int>
{
["id"] = 0,
["filter"] = 1,
["text_JP"] = 2,
["text"] = 3
};
public override bool AllowHotInitialization => true;
public override Row CreateRow()public override Row CreateRow()
cs
};
}
public override Row CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return new Row
{
id = SourceData.GetString(mapping["id"]),
filter = SourceData.GetString(mapping["filter"]),
text_JP = SourceData.GetStringArray(mapping["text_JP"]),
text = SourceData.GetStringArray(mapping["text"])
};
}
public override void SetRow(Row r)
{
map[r.id] = r;
}
public override IReadOnlyDictionary<string, int> GetRowMapping()
{
return RowMapping;
}
public override string[] GetList(string id)
{
Row row = map.TryGetValue(id);LangNote โ
cs
using System;
using System.Collections.Generic;
public class LangNote : SourceDataString<LangNote.Row>
{cs
public override string GetAlias => "n";
}
public static readonly IReadOnlyDictionary<string, int> RowMapping = new Dictionary<string, int>
{
["id"] = 0,
["text_JP"] = 1,
["text"] = 2
};
public override bool AllowHotInitialization => true;
public override Row CreateRow()public override Row CreateRow()
cs
};
}
public override Row CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return new Row
{
id = SourceData.GetString(mapping["id"]),
text_JP = SourceData.GetString(mapping["text_JP"]),
text = SourceData.GetString(mapping["text"])
};
}
public override void SetRow(Row r)
{
map[r.id] = r;
}
public override IReadOnlyDictionary<string, int> GetRowMapping()
{
return RowMapping;
}
}LangWord โ
cs
using System;
using System.Collections.Generic;
public class LangWord : SourceDataInt<LangWord.Row>
{cs
public override string GetAlias => "n";
}
public static readonly IReadOnlyDictionary<string, int> RowMapping = new Dictionary<string, int>
{
["id"] = 0,
["group"] = 1,
["name_JP"] = 2,
["name"] = 3
};
public override bool AllowHotInitialization => true;
public override Row CreateRow()public override Row CreateRow()
cs
};
}
public override Row CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return new Row
{
id = SourceData.GetInt(mapping["id"]),
group = SourceData.GetString(mapping["group"]),
name_JP = SourceData.GetString(mapping["name_JP"]),
name = SourceData.GetString(mapping["name"])
};
}
public override void SetRow(Row r)
{
map[r.id] = r;
}
public override IReadOnlyDictionary<string, int> GetRowMapping()
{
return RowMapping;
}
public override void OnAfterImportData()
{
int num = 0;SourceData โ
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using NPOI.SS.UserModel;
using NPOI.SS.Util;public override bool ImportData(ISheet sheet, string bookname, bool overwrite =
cs
isNew = true;
nameSheet = sheet.SheetName;
nameBook = bookname;
SourceData.rowHeader = sheet.GetRow(0);
SourceData.rowDefault = sheet.GetRow(2);
IReadOnlyDictionary<string, int> rowMapping = GetRowMapping();
Dictionary<string, int> dictionary = null;
if (rowMapping != null)
{
dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
foreach (ICell item in SourceData.rowHeader.Cells.Where((ICell c) => c.ToString() != "0" && !c.ToString().IsEmpty()))
{
dictionary[item.ToString().Trim()] = item.ColumnIndex;
}
if (!rowMapping.Keys.All(dictionary.ContainsKey) || rowMapping.Count > dictionary.Count)
{
string[] array = rowMapping.Keys.Except(dictionary.Keys).ToArray();
if (array.Length != 0)
{
Debug.LogWarning("#source ill-format file with missing columns, init with empty values\n" + ExcelParser.GetRowHeaderDiff(rowMapping, dictionary));
string[] array2 = array;
foreach (string text in array2)
{
SourceData.rowHeader.CreateCell(276, CellType.String).SetCellValue(text);
dictionary[text] = 276;
}
}
else
{
Debug.Log("#source ill-format file with reordered columns");
}
}
else
{
dictionary = null;
}
}
int num = 0;
for (int i = 3; i <= sheet.LastRowNum; i++)
for (int j = 3; j <= sheet.LastRowNum; j++)
{
SourceData.row = sheet.GetRow(i);
if (SourceData.row == null || SourceData.row.GetCell(0) == null || SourceData.row.GetCell(0).ToString().IsEmpty())
SourceData.row = sheet.GetRow(j);
if (string.IsNullOrEmpty(SourceData.row?.GetCell(0)?.ToString()))
{
break;
}
T val = CreateRow();
T val = ((dictionary != null) ? CreateRowByMapping(dictionary) : CreateRow());
val.OnImportData(this);
rows.Add(val);
num++;
}
string text = sheet.SheetName + "/" + sheet.LastRowNum + "/" + num;
Debug.Log(text);
ERROR.msg = text;
string text2 = sheet.SheetName + "/" + sheet.LastRowNum + "/" + num;
Debug.Log(text2);
ERROR.msg = text2;
OnAfterImportData();
initialized = false;
return true;cs
return null;
}
public virtual T CreateRowByMapping(IReadOnlyDictionary<string, int> mapping)
{
return null;
}
public override int ImportRows(IEnumerable<BaseRow> sourceRows)
{
int num = 0;cs
}
}
public static IRow rowHeader
{
get
{
return ExcelParser.rowHeader;
}
set
{
ExcelParser.rowHeader = value;
}
}
public void BuildFlags(string rawText, Dictionary<string, bool> map)
{
if (!string.IsNullOrEmpty(rawText))public virtual void ValidateLang()
cs
{
}
public virtual IReadOnlyDictionary<string, int> GetRowMapping()
{
return null;
}
public static bool IsNull(ICell cell)
{
if (cell != null && cell.CellType != CellType.Blank)