diff --git a/README.md b/README.md index f1355a1..38e69df 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,14 @@ luban相较于常规的excel导表工具有以下核心优势: ## 特性 - 支持excel族、json、xml、lua、yaml 多种数据格式,基本统一了游戏常见的配置数据 -- **强大完备的类型系统**。**可以优雅表达任意复杂的数据结构**。支持所有常见原生类型、datetime类型、容器类型list,set,map、枚举和结构、**多态结构**以及**可空类型**。 +- **强大完备的类型系统**。**可以优雅表达任意复杂的数据结构**。支持所有常见原生类型、text本地化类型、datetime类型、vector{2,3,4}、容器类型list,set,map、枚举和结构、**多态结构**以及**可空类型**。 - 支持增强的excel格式。可以在excel里比较简洁填写出任意复杂的嵌套数据。 - 生成代码清晰易读、良好模块化。支持指定变量命名风格约定。特地支持运行时原子性热更新配置。 - 灵活的数据源定义。一个表可以来自多个文件或者一个文件内定义多个表或者一个目录下所有文件甚至来自云表格,以及以上的组合 - 支持表与字段级别分组。可以灵活定义分组,选择性地导出客户端或者服务器或编辑器所用的表及字段 -- 多种导出数据格式支持。支持binary、json、**protobuf**、lua、xml、erlang、**xlsx** 及自定义的导出数据格式 -- 支持xlsx与json、lua、protobuf等格式之间互转 +- 支持生成**protobuf**、**msgpack**、**flatbuffers**相应的定义文件及相应的数据文件(直接反射导出,高效,并不需要生成代码后再利用生成的代码加载导出) +- 多种导出数据格式支持。支持binary、json、**protobuf**、**msgpack**、**flatbuffers**、lua、xml、erlang、**xlsx** 及自定义的导出数据格式 +- 支持xlsx与json、lua、xml、yaml等格式之间互转 - 强大灵活的定制能力 - 支持代码模板,可以用自定义模板定制生成的代码格式 - **支持数据模板**,可以用模板文件定制导出格式。意味着可以在不改动现有程序代码的情况下,把luban当作**配置处理前端**,生成自定义格式的数据与自己项目的配置加载代码配合工作。开发已久的项目或者已经上线的老项目,也能从luban强大的数据处理工作流中获益 diff --git a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs index fbeec21..a17f82d 100644 --- a/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs +++ b/src/Luban.Job.Cfg/Source/Defs/CfgDefLoader.cs @@ -687,7 +687,7 @@ namespace Luban.Job.Cfg.Defs ); } - private Field CreateField(string defileFile, string name, string type, string group, + private Field CreateField(string defineFile, string name, string type, string group, string comment, string tags, bool ignoreNameValidation) { @@ -703,13 +703,9 @@ namespace Luban.Job.Cfg.Defs // 字段与table的默认组不一样。 // table 默认只属于default=1的组 // 字段默认属于所有组 - if (f.Groups.Count == 0) + if (!ValidGroup(f.Groups, out var invalidGroup)) { - - } - else if (!ValidGroup(f.Groups, out var invalidGroup)) - { - throw new Exception($"定义文件:{defileFile} field:'{name}' group:'{invalidGroup}' 不存在"); + throw new Exception($"定义文件:{defineFile} field:'{name}' group:'{invalidGroup}' 不存在"); } f.Type = type; @@ -724,7 +720,7 @@ namespace Luban.Job.Cfg.Defs return f; } - private static readonly List _beanOptinsAttrs = new List { "value_type", "alias", "sep", "comment", "tags" }; + private static readonly List _beanOptinsAttrs = new List { "value_type", "alias", "sep", "comment", "tags", "group" }; private static readonly List _beanRequireAttrs = new List { "name" }; override protected void AddBean(string defineFile, XElement e, string parent) diff --git a/src/Luban.Job.Common/Source/Types/TArray.cs b/src/Luban.Job.Common/Source/Types/TArray.cs index 32041d7..df8fae0 100644 --- a/src/Luban.Job.Common/Source/Types/TArray.cs +++ b/src/Luban.Job.Common/Source/Types/TArray.cs @@ -14,6 +14,8 @@ namespace Luban.Job.Common.Types public override TType ElementType { get; } + public override string TypeName => "array"; + private TArray(bool isNullable, Dictionary tags, TType elementType) : base(isNullable, tags) { ElementType = elementType; diff --git a/src/Luban.Job.Common/Source/Types/TBean.cs b/src/Luban.Job.Common/Source/Types/TBean.cs index e8e402a..b3eccb6 100644 --- a/src/Luban.Job.Common/Source/Types/TBean.cs +++ b/src/Luban.Job.Common/Source/Types/TBean.cs @@ -18,6 +18,8 @@ namespace Luban.Job.Common.Types public T GetBeanAs() where T : DefBeanBase => (T)Bean; + public override string TypeName => "bean"; + private TBean(bool isNullable, Dictionary attrs, DefBeanBase defBean) : base(isNullable, attrs) { this.Bean = defBean; diff --git a/src/Luban.Job.Common/Source/Types/TBool.cs b/src/Luban.Job.Common/Source/Types/TBool.cs index a4f42c4..730a8aa 100644 --- a/src/Luban.Job.Common/Source/Types/TBool.cs +++ b/src/Luban.Job.Common/Source/Types/TBool.cs @@ -16,6 +16,8 @@ namespace Luban.Job.Common.Types public bool IsBool => true; + public override string TypeName => "bool"; + public override bool TryParseFrom(string s) { return bool.TryParse(s, out _); diff --git a/src/Luban.Job.Common/Source/Types/TByte.cs b/src/Luban.Job.Common/Source/Types/TByte.cs index 7eb1e73..d6ef120 100644 --- a/src/Luban.Job.Common/Source/Types/TByte.cs +++ b/src/Luban.Job.Common/Source/Types/TByte.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TByte(isNullable, tags); } + public override string TypeName => "byte"; + private TByte(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TBytes.cs b/src/Luban.Job.Common/Source/Types/TBytes.cs index d15d274..383aa1b 100644 --- a/src/Luban.Job.Common/Source/Types/TBytes.cs +++ b/src/Luban.Job.Common/Source/Types/TBytes.cs @@ -11,6 +11,8 @@ namespace Luban.Job.Common.Types return new TBytes(isNullable, tags); } + public override string TypeName => "bytes"; + private TBytes(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TDateTime.cs b/src/Luban.Job.Common/Source/Types/TDateTime.cs index 3c50656..768514d 100644 --- a/src/Luban.Job.Common/Source/Types/TDateTime.cs +++ b/src/Luban.Job.Common/Source/Types/TDateTime.cs @@ -11,6 +11,8 @@ namespace Luban.Job.Common.Types return new TDateTime(isNullable, tags); } + public override string TypeName => "datetime"; + private TDateTime(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TDouble.cs b/src/Luban.Job.Common/Source/Types/TDouble.cs index dcf1f09..ed793b3 100644 --- a/src/Luban.Job.Common/Source/Types/TDouble.cs +++ b/src/Luban.Job.Common/Source/Types/TDouble.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TDouble(isNullable, tags); } + public override string TypeName => "double"; + private TDouble(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TEnum.cs b/src/Luban.Job.Common/Source/Types/TEnum.cs index cda5570..2742047 100644 --- a/src/Luban.Job.Common/Source/Types/TEnum.cs +++ b/src/Luban.Job.Common/Source/Types/TEnum.cs @@ -13,6 +13,8 @@ namespace Luban.Job.Common.Types return new TEnum(isNullable, DefUtil.MergeTags(defEnum.Tags, tags), defEnum); } + public override string TypeName => "enum"; + public DefEnum DefineEnum { get; } private TEnum(bool isNullable, Dictionary tags, DefEnum defEnum) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TFint.cs b/src/Luban.Job.Common/Source/Types/TFint.cs index 07f94a2..a82e202 100644 --- a/src/Luban.Job.Common/Source/Types/TFint.cs +++ b/src/Luban.Job.Common/Source/Types/TFint.cs @@ -14,6 +14,8 @@ namespace Luban.Job.Common.Types { } + public override string TypeName => "fint"; + public override bool TryParseFrom(string s) { return int.TryParse(s, out _); diff --git a/src/Luban.Job.Common/Source/Types/TFloat.cs b/src/Luban.Job.Common/Source/Types/TFloat.cs index 8f35ade..0bd6562 100644 --- a/src/Luban.Job.Common/Source/Types/TFloat.cs +++ b/src/Luban.Job.Common/Source/Types/TFloat.cs @@ -12,6 +12,8 @@ namespace Luban.Job.Common.Types return new TFloat(isNullable, tags); } + public override string TypeName => "float"; + private TFloat(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TFlong.cs b/src/Luban.Job.Common/Source/Types/TFlong.cs index e41e868..8031ab0 100644 --- a/src/Luban.Job.Common/Source/Types/TFlong.cs +++ b/src/Luban.Job.Common/Source/Types/TFlong.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TFlong(isNullable, tags); } + public override string TypeName => "flong"; + private TFlong(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TFshort.cs b/src/Luban.Job.Common/Source/Types/TFshort.cs index 3d2799d..7284582 100644 --- a/src/Luban.Job.Common/Source/Types/TFshort.cs +++ b/src/Luban.Job.Common/Source/Types/TFshort.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TFshort(isNullable, tags); } + public override string TypeName => "fshort"; + private TFshort(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TInt.cs b/src/Luban.Job.Common/Source/Types/TInt.cs index bb335e5..2ebe380 100644 --- a/src/Luban.Job.Common/Source/Types/TInt.cs +++ b/src/Luban.Job.Common/Source/Types/TInt.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TInt(isNullable, tags); } + public override string TypeName => "int"; + private TInt(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TList.cs b/src/Luban.Job.Common/Source/Types/TList.cs index 403b577..fffeedc 100644 --- a/src/Luban.Job.Common/Source/Types/TList.cs +++ b/src/Luban.Job.Common/Source/Types/TList.cs @@ -12,6 +12,8 @@ namespace Luban.Job.Common.Types return new TList(isNullable, tags, elementType, isArrayList); } + public override string TypeName => "list"; + public override TType ElementType { get; } public bool IsArrayList { get; } diff --git a/src/Luban.Job.Common/Source/Types/TLong.cs b/src/Luban.Job.Common/Source/Types/TLong.cs index 1282495..60adb37 100644 --- a/src/Luban.Job.Common/Source/Types/TLong.cs +++ b/src/Luban.Job.Common/Source/Types/TLong.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TLong(isNullable, tags, isBigInt); } + public override string TypeName => "long"; + public bool IsBigInt { get; } private TLong(bool isNullable, Dictionary tags, bool isBigInt) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TMap.cs b/src/Luban.Job.Common/Source/Types/TMap.cs index ce48958..d734596 100644 --- a/src/Luban.Job.Common/Source/Types/TMap.cs +++ b/src/Luban.Job.Common/Source/Types/TMap.cs @@ -12,6 +12,8 @@ namespace Luban.Job.Common.Types return new TMap(isNullable, tags, keyType, valueType, isOrderedMap); } + public override string TypeName => "map"; + public bool IsMap => true; public TType KeyType { get; } diff --git a/src/Luban.Job.Common/Source/Types/TSet.cs b/src/Luban.Job.Common/Source/Types/TSet.cs index 3f537ce..78f1604 100644 --- a/src/Luban.Job.Common/Source/Types/TSet.cs +++ b/src/Luban.Job.Common/Source/Types/TSet.cs @@ -12,6 +12,8 @@ namespace Luban.Job.Common.Types return new TSet(isNullable, tags, elementType, isOrdered); } + public override string TypeName => "set"; + public override TType ElementType { get; } public bool IsOrderSet { get; } diff --git a/src/Luban.Job.Common/Source/Types/TShort.cs b/src/Luban.Job.Common/Source/Types/TShort.cs index f569c09..b5d016f 100644 --- a/src/Luban.Job.Common/Source/Types/TShort.cs +++ b/src/Luban.Job.Common/Source/Types/TShort.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TShort(isNullable, tags); } + public override string TypeName => "short"; + private TShort(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TString.cs b/src/Luban.Job.Common/Source/Types/TString.cs index 4bd14a6..a9f697d 100644 --- a/src/Luban.Job.Common/Source/Types/TString.cs +++ b/src/Luban.Job.Common/Source/Types/TString.cs @@ -10,6 +10,8 @@ namespace Luban.Job.Common.Types return new TString(isNullable, tags); } + public override string TypeName => "string"; + private TString(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TText.cs b/src/Luban.Job.Common/Source/Types/TText.cs index ccbe80b..26cc1b1 100644 --- a/src/Luban.Job.Common/Source/Types/TText.cs +++ b/src/Luban.Job.Common/Source/Types/TText.cs @@ -12,6 +12,8 @@ namespace Luban.Job.Common.Types return new TText(isNullable, tags); } + public override string TypeName => "text"; + private TText(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TType.cs b/src/Luban.Job.Common/Source/Types/TType.cs index 64e6dd9..382ddd2 100644 --- a/src/Luban.Job.Common/Source/Types/TType.cs +++ b/src/Luban.Job.Common/Source/Types/TType.cs @@ -18,6 +18,8 @@ namespace Luban.Job.Common.Types Tags = tags ?? new Dictionary(); } + public abstract string TypeName { get; } + public bool HasTag(string attrName) { return Tags != null && Tags.ContainsKey(attrName); diff --git a/src/Luban.Job.Common/Source/Types/TVector2.cs b/src/Luban.Job.Common/Source/Types/TVector2.cs index 6a599a1..e72f114 100644 --- a/src/Luban.Job.Common/Source/Types/TVector2.cs +++ b/src/Luban.Job.Common/Source/Types/TVector2.cs @@ -11,6 +11,8 @@ namespace Luban.Job.Common.Types return new TVector2(isNullable, tags); } + public override string TypeName => "vector2"; + private TVector2(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TVector3.cs b/src/Luban.Job.Common/Source/Types/TVector3.cs index ab2afcb..cde4bac 100644 --- a/src/Luban.Job.Common/Source/Types/TVector3.cs +++ b/src/Luban.Job.Common/Source/Types/TVector3.cs @@ -11,6 +11,8 @@ namespace Luban.Job.Common.Types return new TVector3(isNullable, tags); } + public override string TypeName => "vector3"; + private TVector3(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Job.Common/Source/Types/TVector4.cs b/src/Luban.Job.Common/Source/Types/TVector4.cs index 89b8c0d..32451ca 100644 --- a/src/Luban.Job.Common/Source/Types/TVector4.cs +++ b/src/Luban.Job.Common/Source/Types/TVector4.cs @@ -11,6 +11,8 @@ namespace Luban.Job.Common.Types return new TVector4(isNullable, tags); } + public override string TypeName => "vector4"; + private TVector4(bool isNullable, Dictionary tags) : base(isNullable, tags) { } diff --git a/src/Luban.Server/Templates/config/cs_bin/bean.tpl b/src/Luban.Server/Templates/config/cs_bin/bean.tpl index 4921342..809f758 100644 --- a/src/Luban.Server/Templates/config/cs_bin/bean.tpl +++ b/src/Luban.Server/Templates/config/cs_bin/bean.tpl @@ -59,6 +59,9 @@ public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{x.paren {{~if field.gen_ref~}} public {{field.cs_ref_validator_define}} {{~end~}} + {{~if field.ctype.type_name == "datetime" && !field.ctype.is_nullable ~}} + public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L; + {{~end~}} {{~if field.gen_text_key~}} public {{cs_define_text_key_field field}} { get; } {{~end~}} diff --git a/src/Luban.Server/Templates/config/cs_json/bean.tpl b/src/Luban.Server/Templates/config/cs_json/bean.tpl index 3558186..dd48e5c 100644 --- a/src/Luban.Server/Templates/config/cs_json/bean.tpl +++ b/src/Luban.Server/Templates/config/cs_json/bean.tpl @@ -68,6 +68,9 @@ public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent} {{~if field.gen_ref~}} public {{field.cs_ref_validator_define}} {{~end~}} + {{~if field.ctype.type_name == "datetime" && !field.ctype.is_nullable ~}} + public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L; + {{~end~}} {{~if field.gen_text_key~}} public {{cs_define_text_key_field field}} { get; } {{~end~}} diff --git a/src/Luban.Server/Templates/config/cs_unity_json/bean.tpl b/src/Luban.Server/Templates/config/cs_unity_json/bean.tpl index 75cd5ab..201151c 100644 --- a/src/Luban.Server/Templates/config/cs_unity_json/bean.tpl +++ b/src/Luban.Server/Templates/config/cs_unity_json/bean.tpl @@ -69,6 +69,9 @@ public {{x.cs_class_modifier}} class {{name}} : {{if parent_def_type}} {{parent} {{~if field.gen_ref~}} public {{field.cs_ref_validator_define}} {{~end~}} + {{~if field.ctype.type_name == "datetime" && !field.ctype.is_nullable ~}} + public long {{field.convention_name}}_Millis => {{field.convention_name}} * 1000L; + {{~end~}} {{~if field.gen_text_key~}} public {{cs_define_text_key_field field}} { get; } {{~end~}}