diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index c671fe2..2937e10 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
- go-version: '1.20'
+ go-version: '1.21'
- run: go build -o bin/${{ github.event.repository.name }}_linux_x64 .
- run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/${{ github.event.repository.name }}_win_x64.exe
diff --git a/README.md b/README.md
index 5e92067..9b19d98 100644
--- a/README.md
+++ b/README.md
@@ -121,11 +121,15 @@ table_export -g csv_test,csv_test.csv
# TODO
-在1.0版本中会加入数据检测,自定义复合类型,自定义枚举,特殊后处理等功能。
-
+目前1.0版本中已经支持,后续会更新使用文档
+ - 数据检测
+ - 自定义复合类型(使用go或者js脚本扩展)
+ - 自定义枚举
+TODO :添加特殊后处理等功能。
## Credits
- [LuaTableOptimizer](https://github.com/lujian101/LuaTableOptimizer) 使用了lua表优化工具,在此基础上做了更进一步的优化
-- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路
\ No newline at end of file
+- [luban](https://github.com/focus-creative-games/luban) 使用了二进制序列化的代码和一些思路
+- [goja](https://github.com/dop251/goja) js的脚本引擎,使用js来扩展自定义类型和表后处理
\ No newline at end of file
diff --git a/component/goja/table_engine/module.go b/component/goja/table_engine/module.go
new file mode 100644
index 0000000..df95b0f
--- /dev/null
+++ b/component/goja/table_engine/module.go
@@ -0,0 +1,90 @@
+package table_engine
+
+import (
+ "github.com/821869798/table-export/config"
+ "github.com/821869798/table-export/field_type"
+ "github.com/dop251/goja"
+ "github.com/dop251/goja_nodejs/require"
+ _ "github.com/dop251/goja_nodejs/util"
+)
+
+type TableEngine struct {
+ runtime *goja.Runtime
+ //util *goja.Object
+}
+
+func (c *TableEngine) NewTableFieldClass(name string) *field_type.TableFieldClass {
+ return field_type.NewTableFieldClass(name)
+}
+
+func (c *TableEngine) NewTableFieldType(fieldType int) *field_type.TableFieldType {
+ return field_type.NewTableFieldType(field_type.EFieldType(fieldType))
+}
+
+func (c *TableEngine) NewTableFieldEnumType(name string) *field_type.TableFieldType {
+ return field_type.NewTableFieldEnumType(name)
+}
+
+func (c *TableEngine) NewTableFieldArrayType(value *field_type.TableFieldType) *field_type.TableFieldType {
+ return field_type.NewTableFieldArrayType(value)
+}
+
+func (c *TableEngine) NewTableFieldMapType(key *field_type.TableFieldType, value *field_type.TableFieldType) *field_type.TableFieldType {
+ return field_type.NewTableFieldMapType(key, value)
+}
+
+func (c *TableEngine) NewTableFieldClassType(class *field_type.TableFieldClass) *field_type.TableFieldType {
+ return field_type.NewTableFieldClassType(class)
+}
+
+//func (c *TableEngine) log(p func(string)) func(goja.FunctionCall) goja.Value {
+// return func(call goja.FunctionCall) goja.Value {
+// if format, ok := goja.AssertFunction(c.util.Get("format")); ok {
+// ret, err := format(c.util, call.Arguments...)
+// if err != nil {
+// panic(err)
+// }
+//
+// p(ret.String())
+// } else {
+// panic(c.runtime.NewTypeError("util.format is not a function"))
+// }
+//
+// return nil
+// }
+//}
+
+func Require(runtime *goja.Runtime, module *goja.Object) {
+ requireWithPrinter()(runtime, module)
+}
+
+func RequireWithPrinter() require.ModuleLoader {
+ return requireWithPrinter()
+}
+
+func requireWithPrinter() require.ModuleLoader {
+ return func(runtime *goja.Runtime, module *goja.Object) {
+ c := &TableEngine{
+ runtime: runtime,
+ }
+
+ //c.util = require.Require(runtime, "util").(*goja.Object)
+
+ o := module.Get("exports").(*goja.Object)
+ o.Set("NewTableFieldClass", c.NewTableFieldClass)
+ o.Set("NewTableFieldType", c.NewTableFieldType)
+ o.Set("NewTableFieldEnumType", c.NewTableFieldEnumType)
+ o.Set("NewTableFieldArrayType", c.NewTableFieldArrayType)
+ o.Set("NewTableFieldMapType", c.NewTableFieldMapType)
+ o.Set("NewTableFieldClassType", c.NewTableFieldClassType)
+ o.Set("TableConfig", config.GlobalConfig.Table)
+ }
+}
+
+func Enable(runtime *goja.Runtime) {
+ runtime.Set("tableEngine", require.Require(runtime, "tableEngine"))
+}
+
+func init() {
+ require.RegisterNativeModule("tableEngine", Require)
+}
diff --git a/config/config_rule.go b/config/config_rule.go
index 2f0e4ef..fc04181 100644
--- a/config/config_rule.go
+++ b/config/config_rule.go
@@ -42,42 +42,3 @@ type RawMetaRuleUnitLua struct {
func (r *RawMetaRuleUnitLua) RuleExportType() ExportType {
return ExportType_Lua
}
-
-type RawMetaRuleUnitCSBin struct {
- CodeTempDir string `toml:"code_temp_dir"`
- DataTempDir string `toml:"data_temp_dir"`
- GenCodeDir string `toml:"gen_code_dir"`
- DataBinDir string `toml:"data_bin_dir"`
- GenCodeNamespace string `toml:"code_namespace"`
- GenCodeHead string `toml:"gen_code_head"`
- CodeNotFoundKey string `toml:"code_not_found_key"`
- GenOptimizeData bool `toml:"gen_optimize"`
- EnumFiles []string `toml:"enum_files"`
- EnumDefinePrefix string `toml:"enum_define_prefix"`
- ClassDefinePrefix string `toml:"class_define_prefix"`
- BuiltinFieldTypes []string `toml:"builtin_field_types"`
-}
-
-func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType {
- return ExportType_CS_Bin
-}
-
-func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool {
- return r.GenOptimizeData
-}
-
-func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string {
- return r.EnumFiles
-}
-
-func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string {
- return r.EnumDefinePrefix
-}
-
-func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string {
- return r.ClassDefinePrefix
-}
-
-func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string {
- return r.BuiltinFieldTypes
-}
diff --git a/config/config_rule_csbin.go b/config/config_rule_csbin.go
new file mode 100644
index 0000000..ee2095e
--- /dev/null
+++ b/config/config_rule_csbin.go
@@ -0,0 +1,45 @@
+package config
+
+type RawMetaRuleUnitCSBin struct {
+ CodeTempDir string `toml:"code_temp_dir"`
+ DataTempDir string `toml:"data_temp_dir"`
+ GenCodeDir string `toml:"gen_code_dir"`
+ DataBinDir string `toml:"data_bin_dir"`
+ GenCodeNamespace string `toml:"code_namespace"`
+ GenCodeHead string `toml:"gen_code_head"`
+ CodeNotFoundKey string `toml:"code_not_found_key"`
+ GenOptimizeData bool `toml:"gen_optimize"`
+ EnumFiles []string `toml:"enum_files"`
+ EnumDefinePrefix string `toml:"enum_define_prefix"`
+ ClassDefinePrefix string `toml:"class_define_prefix"`
+ BuiltinFieldTypes []string `toml:"builtin_field_types"`
+ ScriptFieldTypes []string `toml:"script_field_types"`
+}
+
+func (r *RawMetaRuleUnitCSBin) RuleExportType() ExportType {
+ return ExportType_CS_Bin
+}
+
+func (r *RawMetaRuleUnitCSBin) ActiveOptimizeData() bool {
+ return r.GenOptimizeData
+}
+
+func (r *RawMetaRuleUnitCSBin) GetEnumFiles() []string {
+ return r.EnumFiles
+}
+
+func (r *RawMetaRuleUnitCSBin) GetEnumDefinePrefix() string {
+ return r.EnumDefinePrefix
+}
+
+func (r *RawMetaRuleUnitCSBin) GetClassDefinePrefix() string {
+ return r.ClassDefinePrefix
+}
+
+func (r *RawMetaRuleUnitCSBin) GetBuiltinFieldTypes() []string {
+ return r.BuiltinFieldTypes
+}
+
+func (r *RawMetaRuleUnitCSBin) GetExtFieldTypeScriptPath() []string {
+ return r.ScriptFieldTypes
+}
diff --git a/config/define.go b/config/define.go
index 3093bd2..7beda7a 100644
--- a/config/define.go
+++ b/config/define.go
@@ -22,4 +22,5 @@ type MetaRuleUnitPlus interface {
GetEnumDefinePrefix() string
GetClassDefinePrefix() string
GetBuiltinFieldTypes() []string
+ GetExtFieldTypeScriptPath() []string
}
diff --git a/convert/apiconvert/idatavisitor.go b/convert/apiconvert/idatavisitor.go
index 7cc26a6..50dc371 100644
--- a/convert/apiconvert/idatavisitor.go
+++ b/convert/apiconvert/idatavisitor.go
@@ -23,4 +23,5 @@ type IDataVisitor interface {
AcceptCommonMap(r map[interface{}]interface{}, KeyType *field_type.TableFieldType, ValueType *field_type.TableFieldType)
AcceptClass(r map[string]interface{}, class *field_type.TableFieldClass)
AcceptClassString(r map[string]string, class *field_type.TableFieldClass)
+ AcceptClassNull(class *field_type.TableFieldClass)
}
diff --git a/convert/visitor/binary.go b/convert/visitor/binary.go
index eafa41f..16bcf77 100644
--- a/convert/visitor/binary.go
+++ b/convert/visitor/binary.go
@@ -202,3 +202,13 @@ func (b *BinaryVisitor) AcceptClassString(r map[string]string, class *field_type
}
}
}
+
+func (b *BinaryVisitor) AcceptClassNull(class *field_type.TableFieldClass) {
+ for _, field := range class.AllFields() {
+ // 使用默认值解析
+ err := wrap.RunDataVisitorString(b, field.Type, "")
+ if err != nil {
+ slog.Fatalf("export binary AcceptClass failed: %v", err)
+ }
+ }
+}
diff --git a/convert/wrap/wrap_class.go b/convert/wrap/wrap_class.go
index 9bd0b93..ef8f202 100644
--- a/convert/wrap/wrap_class.go
+++ b/convert/wrap/wrap_class.go
@@ -34,6 +34,10 @@ func (c *classWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType
}
func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
+ if origin == nil {
+ visitor.AcceptClassNull(fieldType.Class)
+ return nil
+ }
switch value := origin.(type) {
case map[string]interface{}:
visitor.AcceptClass(value, fieldType.Class)
@@ -44,7 +48,7 @@ func (c *classWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType
case string:
return RunDataVisitorString(visitor, fieldType, value)
default:
- return errors.New(fmt.Sprintf("[DataVisitorValue|map] no support type[%T]", origin))
+ return errors.New(fmt.Sprintf("[DataVisitorValue|class] no support type[%T]", origin))
}
}
diff --git a/convert/wrap/wrap_double.go b/convert/wrap/wrap_double.go
index 48b26d0..12bebaa 100644
--- a/convert/wrap/wrap_double.go
+++ b/convert/wrap/wrap_double.go
@@ -59,16 +59,21 @@ func (b *doubleWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldTyp
}
func (b *doubleWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
- value, ok := origin.(float64)
- if ok {
+ switch value := origin.(type) {
+ case float64:
visitor.AcceptDouble(value)
return nil
+ case float32:
+ visitor.AcceptDouble(float64(value))
+ return nil
+ case int64:
+ visitor.AcceptDouble(float64(value))
+ return nil
+ case string:
+ return b.DataVisitorString(visitor, fieldType, value)
+ default:
+ return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin))
}
- stringValue, ok := origin.(string)
- if ok {
- return b.DataVisitorString(visitor, fieldType, stringValue)
- }
- return errors.New(fmt.Sprintf("[DataVisitorValue|double] no support type[%T]", origin))
}
func (b *doubleWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string {
diff --git a/convert/wrap/wrap_enum.go b/convert/wrap/wrap_enum.go
index 4bbdc69..af2bd3e 100644
--- a/convert/wrap/wrap_enum.go
+++ b/convert/wrap/wrap_enum.go
@@ -84,6 +84,9 @@ func (e *enumWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *
case int:
visitor.AcceptInt(int32(value))
return nil
+ case float64:
+ visitor.AcceptInt(int32(value))
+ return nil
case string:
return e.DataVisitorString(visitor, fieldType, value)
default:
diff --git a/convert/wrap/wrap_float.go b/convert/wrap/wrap_float.go
index a8a8c97..50e3f18 100644
--- a/convert/wrap/wrap_float.go
+++ b/convert/wrap/wrap_float.go
@@ -70,6 +70,9 @@ func (b *floatWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType
case float64:
visitor.AcceptFloat(float32(value))
return nil
+ case int64:
+ visitor.AcceptFloat(float32(value))
+ return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
diff --git a/convert/wrap/wrap_int.go b/convert/wrap/wrap_int.go
index 0b6a658..2ea4ece 100644
--- a/convert/wrap/wrap_int.go
+++ b/convert/wrap/wrap_int.go
@@ -69,6 +69,9 @@ func (b *intWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *f
case int:
visitor.AcceptInt(int32(value))
return nil
+ case float64:
+ visitor.AcceptInt(int32(value))
+ return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
diff --git a/convert/wrap/wrap_long.go b/convert/wrap/wrap_long.go
index a124195..342fd5e 100644
--- a/convert/wrap/wrap_long.go
+++ b/convert/wrap/wrap_long.go
@@ -59,16 +59,24 @@ func (b *longWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType
}
func (b *longWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
- value, ok := origin.(int64)
- if ok {
+ switch value := origin.(type) {
+ case int64:
visitor.AcceptLong(value)
return nil
+ case int32:
+ visitor.AcceptLong(int64(value))
+ return nil
+ case int:
+ visitor.AcceptLong(int64(value))
+ return nil
+ case float64:
+ visitor.AcceptLong(int64(value))
+ return nil
+ case string:
+ return b.DataVisitorString(visitor, fieldType, value)
+ default:
+ return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin))
}
- stringValue, ok := origin.(string)
- if ok {
- return b.DataVisitorString(visitor, fieldType, stringValue)
- }
- return errors.New(fmt.Sprintf("[DataVisitorValue|long] no support type[%T]", origin))
}
func (b *longWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string {
diff --git a/convert/wrap/wrap_uint.go b/convert/wrap/wrap_uint.go
index b43e8a6..76d823a 100644
--- a/convert/wrap/wrap_uint.go
+++ b/convert/wrap/wrap_uint.go
@@ -70,6 +70,18 @@ func (b *uintWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *
case uint64:
visitor.AcceptUInt(uint32(value))
return nil
+ case int:
+ visitor.AcceptUInt(uint32(value))
+ return nil
+ case float64:
+ visitor.AcceptUInt(uint32(value))
+ return nil
+ case int64:
+ visitor.AcceptUInt(uint32(value))
+ return nil
+ case int32:
+ visitor.AcceptUInt(uint32(value))
+ return nil
case string:
return b.DataVisitorString(visitor, fieldType, value)
default:
diff --git a/convert/wrap/wrap_ulong.go b/convert/wrap/wrap_ulong.go
index ab8f1a8..cf40c3a 100644
--- a/convert/wrap/wrap_ulong.go
+++ b/convert/wrap/wrap_ulong.go
@@ -59,16 +59,30 @@ func (b *ulongWrap) DataVisitorString(visitor apiconvert.IDataVisitor, fieldType
}
func (b *ulongWrap) DataVisitorValue(visitor apiconvert.IDataVisitor, fieldType *field_type.TableFieldType, origin interface{}) error {
- value, ok := origin.(uint64)
- if ok {
+ switch value := origin.(type) {
+ case uint64:
visitor.AcceptULong(value)
return nil
+ case uint32:
+ visitor.AcceptULong(uint64(value))
+ return nil
+ case int:
+ visitor.AcceptULong(uint64(value))
+ return nil
+ case float64:
+ visitor.AcceptULong(uint64(value))
+ return nil
+ case int64:
+ visitor.AcceptULong(uint64(value))
+ return nil
+ case int32:
+ visitor.AcceptULong(uint64(value))
+ return nil
+ case string:
+ return b.DataVisitorString(visitor, fieldType, value)
+ default:
+ return errors.New(fmt.Sprintf("[DataVisitorValue|ulong] no support type[%T]", origin))
}
- stringValue, ok := origin.(string)
- if ok {
- return b.DataVisitorString(visitor, fieldType, stringValue)
- }
- return errors.New(fmt.Sprintf("[DataVisitorValue|ulong] no support type[%T]", origin))
}
func (b *ulongWrap) CodePrintValue(print apiconvert.ICodePrinter, fieldType *field_type.TableFieldType, fieldName string, reader string, depth int32) string {
diff --git a/examples/conf/config.toml b/examples/conf/config.toml
index 9ee11c9..3efc381 100644
--- a/examples/conf/config.toml
+++ b/examples/conf/config.toml
@@ -69,7 +69,7 @@ Debug.LogError($"[%s] config id not found,id:{%s}");
gen_optimize = true
# 枚举文件路径集,可以支持多个,以及*或**匹配
enum_files = [
- "./cs_bin_config/enum_define/*.toml",
+ "./cs_bin_config/enum_define/**/*.toml",
]
# 枚举,统一添加一个的前缀名,可为空
enum_define_prefix = ""
@@ -81,5 +81,8 @@ Debug.LogError($"[%s] config id not found,id:{%s}");
"KVList_IntInt",
"KVList_IntFloat",
]
-
+ # 用脚本实现的扩展类型
+ script_field_types = [
+ "./cs_bin_config/scripts/ext_field/**/*.js",
+ ]
diff --git a/examples/cs_bin_config/scripts/common/table-lib.js b/examples/cs_bin_config/scripts/common/table-lib.js
new file mode 100644
index 0000000..e71ddd4
--- /dev/null
+++ b/examples/cs_bin_config/scripts/common/table-lib.js
@@ -0,0 +1,19 @@
+const eFieldType = {
+ None: 0,
+ Int: 1,
+ UInt: 2,
+ Long: 3,
+ ULong: 4,
+ Bool: 5,
+ Float: 6,
+ Double: 7,
+ String: 8,
+ Enum: 9,
+ Slice: 10,
+ Map: 11,
+ Class: 12
+}
+
+module.exports = {
+ eFieldType
+}
\ No newline at end of file
diff --git a/examples/cs_bin_config/scripts/ext_field/field-vector3.js b/examples/cs_bin_config/scripts/ext_field/field-vector3.js
new file mode 100644
index 0000000..5e4bea4
--- /dev/null
+++ b/examples/cs_bin_config/scripts/ext_field/field-vector3.js
@@ -0,0 +1,45 @@
+const {eFieldType} = require('../common/table-lib');
+
+const TypeName = "TestVector3";
+
+var ftc = tableEngine.NewTableFieldClass(TypeName);
+ftc.AddField("x", tableEngine.NewTableFieldType(eFieldType.Float));
+ftc.AddField("y", tableEngine.NewTableFieldType(eFieldType.Float));
+ftc.AddField("z", tableEngine.NewTableFieldType(eFieldType.Float));
+
+const fieldType = tableEngine.NewTableFieldClassType(ftc);
+
+const ArraySplit = tableEngine.TableConfig.ArraySplit;
+
+const extFieldVector3 = {
+ Name() {
+ return TypeName;
+ },
+ DefineFile() {
+ return "CfgMath";
+ },
+ TableFieldType() {
+ return fieldType;
+ },
+ ParseOriginData(origin, context) {
+ origin = origin.trim();
+ if (origin.length === 0) {
+ return { x : 0, y: 0, z: 0};
+ }
+ const stringArray = origin.split(ArraySplit);
+ if (stringArray.length === 0) {
+ return { x : 0, y: 0, z: 0};
+ }
+ if (stringArray.length !== 3) {
+ context.Error = "Vector3 Parse Error,param count must be 3 or 0: " + origin;
+ //console.error("js error:" + origin);
+ return null
+ }
+ const x = parseFloat(stringArray[0]);
+ const y = parseFloat(stringArray[1]);
+ const z = parseFloat(stringArray[2]);
+ return { x : x, y: y, z: z};
+ }
+}
+
+module.exports = extFieldVector3;
\ No newline at end of file
diff --git a/examples/cs_bin_config/table_meta/base_test.toml b/examples/cs_bin_config/table_meta/base_test.toml
index 88dce5e..c26f548 100644
--- a/examples/cs_bin_config/table_meta/base_test.toml
+++ b/examples/cs_bin_config/table_meta/base_test.toml
@@ -19,6 +19,7 @@ fields = [
{ active = true, sname = "condition_type" , tname = "conditionType" , type = "ConditionType" , key = 0, desc = "条件类型,测试枚举2"},
{ active = true, sname = "position", tname = "position", type = "PointInt", key = 0, desc = "位置"},
{ active = true, sname = "rewards", tname = "rewards", type = "KVList_IntInt", key = 0, desc = "奖励"},
+ { active = true, sname = "vector3", tname = "vector3", type = "TestVector3", key = 0, desc = "测试使用脚本自定义字段类型" }
]
# 数据检测示例,$代表一行数据,table代表当前表,global代表全局,global[name]可以取到其他表的数据
diff --git a/examples/excels/base_test.xlsx b/examples/excels/base_test.xlsx
index 1ccd565..e307525 100644
Binary files a/examples/excels/base_test.xlsx and b/examples/excels/base_test.xlsx differ
diff --git a/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs b/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs
index cbda6c4..8f51b92 100644
--- a/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs
+++ b/examples/projects/proj_cs_bin/src/gen/CfgCommon.cs
@@ -12,7 +12,6 @@ public partial class KVList_IntInt
public KVList_IntInt(ByteBuf _buf)
{
-
{int __n0 = _buf.ReadSize(); keys = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); keys[__i0] = __v0; } }
{int __n0 = _buf.ReadSize(); values = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); values[__i0] = __v0; } }
PostInit();
@@ -31,7 +30,6 @@ public partial class KVList_IntFloat
public KVList_IntFloat(ByteBuf _buf)
{
-
{int __n0 = _buf.ReadSize(); keys = new int[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int __v0; __v0 = _buf.ReadInt(); keys[__i0] = __v0; } }
{int __n0 = _buf.ReadSize(); values = new float[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ float __v0; __v0 = _buf.ReadFloat(); values[__i0] = __v0; } }
PostInit();
diff --git a/examples/projects/proj_cs_bin/src/gen/CfgMath.cs b/examples/projects/proj_cs_bin/src/gen/CfgMath.cs
index e2c7940..7d185b2 100644
--- a/examples/projects/proj_cs_bin/src/gen/CfgMath.cs
+++ b/examples/projects/proj_cs_bin/src/gen/CfgMath.cs
@@ -12,7 +12,6 @@ public partial class PointInt
public PointInt(ByteBuf _buf)
{
-
x = _buf.ReadInt();
y = _buf.ReadInt();
PostInit();
@@ -24,4 +23,24 @@ public PointInt(ByteBuf _buf)
partial void PostInit();
}
+ public partial class TestVector3
+ {
+ public float x { get; private set; }
+ public float y { get; private set; }
+ public float z { get; private set; }
+
+ public TestVector3(ByteBuf _buf)
+ {
+ x = _buf.ReadFloat();
+ y = _buf.ReadFloat();
+ z = _buf.ReadFloat();
+ PostInit();
+ }
+
+ ///
+ /// post process ext class
+ ///
+ partial void PostInit();
+ }
+
}
diff --git a/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs b/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs
index dd2483e..7482cd9 100644
--- a/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs
+++ b/examples/projects/proj_cs_bin/src/gen/Tblbase_test.cs
@@ -77,6 +77,7 @@ private Cfgbase_test(ByteBuf _buf, _TbCommonbase_test _commonData)
conditionType = (ConditionType)_buf.ReadInt();
{ int dataIndex = _buf.ReadInt() - 1; position = _commonData._field2[dataIndex]; }
{ int dataIndex = _buf.ReadInt() - 1; rewards = _commonData._field3[dataIndex]; }
+ { int dataIndex = _buf.ReadInt() - 1; vector3 = _commonData._field4[dataIndex]; }
PostInit();
}
@@ -130,6 +131,11 @@ internal static Cfgbase_test DeserializeCfgbase_test(ByteBuf _buf, _TbCommonbase
///
public KVList_IntInt rewards { get; private set; }
+ ///
+ /// 测试使用脚本自定义字段类型
+ ///
+ public TestVector3 vector3 { get; private set; }
+
///
/// post process table
@@ -147,6 +153,7 @@ internal class _TbCommonbase_test
internal int[][] _field1 { get; private set; }
internal PointInt[] _field2 { get; private set; }
internal KVList_IntInt[] _field3 { get; private set; }
+ internal TestVector3[] _field4 { get; private set; }
internal _TbCommonbase_test(ByteBuf _buf)
{
@@ -154,6 +161,7 @@ internal _TbCommonbase_test(ByteBuf _buf)
{int __n0 = _buf.ReadSize(); _field1 = new int[__n0][]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ int[] __v0; {int __n1 = _buf.ReadSize(); __v0 = new int[__n1]; for(var __i1 = 0 ; __i1 < __n1 ; __i1++ ){ int __v1; __v1 = _buf.ReadInt(); __v0[__i1] = __v1; } } _field1[__i0] = __v0; } }
{int __n0 = _buf.ReadSize(); _field2 = new PointInt[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ PointInt __v0; __v0 = new PointInt(_buf); _field2[__i0] = __v0; } }
{int __n0 = _buf.ReadSize(); _field3 = new KVList_IntInt[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ KVList_IntInt __v0; __v0 = new KVList_IntInt(_buf); _field3[__i0] = __v0; } }
+ {int __n0 = _buf.ReadSize(); _field4 = new TestVector3[__n0]; for(var __i0 = 0 ; __i0 < __n0 ; __i0++ ){ TestVector3 __v0; __v0 = new TestVector3(_buf); _field4[__i0] = __v0; } }
}
}
diff --git a/examples/projects/proj_cs_bin/table_bytes/base_test.bytes b/examples/projects/proj_cs_bin/table_bytes/base_test.bytes
index a538ba2..df4c060 100644
Binary files a/examples/projects/proj_cs_bin/table_bytes/base_test.bytes and b/examples/projects/proj_cs_bin/table_bytes/base_test.bytes differ
diff --git a/export/common/export_util.go b/export/common/export_util.go
index a91ea6e..ae8d7fe 100644
--- a/export/common/export_util.go
+++ b/export/common/export_util.go
@@ -7,11 +7,12 @@ import (
"github.com/821869798/table-export/data/env"
"github.com/821869798/table-export/data/model"
"github.com/821869798/table-export/ext"
+ "github.com/821869798/table-export/ext/ext_scripts"
"github.com/821869798/table-export/meta"
"github.com/BurntSushi/toml"
+ "github.com/bmatcuk/doublestar/v4"
"github.com/gookit/slog"
"os"
- "path/filepath"
"sync"
)
@@ -21,9 +22,9 @@ func ExportPlusCommon(tableMetas []*meta.RawTableMeta, rulePlus config.MetaRuleU
var enumFiles = rulePlus.GetEnumFiles()
rawEnumConfigs := make([]*config.RawMetaEnumConfig, 0, len(enumFiles))
for _, p := range enumFiles {
- matches, err := filepath.Glob(p)
+ matches, err := doublestar.FilepathGlob(p)
if err != nil {
- slog.Fatalf("Enum Files laod error filePath:%s err:%v", p, err)
+ slog.Fatalf("Enum Files load error filePath:%s err:%v", p, err)
}
for _, m := range matches {
fullPath := fanpath.AbsOrRelExecutePath(m)
@@ -52,7 +53,26 @@ func ExportPlusCommon(tableMetas []*meta.RawTableMeta, rulePlus config.MetaRuleU
}
}
- // TODO 加载自定义解析脚本
+ // 添加脚本实现的扩展类型
+ for _, extFieldScriptPath := range rulePlus.GetExtFieldTypeScriptPath() {
+ matches, err := doublestar.FilepathGlob(extFieldScriptPath)
+ if err != nil {
+ slog.Fatalf("Ext Script path glob error filePath:%s err:%v", extFieldScriptPath, err)
+ os.Exit(1)
+ }
+ for _, m := range matches {
+ extFieldType, err := ext_scripts.NewExtFieldJS(m)
+ if err != nil {
+ slog.Fatalf("Ext Script Files laod error filePath:%s err:%v", m, err)
+ os.Exit(1)
+ }
+ err = env.AddExtFieldType(extFieldType)
+ if err != nil {
+ slog.Fatalf("add ext field type error:%v", err)
+ os.Exit(1)
+ }
+ }
+ }
//实际开始转换
allDataModel := LoadTableModelPlusParallel(tableMetas, rulePlus, nil)
diff --git a/export/cs_bin/template_cs_bin.go b/export/cs_bin/template_cs_bin.go
index 80b5b6a..e5f72e0 100644
--- a/export/cs_bin/template_cs_bin.go
+++ b/export/cs_bin/template_cs_bin.go
@@ -131,7 +131,7 @@ namespace {{.NameSpace}}
public {{$.ClassDefinePrefix}}{{$classType.Name}}(ByteBuf _buf)
{
-{{ range $v := $classType.Fields }}
+{{- range $v := $classType.Fields }}
{{CSbinFieldReader $v.FieldType $v.Name "_buf" }}
{{- end }}
PostInit();
diff --git a/ext/ext_scripts/ext_field_goja.go b/ext/ext_scripts/ext_field_goja.go
new file mode 100644
index 0000000..d6beb4f
--- /dev/null
+++ b/ext/ext_scripts/ext_field_goja.go
@@ -0,0 +1,85 @@
+package ext_scripts
+
+import (
+ "errors"
+ "fmt"
+ "github.com/821869798/fankit/fanpath"
+ "github.com/821869798/table-export/component/goja/table_engine"
+ "github.com/821869798/table-export/field_type"
+ "github.com/dop251/goja"
+ "github.com/dop251/goja_nodejs/console"
+ "github.com/dop251/goja_nodejs/require"
+ "sync"
+)
+
+// ExtFieldJS 通过js脚本扩展字段类型
+type ExtFieldJS struct {
+ FieldType *field_type.TableFieldType
+ ScriptPath string
+ jsResult *jsScriptResult
+ Error string
+ mutex sync.Mutex
+}
+
+type jsScriptResult struct {
+ Name string
+ DefineFile string
+ ParseFunc func(string, *ExtFieldJS) interface{}
+ TableFieldType func() *field_type.TableFieldType
+}
+
+func NewExtFieldJS(scripPath string) (field_type.IExtFieldType, error) {
+
+ e := &ExtFieldJS{
+ ScriptPath: scripPath,
+ jsResult: &jsScriptResult{},
+ }
+ registry := require.NewRegistry(require.WithGlobalFolders(fanpath.ExecuteParentPath()))
+
+ vm := goja.New()
+ _ = registry.Enable(vm)
+ console.Enable(vm)
+ table_engine.Enable(vm)
+
+ var script = fmt.Sprintf("const extField = require(\"%s\");\n", e.ScriptPath) +
+ `const result = { Name: extField.Name(),DefineFile: extField.DefineFile(),TableFieldType: extField.TableFieldType, ParseFunc: extField.ParseOriginData};
+result;`
+ res, err := vm.RunString(script)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := vm.ExportTo(res, e.jsResult); err != nil {
+ return nil, err
+ }
+
+ e.FieldType = e.jsResult.TableFieldType()
+ e.FieldType.SetExtFieldType(e)
+
+ return e, nil
+}
+
+func (e *ExtFieldJS) Name() string {
+ return e.jsResult.Name
+}
+
+func (e *ExtFieldJS) DefineFile() string {
+ return e.jsResult.DefineFile
+}
+
+func (e *ExtFieldJS) TableFieldType() *field_type.TableFieldType {
+ return e.FieldType
+}
+
+func (e *ExtFieldJS) ParseOriginData(origin string) (interface{}, error) {
+ // goja 不支持线程安全
+ e.mutex.Lock()
+ defer e.mutex.Unlock()
+
+ e.Error = ""
+ result := e.jsResult.ParseFunc(origin, e)
+ if e.Error != "" {
+ return nil, errors.New(e.Error)
+ }
+ return result, nil
+}
diff --git a/go.mod b/go.mod
index 202997f..1851cde 100644
--- a/go.mod
+++ b/go.mod
@@ -5,12 +5,18 @@ go 1.21
require (
github.com/821869798/fankit v0.0.6
github.com/BurntSushi/toml v1.3.2
+ github.com/bmatcuk/doublestar/v4 v4.6.1
+ github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e
+ github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c
github.com/expr-lang/expr v1.15.8
github.com/gookit/slog v0.5.4
github.com/xuri/excelize/v2 v2.8.0
)
require (
+ github.com/dlclark/regexp2 v1.10.0 // indirect
+ github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+ github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/gookit/goutil v0.6.12 // indirect
github.com/gookit/gsr v0.1.0 // indirect
@@ -21,9 +27,9 @@ require (
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
- golang.org/x/crypto v0.12.0 // indirect
- golang.org/x/net v0.14.0 // indirect
+ golang.org/x/crypto v0.14.0 // indirect
+ golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.11.0 // indirect
- golang.org/x/text v0.12.0 // indirect
+ golang.org/x/sys v0.13.0 // indirect
+ golang.org/x/text v0.13.0 // indirect
)
diff --git a/go.sum b/go.sum
index 8c91382..ed78dcc 100644
--- a/go.sum
+++ b/go.sum
@@ -2,11 +2,33 @@ github.com/821869798/fankit v0.0.6 h1:WnBBUMwIB+zyqtpJSxx8JD8j+CprDE0KrJZGrO9U5Q
github.com/821869798/fankit v0.0.6/go.mod h1:73w1EUt6i92eswVBeuUVVmHtjidOqcVsmwL3beokqQA=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
+github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
+github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
+github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
+github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e h1:lCjFpJwrCCaDOyQ4RKYNOIexG+yrjxai//OlcMQEGqg=
+github.com/dop251/goja v0.0.0-20231014103939-873a1496dc8e/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
+github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
+github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c h1:hLoodLRD4KLWIH8eyAQCLcH8EqIrjac7fCkp/fHnvuQ=
+github.com/dop251/goja_nodejs v0.0.0-20231122114759-e84d9a924c5c/go.mod h1:bhGPmCgCCTSRfiMYWjpS46IDo9EUZXlsuUaPXSWGbv0=
github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI=
github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
+github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
+github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
+github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ=
+github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/gookit/goutil v0.6.12 h1:73vPUcTtVGXbhSzBOFcnSB1aJl7Jq9np3RAE50yIDZc=
@@ -15,6 +37,13 @@ github.com/gookit/gsr v0.1.0 h1:0gadWaYGU4phMs0bma38t+Do5OZowRMEVlHv31p0Zig=
github.com/gookit/gsr v0.1.0/go.mod h1:7wv4Y4WCnil8+DlDYHBjidzrEzfHhXEoFjEA0pPPWpI=
github.com/gookit/slog v0.5.4 h1:EMctf/kap/SR8cnhkUucL0D3YZwUAJJ+WKQ/DN6kS5s=
github.com/gookit/slog v0.5.4/go.mod h1:awroa12zroMvjFpS7tdpTX12AqIzVewUlC10tsj4TYY=
+github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -24,6 +53,7 @@ github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -44,8 +74,9 @@ github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
@@ -57,8 +88,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -67,12 +99,14 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -80,17 +114,25 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=