2using System.Collections.Generic;
5using System.Reflection;
6using NPOI.SS.UserModel;
8using NPOI.XSSF.UserModel;
29 if (r.HasField<
string>(
id))
31 return r.GetField<
string>(
id);
33 if (r.HasField<
int>(
id))
35 return r.GetField<
int>(
id).ToString();
37 if (r.HasField<
string[]>(
id))
40 string[] field = r.GetField<
string[]>(
id);
43 string[] array = field;
44 foreach (
string text2
in array)
46 text = text + text2 +
",";
49 return text.TrimEnd(
',');
62 public List<T>
rows =
new List<T>();
64 public Dictionary<T2, T>
map =
new Dictionary<T2, T>();
66 public Dictionary<string, T>
alias =
new Dictionary<string, T>();
83 public override void Init()
85 Debug.Log(
"Initializing:" + base.name);
88 Debug.Log(
"#init Skipping sourceData.Init:" + base.name);
119 if (!Application.isPlaying)
121 BaseCore.resetRuntime =
true;
137 public override bool ImportData(ISheet sheet,
string bookname,
bool overwrite =
false)
141 rows =
new List<T>();
146 SourceData.rowHeader = sheet.GetRow(0);
147 SourceData.rowDefault = sheet.GetRow(2);
148 IRow
row = sheet.GetRow(3);
151 ERROR.lastImported = 0;
154 IReadOnlyDictionary<string, int> rowMapping =
GetRowMapping();
155 Dictionary<string, int> header =
null;
156 if (rowMapping !=
null)
158 header =
new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
161 string text = cell.ToString().Trim();
162 if (!(text ==
"0") && !text.IsEmpty())
164 header[text] = cell.ColumnIndex;
167 if (!rowMapping.All((KeyValuePair<string, int> kv) => header.TryGetValue(kv.Key, 0) == kv.Value))
169 string[] array = rowMapping.Keys.Except(header.Keys).ToArray();
170 if (array.Length != 0)
173 string[] array2 = array;
174 foreach (
string text2
in array2)
182 Debug.Log(
"#source ill-format file with reordered columns");
191 for (
int j = 3; j <= sheet.LastRowNum; j++)
193 SourceData.row = sheet.GetRow(j);
196 if (
string.IsNullOrEmpty(
SourceData.
row?.GetCell(0)?.ToString()))
201 val.OnImportData(
this);
206 catch (Exception arg)
208 Debug.LogError(
$"#source failed to create row#{j + 1}\n{arg}");
212 Debug.Log(sheet.SheetName +
"/" + sheet.LastRowNum +
"/" + num);
213 ERROR.lastImported = num;
238 public override int ImportRows(IEnumerable<BaseRow> sourceRows)
241 foreach (
BaseRow sourceRow
in sourceRows)
243 if (sourceRow is T val)
245 val.OnImportData(
this);
257 HashSet<T2> hashSet =
new HashSet<T2>();
258 List<T> list =
new List<T>(
rows.Count);
259 string arg = GetType().Name;
260 System.Reflection.FieldInfo field = typeof(T).GetField(
"id");
261 bool flag = typeof(
LangRow).IsAssignableFrom(typeof(T));
266 if (field.FieldType != typeof(T2))
268 Debug.LogError(
$"#source-override: {arg} id field mismatch {field.FieldType} != {typeof(T2)}");
270 for (
int num =
rows.Count - 1; num >= 0; num--)
273 T2 val2 = (T2)field.GetValue(val);
274 if (hashSet.Add(val2))
280 Debug.Log(
$"#source-override: {arg} {val2}");
283 if (
rows.Count != list.Count)
285 Debug.Log(
$"#source-override: {arg} total/{rows.Count} -> unique/{list.Count}");
320 List<FieldInfo> list =
new List<FieldInfo>();
322 AddField(
"id", 4096);
323 AddField(
"version", 4096);
324 AddField(
"filter", 4096);
325 AddField(
"name", 4096);
326 AddField(
"text", 4096);
327 AddField(
"detail", 4096);
328 AddField(
"description", 4096);
330 foreach (
string text
in importFields)
334 AddField(text, 4096);
338 void AddField(
string id,
int width)
340 bool flag =
id ==
"id" ||
id ==
"filter";
341 bool flag2 =
id ==
"version";
342 if (!(typeof(T).GetField(
id) ==
null) || flag2)
353 if (!(flag || flag2))
383 public override void ExportTexts(
string path,
bool update =
false)
387 XSSFWorkbook xSSFWorkbook =
new XSSFWorkbook();
396 ICellStyle cellStyle = xSSFWorkbook.CreateCellStyle();
397 cellStyle.FillForegroundColor = 44;
398 cellStyle.FillPattern = FillPattern.SolidForeground;
399 if (!
item.isStatic &&
item.id !=
"version")
401 GetCell(num, y).CellStyle = cellStyle;
407 foreach (T row4
in rows)
415 else if (item2.
id ==
"version")
423 currentSheet.SetAutoFilter(
new CellRangeAddress(1, 1, 0, fields.Count - 1));
426 Dictionary<string, int> dictionary =
new Dictionary<string, int>();
427 if (!File.Exists(path +
"_temp/" + text))
431 XSSFWorkbook xSSFWorkbook2;
432 using (FileStream @is = File.Open(path +
"_temp/" + text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
434 xSSFWorkbook2 =
new XSSFWorkbook((Stream)@is);
436 ISheet sheetAt = xSSFWorkbook2.GetSheetAt(0);
437 IRow
row = sheetAt.GetRow(0);
446 for (
int i = 0; i <
row.LastCellNum; i++)
448 string stringCellValue =
row.GetCell(i).StringCellValue;
449 if (stringCellValue.IsEmpty())
453 if (stringCellValue == item3.
id)
463 dictionary.Add(item3.
id, 0);
464 for (y = 2; y <= sheetAt.LastRowNum; y++)
466 IRow row2 = sheetAt.GetRow(y);
475 ICell cell = row2.GetCell(0);
480 string text2 = ((cell.CellType == CellType.Numeric) ? cell.NumericCellValue.ToString() : cell.StringCellValue);
496 ICell cell2 = row3.GetCell(0);
497 if (cell2 ==
null || cell2.StringCellValue != text2)
501 string text3 = row2.GetCell(num3)?.StringCellValue ??
"";
506 (row3.GetCell(item3.
column) ?? row3.CreateCell(item3.
column)).SetCellValue(text3);
507 if (item3.
id !=
"version")
509 ICell cell3 = row3.GetCell(item3.
column + 2);
510 ICell cell4 = row2.GetCell(num3 + 2);
515 if (cell4 ==
null || cell3.StringCellValue != cell4.StringCellValue)
517 row3.GetCell(1).SetCellValue(cellValue);
521 dictionary[item3.
id]++;
525 Log.system = Log.system + ((num2 == 0) ?
"(No Changes) " :
"(Updated) ") + path +
"/" + text + Environment.NewLine;
528 foreach (KeyValuePair<string, int> item4
in dictionary)
530 Log.system = Log.system + item4.Key +
":" + item4.Value +
" ";
532 Log.system += Environment.NewLine;
534 Log.system += Environment.NewLine;
536 if (!Directory.Exists(path))
538 Directory.CreateDirectory(path);
540 using FileStream stream =
new FileStream(path +
"/" + text, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
541 xSSFWorkbook.Write(stream);
548 Log.system = Log.system + langImportMod + text + Environment.NewLine;
549 Log.system += Environment.NewLine;
555 string text = _nameSheet.IsEmpty(
nameSheet) +
".xlsx";
556 if (!File.Exists(langImportMod + text))
560 XSSFWorkbook xSSFWorkbook;
561 using (FileStream @is = File.Open(langImportMod + text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
563 xSSFWorkbook =
new XSSFWorkbook((Stream)@is);
565 ISheet sheetAt = xSSFWorkbook.GetSheetAt(0);
567 IRow
row = sheetAt.GetRow(0);
568 List<FieldMap> list =
new List<FieldMap>();
575 for (
int i = 0; i <
row.LastCellNum; i++)
577 string stringCellValue =
row.GetCell(i).StringCellValue;
578 if (stringCellValue.IsEmpty())
582 if (stringCellValue ==
item.id)
593 for (
int j = 2; j <= sheetAt.LastRowNum; j++)
595 IRow row2 = sheetAt.GetRow(j);
596 T val =
GetRow(row2.GetCell(0).StringCellValue);
599 Debug.Log(sheetAt.SheetName +
": id to import no longer exist: " + row2.GetCell(0).StringCellValue);
605 System.Reflection.FieldInfo field2 = val.GetType().GetField(field.
id +
"_L");
610 if (typeof(
string[]).IsAssignableFrom(field2.FieldType))
612 ICell cell = row2.GetCell(item2.
column);
613 string[] array = ((cell ==
null) ?
new string[0] : cell.StringCellValue.Split(
','));
614 string[] field3 = val.GetField<
string[]>(field.
id);
617 field2.SetValue(val, (array.Length >= field3.Length) ? array : field3);
622 ICell cell2 = row2.GetCell(item2.
column);
625 field2.SetValue(val, cell2.StringCellValue.IsEmpty(val.GetField<
string>(field.
id)));
635 return row.GetCell(x) ??
row.CreateCell(x);
649 private static readonly Dictionary<Type, Dictionary<string, FieldInfo>>
_fieldCache =
new Dictionary<Type, Dictionary<string, FieldInfo>>();
659 Type type = GetType();
664 value =
new Dictionary<string, FieldInfo>();
665 FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
668 value[fieldInfo.Name] = fieldInfo;
685 return this.GetField<int>(
"id") +
"-" + this.GetField<string>(
"alias") +
"(" + this.GetField<string>(
"name_JP") +
")";
688 public string GetText(
string id =
"name",
bool returnNull =
false)
690 Dictionary<string, FieldInfo> rowFields =
GetRowFields();
691 if (rowFields.TryGetValue(
id +
LangSuffix, out var value))
693 string text = value.GetValue(
this) as string;
699 if (!
Lang.
isBuiltin && rowFields.TryGetValue(
id, out var value2))
701 string text2 = value2.GetValue(
this) as string;
702 if (!text2.IsEmpty())
716 Dictionary<string, FieldInfo> rowFields =
GetRowFields();
717 if (rowFields.TryGetValue(
id +
LangSuffix, out var value) && value.GetValue(
this) is
string[] { Length: >0 } array)
721 if (!
Lang.
isBuiltin && rowFields.TryGetValue(
id, out var value2) && value2.GetValue(
this) is
string[] { Length: >0 } array2)
725 return Array.Empty<
string>();
728 public virtual void SetID(ref
int count)
730 this.SetField(
"id", count);
738 public virtual IDictionary<string, string>
ExportTexts(
string idField =
"id")
740 Dictionary<string, FieldInfo> rowFields =
GetRowFields();
741 object obj = rowFields.GetValueOrDefault(idField)?.GetValue(
this);
742 SortedDictionary<string, string> sortedDictionary =
new SortedDictionary<string, string>();
745 return sortedDictionary;
747 string name = GetType().DeclaringType.Name;
748 foreach (var (text2, jp2) in rowFields)
750 if (!text2.EndsWith(
"_JP"))
754 string text3 = text2[..^3];
755 if (rowFields.TryGetValue(text3, out var value) && rowFields.TryGetValue(text3 +
"_L", out var value2))
757 string text4 = GetFieldText(jp2, value, value2);
758 if (!text4.IsEmpty())
760 sortedDictionary[
$"{name}.{obj}.{text3}"] = text4;
764 return sortedDictionary;
771 object obj2 = ((langCode ==
"JP") ? value3 : ((!(langCode ==
"EN")) ? (value5 ?? value4) : value4));
773 if (obj3 is
string str)
775 return str.IsEmpty(value4 as
string);
777 if (obj3 is
string[] array)
779 return string.Join(
',', (array.Length != 0) ? array : (value4 as
string[]));
785 public virtual void ImportTexts(IReadOnlyDictionary<string, string> texts,
string idField =
"id")
787 Dictionary<string, FieldInfo> rowFields =
GetRowFields();
788 object obj = rowFields.GetValueOrDefault(idField)?.GetValue(
this);
793 string name = GetType().DeclaringType.Name;
795 foreach (var (text2, fieldInfo2) in rowFields)
797 if (!text2.EndsWith(
"_L"))
801 string text3 = text2[..^2];
802 if (!texts.TryGetValue(
$"{name}.{obj}.{text3}", out var value2) || value2.IsEmpty() || !rowFields.TryGetValue(text3, out var value3) || !rowFields.TryGetValue(text3 +
"_JP", out var value4))
806 fieldInfo2.SetValue(
this,
null);
807 SetFieldText(fieldInfo2, value2);
808 if (!(langCode ==
"EN"))
810 if (langCode ==
"JP")
812 SetFieldText(value4, value2);
817 SetFieldText(value3, value2);
820 void SetFieldText(
FieldInfo l,
string value)
822 if (l.FieldType == typeof(
string))
824 l.SetValue(
this, value);
826 else if (l.FieldType == typeof(
string[]))
828 l.SetValue(
this, value.IsEmpty() ? Array.Empty<
string>() : value.Split(
','));
858 ExcelParser.row = value;
870 ExcelParser.rowDefault = value;
882 ExcelParser.rowHeader = value;
888 if (!
string.IsNullOrEmpty(rawText))
890 string[] array = rawText.Split(
',');
891 foreach (
string key
in array)
893 map.Add(key, value:
true);
915 public virtual bool ImportData(ISheet sheet,
string bookname,
bool overwrite =
false)
920 public virtual int ImportRows(IEnumerable<BaseRow> sourceRows)
974 if (cell !=
null && cell.CellType != CellType.Blank)
976 return cell.CellType == CellType.Unknown;
1021 public static string GetStr(
int id,
bool useDefault =
false)
static string LangImportMod
static bool GetBool(int id)
static string GetRowHeaderDiff(IReadOnlyDictionary< string, int > mapping, IReadOnlyDictionary< string, int > header)
static int GetInt(int id)
static string GetString(int id)
static int[] GetIntArray(int id)
static float GetFloat(int id)
static double GetDouble(int id)
static string GetStr(int id, bool useDefault=false)
static float[] GetFloatArray(int id)
static string[] GetStringArray(int id)
virtual string GetEditorListName()
string[] GetTextArray(string id)
virtual void SetID(ref int count)
string GetText(string id="name", bool returnNull=false)
virtual IDictionary< string, string > ExportTexts(string idField="id")
static readonly Dictionary< Type, Dictionary< string, FieldInfo > > _fieldCache
virtual void OnImportData(SourceData data)
virtual void ImportTexts(IReadOnlyDictionary< string, string > texts, string idField="id")
Dictionary< string, FieldInfo > GetRowFields()
static float GetFloat(int id)
virtual string[] ImportFields
static string[] GetStringArray(int id)
virtual void SetRow(T row)
override bool ImportData(ISheet sheet, string bookname, bool overwrite=false)
static string GetString(int id)
static bool GetBool(int id)
override void RollbackSource()
virtual BaseRow[] ExportRows()
override void ExportTexts(string path, bool update=false)
static bool IsNull(ICell cell)
virtual string[] GetList(string id)
static double GetDouble(int id)
virtual void BackupSource()
virtual IReadOnlyDictionary< string, int > GetRowMapping()
static int GetInt(int id)
virtual void InsertData(IRow row)
virtual string sourcePath
override void BackupSource()
void BuildFlags(string rawText, Dictionary< string, bool > map)
static string GetStr(int id, bool useDefault=false)
static ICell GetCell(int x, int y)
virtual void OnAfterImportData()
virtual bool ImportData(ISheet sheet, string bookname, bool overwrite=false)
override void ValidateLang()
static float[] GetFloatArray(int id)
static ISheet currentSheet
virtual void ValidateLang()
virtual T CreateRowByMapping(IReadOnlyDictionary< string, int > mapping)
virtual void RemoveDuplicateRows()
override BaseRow[] ExportRows()
static int[] GetIntArray(int id)
Dictionary< string, T > alias
virtual void ExportTexts(string path, bool update=false)
virtual void ValidatePref()
override int ImportRows(IEnumerable< BaseRow > sourceRows)
virtual void RollbackSource()
override void ImportTexts(string _nameSheet=null)
virtual void RestorePref()
virtual T GetRow(string id)
List< string > editorListString
List< FieldInfo > GetFields()
List< string > GetListString()
SourceData< T, T2 > BuildEditorList()
virtual IReadOnlyDictionary< string, string > GetTypeMapping()
virtual void BackupPref()
virtual int ImportRows(IEnumerable< BaseRow > sourceRows)
virtual void ImportTexts(string _nameSheet=null)
virtual bool AllowHotInitialization