123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- using System.Text;
- namespace etoy
- {
- class CmdKsonToJson : Command
- {
- public override string Description => "将Kson数据转成Json";
- List<Exception> _errors = new List<Exception>();
- int _total;
- int _done;
- protected override void OnProcess()
- {
- _total = Context.Blackboard.Tables.Count;
- Task.Factory.StartNew(OnThread);
- Task.Factory.StartNew(() =>
- {
- while (_done < _total)
- Thread.Sleep(1);
- if (_errors.Count > 0)
- SetException(new Exception(string.Join('\n', (from e in _errors select $"## ERROR: {e.Message}").ToArray())));
- else
- Completed();
- });
- }
- private void OnThread()
- {
- var tables = Context.Blackboard.Tables;
- for (int i = 0; i < _total; i++)
- {
- var table = tables[i];
- SingleTable(table);
- SetProgress(++_done / (float)_total);
- }
- }
- void SingleTable(Table table)
- {
- for (int i = 0, rowCount = table.Rows.Count; i < rowCount; i++)
- {
- var row = table.Rows[i];
- for (int j = 0, colCount = row.Cells.Count; j < colCount; j++)
- {
- var cell = row.Cells[j];
- if (Context.Blackboard.TryGetMetadata(cell.FieldInfo.FieldType, out var metadata) && metadata.StructType == MetadataStructType.Struct)
- {
- if (cell.Value.IsKsonString())
- {
- string json;
- string repeated = cell.FieldInfo.IsRepeated ? "[]" : string.Empty;
- try
- {
- json = FromKsonToJson(cell.Value, metadata, cell.FieldInfo.IsRepeated);
- }
- catch (Exception e)
- {
- _errors.Add(new Exception($"Kson解析失败, {e.Message}。 类型: {cell.FieldInfo.FieldType}{repeated}\n配置表: {table.Name}, 字段: {cell.FieldInfo.FieldName}, kson: {cell.Value}\n"));
- continue;
- }
- if (!json.IsJsonString())
- {
- _errors.Add(new Exception($"kson转出来的json不合法, kson: {cell.Value}, json: {json}, Table: {table.Name}, Field: {cell.FieldInfo.FieldName}, FieldType: {cell.FieldInfo.FieldType}{repeated}"));
- continue;
- }
- // 正确才改值
- cell.Value = json;
- }
- }
- }
- }
- }
- string FromKsonToJson(string kson, MetadataStruct metadata, bool isRepeated)
- {
- StringBuilder sb = new StringBuilder();
- KsonObject ksonObject = new KsonObject(kson);
- if (ksonObject.IsArray != isRepeated || ksonObject.IsObject == isRepeated)
- throw new Exception("Kson配置错误");
- if (ksonObject.IsObject)
- {
- ToObjectJson(sb, ksonObject, metadata, string.Empty);
- }
- else
- {
- sb.Append("[");
- for (int i = 0, length = ksonObject.ArrayObjects.Count; i < length; i++)
- {
- var list = ksonObject.ArrayObjects[i];
- for (int j = 0, count = list.Count; j < count; j++)
- {
- ToObjectJson(sb, list[j], metadata, string.Empty);
- if (j < count - 1)
- sb.Append(",");
- }
- if (i < length - 1)
- sb.Append(",");
- }
- sb.Append("]");
- }
- return sb.ToString();
- }
- void ToObjectJson(StringBuilder sb, KsonObject ksonObject, MetadataStruct metadata, string key)
- {
- key = string.IsNullOrEmpty(key) ? "{" : $"\"{key}\":{{";
- sb.Append(key);
- // 0允许, 即{}. 非0且数量不相等便是策划配置字段数量有误
- int fieldCount = ksonObject.FieldCount;
- if (fieldCount != 0 && fieldCount != metadata.Fields.Length)
- throw new Exception("字段数量不一致");
- for (int i = 0; i < fieldCount; i++)
- {
- var field = metadata.Fields[i];
- var fieldName = field.Name;
- var fieldType = field.FieldType;
- if (Context.Blackboard.TryGetMetadata(fieldType, out var fieldMetadata))
- {
- if (ksonObject.KsonObjects.TryGetValue(i, out var obj))
- {
- ToObjectJson(sb, obj, fieldMetadata, fieldName);
- }
- else if (ksonObject.ArrayObjects.TryGetValue(i, out var array))
- {
- sb.Append($"\"{fieldName}\":[");
- for (int j = 0, arrayCount = array.Count; j < arrayCount; j++)
- {
- ToObjectJson(sb, array[j], fieldMetadata, string.Empty);
- if (j < arrayCount - 1)
- sb.Append(",");
- }
- sb.Append("]");
- }
- }
- else if (ksonObject.StringValues.TryGetValue(i, out var stringValue))
- {
- switch (fieldType)
- {
- case FieldTypeDefine.Boolean:
- case FieldTypeDefine.Int:
- case FieldTypeDefine.Long:
- case FieldTypeDefine.Float:
- case FieldTypeDefine.Double:
- sb.Append($"\"{fieldName}\":{stringValue}");
- break;
- default:
- sb.Append($"\"{fieldName}\":\"{stringValue}\"");
- break;
- }
- }
- else if (ksonObject.ArrayObjects.TryGetValue(i, out var array))
- {
- sb.Append($"\"{fieldName}\":[");
- for (int j = 0, arrayCount = array.Count; j < arrayCount; j++)
- {
- var item = array[j];
- switch (fieldType)
- {
- case FieldTypeDefine.Boolean:
- case FieldTypeDefine.Int:
- case FieldTypeDefine.Long:
- case FieldTypeDefine.Float:
- case FieldTypeDefine.Double:
- sb.Append(item.RawKson);
- break;
- default:
- sb.Append($"\"{item.RawKson}\"");
- break;
- }
- if (j < arrayCount - 1)
- sb.Append(",");
- }
- sb.Append("]");
- }
- if (i < fieldCount - 1)
- sb.Append(",");
- }
- sb.Append("}");
- }
- }
- }
|