123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using XGame.Framework.Serialization;
- namespace etoy
- {
- internal class CmdExportBytesDatabase : Command
- {
- public override string Description => "导出数据库-字节流文本";
- protected virtual TableTag AllowedTableTag => TableTag.Client;
- protected virtual KeyValueTag AllowedKeyValueTag => KeyValueTag.Client;
- protected virtual string DatabaseOutput => Context.Option.ClientDatabaseOutput;
- private readonly string TableExt = "Table.bytes";
- private readonly List<Exception> _errors = new List<Exception>();
- protected override void OnProcess()
- {
- var outputPath = DatabaseOutput.ToPath();
- if (Directory.Exists(outputPath))
- Directory.Delete(outputPath, true);
- Directory.CreateDirectory(outputPath);
- SetProgress(0.1f);
- ExportTables(Context, outputPath);
- if (_errors.Count > 0)
- {
- SetException(new Exception(string.Join('\n', (from e in _errors select $"## ERROR: {e.Message}").ToArray())));
- }
- else
- {
- Completed();
- }
- }
- private void ExportTables(Context context, string outputPath)
- {
- foreach (var table in Context.Blackboard.Tables)
- {
- if (HasTableFlag(table.TableTag))
- {
- try
- {
- ExportTable(context, outputPath, table);
- }
- catch (Exception ex)
- {
- _errors.Add(ex);
- Console.WriteLine($"配置表导出异常 Name:{table.Name} Message:{ex.Message}\n\nStack:{ex.StackTrace}");
- }
- }
- }
- }
- private void ExportTable(Context context, string outputPath, Table table)
- {
- var fileName = table.Name + TableExt;
- var filePath = Path.Combine(outputPath, fileName);
- var serializables = new List<ISerializable>();
- for (int i = 0, rowCount = table.Rows.Count; i < rowCount; i++)
- {
- var row = table.Rows[i];
- var fieldGroup = new SerializableFieldGroup();
- for (int j = 0, colCount = row.Cells.Count; j < colCount; j++)
- {
- var cell = row.Cells[j];
- var fieldInfo = cell.FieldInfo;
- if (HasTableFlag(fieldInfo.OutputTag) == false)
- {
- continue;
- }
- if (context.Blackboard.TryGetMetadata(fieldInfo.FieldType, out var metadata))
- { // 是自定义属性
- if (metadata.StructType == MetadataStructType.Enum)
- {// 枚举
- fieldGroup.fields.Add(new SerializableEnum()
- {
- fieldType = fieldInfo.FieldType,
- fieldName = fieldInfo.FieldName,
- isRepeated = fieldInfo.IsRepeated,
- value = cell.Value,
- meta = metadata
- });
- }
- else
- { // 数据结构
- var structField = GenStructField(fieldInfo, cell.Value, table.Name, context, metadata);
- fieldGroup.fields.Add(structField);
- }
- }
- else
- { // 普通字段
- fieldGroup.fields.Add(new SerializableField()
- {
- fieldType = fieldInfo.FieldType,
- fieldName = fieldInfo.FieldName,
- isRepeated = fieldInfo.IsRepeated,
- value = cell.Value
- });
- }
- }
- if (fieldGroup.fields.Count > 0)
- {
- serializables.Add(fieldGroup);
- }
- }
- var writer = new Writer();
- writer.Write(serializables);
- var bytes = writer.Finish();
- File.WriteAllBytes(filePath, bytes);
- }
- private ISerializable GenStructField(FieldInfo fieldInfo, string value, string tableName, Context context, MetadataStruct metadata)
- {
- if (fieldInfo.IsRepeated)
- {
- var fieldArray = new SerializableArray();
- var jArray = JsonConvert.DeserializeObject<JArray>(value);
- foreach (var item in jArray)
- {
- if (item is JObject jobj)
- {
- fieldArray.fields.Add(GenSingleStructField(jobj, tableName, context, metadata));
- }
- else
- {
- throw new Exception($"配置表序列化结构体数据错误. Table:{tableName} FieldType: {fieldInfo.FieldType} Name:{fieldInfo.FieldName} Value:{value}");
- }
- }
- return fieldArray;
- }
- else
- {
- return GenSingleStructField(JsonConvert.DeserializeObject<JObject>(value), tableName, context, metadata);
- }
- }
- private ISerializable GenSingleStructField(JObject jobj, string tableName, Context context, MetadataStruct metadata)
- {
- var fieldGroup = new SerializableFieldGroup();
- for (int i = 0; i < metadata.Fields.Length; i++)
- {
- var metaField = metadata.Fields[i];
- var fieldVal = jobj[metaField.Name].ToString();
- if (context.Blackboard.TryGetMetadata(metaField.FieldType, out var subMeta))
- { // 嵌套
- if (subMeta.StructType == MetadataStructType.Enum)
- { // 枚举
- fieldGroup.fields.Add(new SerializableEnum()
- {
- fieldType = metaField.FieldType,
- fieldName = metaField.Name,
- isRepeated = metaField.StructRepeated,
- value = fieldVal,
- meta = subMeta,
- });
- }
- else
- { //结构体 递归
- if (metaField.StructRepeated)
- { // 数组
- var jArray = jobj[metaField.Name] as JArray;
- var fieldArray = new SerializableArray();
- foreach (var item in jArray)
- {
- if (item is JObject subObj)
- {
- fieldArray.fields.Add(GenSingleStructField(subObj, tableName, context, subMeta));
- }
- else
- {
- throw new Exception($"配置表序列化结构体数据错误.Table:{tableName} FieldType: {subMeta.Name} Value:{fieldVal}");
- }
- }
- fieldGroup.fields.Add(fieldArray);
- }
- else
- {
- fieldGroup.fields.Add(GenSingleStructField(jobj[metaField.Name] as JObject, tableName, context, subMeta));
- }
- }
- }
- else
- {
- fieldGroup.fields.Add(new SerializableField()
- {
- fieldType = metaField.FieldType,
- fieldName = metaField.Name,
- isRepeated = metaField.StructRepeated,
- value = fieldVal
- });
- }
- }
- return fieldGroup;
- }
- private bool HasTableFlag(TableTag tag)
- {
- return AllowedTableTag == TableTag.All || tag.HasFlag(AllowedTableTag);
- }
- //private bool HasKeyValueFlag(KeyValueTag tag)
- //{
- // return AllowedKeyValueTag == KeyValueTag.All || tag.HasFlag(AllowedKeyValueTag);
- //}
- }
- }
|