diff --git a/README.md b/README.md
index 42cf877..5f478c1 100644
--- a/README.md
+++ b/README.md
@@ -10,28 +10,598 @@

+-------
+
## 介绍
-Luban 是一个强大的配置生成与缓存工具。该工具最初是为了解决传统 excel 导出工具功能过于薄弱,无法很好处理 MMORPG 游戏复杂配置需求的痛点问题。工具生成的目标可以是常规代码、配置数据、类似 protobuf 的消息代码,也可以是游戏资源如 assetbundle。
+Luban是一个强大的对象生成与缓存工具。生成目标可以是类似protobuf的消息代码、游戏配置代码、游戏配置数据、数据库代码,也可以是游戏资源如assetbundle。
-在大型项目中,由于配置或资源数据庞大,生成对象可能会花费相当多的时间。比如一个典型的 MMORPG 项目,后期全量生成配置,即使用了多线程加速,所需时间也在 10 秒的级别。Luban 在优化过程中,除了使用缓存,还使用了 client/server 模式,来加速生成过程。
+Luban适合有以下需求的开发者:
+1. 无法容忍传统excel导表工具的简陋功能,希望找一个快速强大经受过上线项目检验的满足中大型游戏项目配置需求的游戏配置解决方案
+2. 不想使用protobuf,希望针对项目需求方便地自定义消息生成,满足严苛的内存和性能的要求
+3. 希望做其他自定义生成或者缓存
-自2015年以来,Luban 经历过 MMORPG、卡牌、SLG 等多个上线项目的考验,实际项目过程中不断迭代和优化,最终由一个增强型的配置工具成为一个相对完备的游戏配置数据解决方案。
+Luban另一优点是生成过程极快。对于普通的导表工作,一个典型的MMORPG项目后期全量生成配置往往需要几十秒。Luban使用client/server的云生成模式,多线程生成+对象缓存,大多数情况下可以1s内完成整个生成过程 ^_^。
-## 快速生成 lua 的例子
+------
+## 文档
+
+- [主页](https://focus-creative-games.github.io/luban/index.html)
+- [特性](docs/traits.md)
+- [Excel 配置数据简介](docs/data_excel.md)
+- [使用说明](docs/catalog.md)
+- [常见问题](docs/faq.md)
+
+------
+## 特性
+- 支持增强的excel格式,可以在excel里比较简洁填写出任意复杂的数据。
+- 支持excel族、json、xml、lua 多种数据格式
+- 强大完备的类型系统。支持所有常见原生类型、容器类型list,set,map、枚举和结构、**多态结构**以及**可空类型**
+- 灵活的数据源定义。一个表可以来自多个文件,或者一个文件内定义多个表或者一个表对应一个目录下所有文件。以及以上的组合
+- 支持表与字段级别分组。可以选择性地导出客户端或者服务器所用的表及字段。
+- 多种导出数据格式支持。支持binary、json、lua 等导出数据格式。
+- 支持数据标签。 可以选择导出符合要求的数据,发布正式数据时策划不必手动注释掉那些测试或者非正式数据了。
+- 强大的数据校验能力。支持内建数据格式检查。支持ref表引用检查(策划不用担心填错id)。支持path资源检查(策划不用担心填错资源路径)。
+- 支持 one(单例表)、map(常规key-value表)、bmap(双键表)
+- 支持时间本地化。datetime类型数据会根据指定的timezone,转换为目标地区该时刻的UTC时间,方便程序使用。
+- [TODO] 支持文本静态本地化。导出时所有text类型数据正确替换为最终的本地化字符串。
+- [TODO] 支持文本动态本地化。运行时动态切换所有text类型数据为目标本地化字符串。
+- [TODO] 支持main + braches 多分支数据。对于不同地区配置有少量区别的海外项目非常有用。
+- 支持 emmylua anntations。生成的lua包含符合emmylua 格式anntations信息。配合emmylua有良好的配置代码提示能力。
+- 支持 res 资源标记。可以一键导出配置中引用的所有资源列表(icon,ui,assetbundle等等)
+- 生成代码良好模块化。
+- 配置数据模块化。策划可以方便地按需求自己组织数据目录和结构,不影响逻辑表。
+- 支持主流的游戏开发语言
+ - c++ (11+)
+ - c# (.net framework 4+. dotnet core 3+)
+ - java (1.6+)
+ - go (1.10+)
+ - lua (5.1+)
+ - js 和 typescript (3.0+)
+ - python (2.7+ 及 3.0+)
+
+- 支持主流引擎和平台
+ - unity + c#
+ - unity + tolua,xlua
+ - unity + ILRuntime
+ - unreal + c++
+ - unreal + unlua
+ - unreal + sluaunreal
+ - unreal + puerts
+ - cocos2d-x + lua
+ - cocos2d-x + js
+ - 微信小程序平台
+ - 其他家基于js的小程序平台
+ - 其他所有支持lua的引擎和平台
+ - 其他所有支持js的引擎和平台
+
+--------
+
+
+
+## 快速入门 - 结构定义和数据配置
+
+ luban创新性提出 定义+数据源 的概念设计,配合完备的类型系统及多种数据源支持,基本解决了中大弄项目中难以配置复杂数据以及excel、json等多种配置方案不统一的问题。与常见的专注于excel的导表工具把定义和数据放在同一个excel文件的做法不同,luban的定义与数据分离,使用单独的xml定义 **表和结构**。
+
+------
+### 常规的原生数据
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+------
+
+### 枚举
+
+```
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+------
+
+### 自定义结构 bean
+
+```
+
+
+
+
+
+
+
+
+
+```
+
+
+
+------
+
+### 多态结构 bean
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+------
+
+### 可空数据类型
+除了string外的所有原生数据类型,以及enum类型都有相应的可空数据类型。定义方式为 <类型名>?,与c#里的Nullable类型定义方式相同。例如 bool?,int?,long?,double?, EColor?
+
+```
+
+
+
+
+
+```
+
+
+
+------
+
+### 简单列表
+```
+
+
+
+
+
+```
+
+
+
+### 结构列表
+对于结构列表类型,有多种填写。根据策划的偏好,可以自由选择最合适的填法。
+
+- 填法1。 全展开。
+
+```
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+- 填法2。 每个Item在一个单元格内
+
+```
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+- 填法3。所有数据都在一个单元格内
+```
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+------
+### 多态结构列表
+```
+
+
+
+
+```
+
+------
+
+### 双主键表
+```
+
+
+
+
+
+
+```
+
+
+------
+
+### 单例表
+
+单例既代码模式中单例的含义,用于配置全局只有一份的数据。
+
+```
+
+
+
+
+
+
+```
+
+
+------
+
+
+### json 数据源
+
+定义
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 多态数据结构
+
+
+
+
+
+
+
+ 使用;来分隔
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+数据
+以目录为数据源,递归遍历整个目录树,将每个json数据当作一个记录读入。
+
+
+
+其中 1.json 文件内容如下
+
+```
+ {
+ "x1":true,
+ "x2":3,
+ "x3":128,
+ "x4":1,
+ "x5":11223344,
+ "x6":1.2,
+ "x7":1.23432,
+ "x8_0":12312,
+ "x8":112233,
+ "x9":223344,
+ "x10":"hq",
+ "x12": { "x1":10},
+ "x13":"B",
+ "x14":{"__type__": "DemoD2", "x1":1, "x2":2},
+ "v2":{"x":1, "y":2},
+ "v3":{"x":1.1, "y":2.2, "z":3.4},
+ "v4":{"x":10.1, "y":11.2, "z":12.3, "w":13.4},
+ "t1":"1970-01-01 00:00:00",
+ "k1":[1,2],
+ "k2":[2,3],
+ "k3":[1,3],
+ "k4":[1,5],
+ "k5":[1,6],
+ "k6":[1,7],
+ "k7":[2,3],
+ "k8":[[2,2],[4,10]],
+ "k9":[{"y1":1, "y2":true},{"y1":2, "y2":false}],
+ "k15":[{"__type__": "DemoD2", "x1":1, "x2":2}]
+ }
+```
+--------
+### xml 数据源
+定义
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 多态数据结构
+
+
+
+
+
+
+
+ 使用;来分隔
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+数据
+
+以目录为数据源,递归遍历整个目录树,将每个xml数据当作一个记录读入。
+其中 1.xml 文件内容如下
+```
+
+ true
+ 4
+ 128
+ 1
+ 112233445566
+ 1.3
+ 1112232.43123
+ 112233
+ 123
+ 112334
+ yf
+
+ 1
+
+ C
+
+ 1
+ 2
+
+ 1,2
+ 1.2,2.3,3.4
+ 1.2,2.2,3.2,4.3
+ 1970-01-01 00:00:00
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 3
+
+
+ - 210
+ - 330
+
+
+ -
+ 1
+ true
+
+ -
+ 2
+ false
+
+
+
+ -
+ 1
+ 2
+
+
+
+```
+### json 数据源
+
+定义
+
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 多态数据结构
+
+
+
+
+
+
+
+ 使用;来分隔
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+数据
+以目录为数据源,递归遍历整个目录树,将每个lua数据当作一个记录读入。
+
+其中 1.lua 文件内容如下
+
+```
+ return
+{
+ x1 = false,
+ x2 = 2,
+ x3 = 128,
+ x4 = 1122,
+ x5 = 112233445566,
+ x6 = 1.3,
+ x7 = 1122,
+ x8 = 12,
+ x8_0 = 13,
+ x9 = 123,
+ x10 = "yf",
+ x12 = {x1=1},
+ x13 = "D",
+ x14 = { __type__="DemoD2", x1 = 1, x2=3},
+ v2 = {x= 1,y = 2},
+ v3 = {x=0.1, y= 0.2,z=0.3},
+ v4 = {x=1,y=2,z=3.5,w=4},
+ t1 = "1970-01-01 00:00:00",
+ k1 = {1,2},
+ k2 = {2,3},
+ k3 = {3,4},
+ k4 = {1,2},
+ k5 = {1,3},
+ k6 = {1,2},
+ k7 = {1,8},
+ k8 = {[2]=10,[3]=12},
+ k9 = {{y1=1,y2=true}, {y1=10,y2=false}},
+ k15 = {{ __type__="DemoD2", x1 = 1, x2=3}},
+}
+```
+------
+## 生成代码与数据
+以lua为例:
1) 进入 config 目录
2) 双击 生成 lua 数据.bat
3) 生成的 output_lua 目录即对像数据
4) 修改 bat 脚本路径,即可使用至项目中
-
-## 使用示例
-- 配置示例
- 
+-----
+## 程序使用示例
- Lua 使用示例
```Lua
- local data = require("TbDataFromJson")
+ local data = require("TbItem")
local cfg = data[32]
print(cfg.name)
```
@@ -41,21 +611,15 @@ Luban 是一个强大的配置生成与缓存工具。该工具最初是为了
// 一行代码可以加载所有配置。 cfg.Tables 包含所有表的一个实例字段。
var tables = new cfg.Tables(file => return new ByteBuf(File.ReadAllBytes("output_data/" + file)));
// 访问一个单例表
- Console.WriteLine(tables.TbSingleton.Name);
+ Console.WriteLine(tables.TbGlobal.Name);
// 访问普通的 key-value 表
- Console.WriteLine(tables.TbDataFromJson.Get(12).X1);
+ Console.WriteLine(tables.TbItem.Get(12).X1);
// 访问 双键表
Console.WriteLine(tables.TbTwoKey.Get(1, 10).X8);
```
- [更多语言的例子](docs/samples.md)
-## 文档
-- [主页](https://focus-creative-games.github.io/luban/index.html)
-- [特性](docs/traits.md)
-- [Excel 配置数据简介](docs/data_excel.md)
-- [使用说明](docs/catalog.md)
-- [常见问题](docs/faq.md)
## 路线图
@@ -77,8 +641,6 @@ Luban 是一个强大的配置生成与缓存工具。该工具最初是为了
## 有用的链接
- [.NET Core source index](https://source.dot.net)
-- 社区的其它实现
- - [tabtoy](https://github.com/davyxu/tabtoy)
## 支持和联系
diff --git a/config/Datas/test/json_datas/tb_role.json b/config/Datas/test/json_datas/1.json
similarity index 97%
rename from config/Datas/test/json_datas/tb_role.json
rename to config/Datas/test/json_datas/1.json
index faa901b..873e9b9 100644
--- a/config/Datas/test/json_datas/tb_role.json
+++ b/config/Datas/test/json_datas/1.json
@@ -2,7 +2,7 @@
"x1":true,
"x2":3,
"x3":128,
- "x4":1211,
+ "x4":1,
"x5":11223344,
"x6":1.2,
"x7":1.23432,
diff --git a/config/Datas/test/json_datas/2.json b/config/Datas/test/json_datas/2.json
new file mode 100644
index 0000000..d3be8bb
--- /dev/null
+++ b/config/Datas/test/json_datas/2.json
@@ -0,0 +1,30 @@
+ {
+ "x1":true,
+ "x2":3,
+ "x3":128,
+ "x4":2,
+ "x5":11223344,
+ "x6":1.2,
+ "x7":1.23432,
+ "x8_0":12312,
+ "x8":112233,
+ "x9":223344,
+ "x10":"hq",
+ "x12": { "x1":10},
+ "x13":"B",
+ "x14":{"__type__": "DemoD2", "x1":1, "x2":2},
+ "v2":{"x":1, "y":2},
+ "v3":{"x":1.1, "y":2.2, "z":3.4},
+ "v4":{"x":10.1, "y":11.2, "z":12.3, "w":13.4},
+ "t1":"1970-01-01 00:00:00",
+ "k1":[1,2],
+ "k2":[2,3],
+ "k3":[1,3],
+ "k4":[1,5],
+ "k5":[1,6],
+ "k6":[1,7],
+ "k7":[2,3],
+ "k8":[[2,2],[4,10]],
+ "k9":[{"y1":1, "y2":true},{"y1":2, "y2":false}],
+ "k15":[{"__type__": "DemoD2", "x1":1, "x2":2}]
+ }
\ No newline at end of file
diff --git a/config/Datas/test/xml_datas/demo.xml b/config/Datas/test/xml_datas/1.xml
similarity index 97%
rename from config/Datas/test/xml_datas/demo.xml
rename to config/Datas/test/xml_datas/1.xml
index 13f9422..b789737 100644
--- a/config/Datas/test/xml_datas/demo.xml
+++ b/config/Datas/test/xml_datas/1.xml
@@ -2,7 +2,7 @@
true
4
128
- 1122
+ 1
112233445566
1.3
1112232.43123
diff --git a/config/Datas/test/xml_datas/2.xml b/config/Datas/test/xml_datas/2.xml
new file mode 100644
index 0000000..7b0ffbf
--- /dev/null
+++ b/config/Datas/test/xml_datas/2.xml
@@ -0,0 +1,78 @@
+
+ true
+ 4
+ 128
+ 2
+ 112233445566
+ 1.3
+ 1112232.43123
+ 112233
+ 123
+ 112334
+ yf
+
+ 1
+
+ C
+
+ 1
+ 2
+
+
+ 1,2
+ 1.2,2.3,3.4
+ 1.2,2.2,3.2,4.3
+
+ 1970-01-01 00:00:00
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 2
+
+
+ - 1
+ - 3
+
+
+
+ - 210
+ - 330
+
+
+
+ -
+ 1
+ true
+
+ -
+ 2
+ false
+
+
+
+ -
+ 1
+ 2
+
+
+
\ No newline at end of file
diff --git a/config/Defines/test.xml b/config/Defines/test.xml
index 0b64bf5..08bcb66 100644
--- a/config/Defines/test.xml
+++ b/config/Defines/test.xml
@@ -42,10 +42,10 @@
+
-
@@ -79,7 +79,6 @@
最常见的普通 key-value表
-
@@ -144,35 +143,21 @@
-
+
-
-
- 多态数据结构
-
-
-
- 使用;来分隔
-
-
+
diff --git a/config/demo_defs.xml b/config/demo_defs.xml
new file mode 100644
index 0000000..099963c
--- /dev/null
+++ b/config/demo_defs.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/output_lua/TbDataFromJson.lua b/config/output_lua/TbDataFromJson.lua
new file mode 100644
index 0000000..3c1ad34
--- /dev/null
+++ b/config/output_lua/TbDataFromJson.lua
@@ -0,0 +1,5 @@
+return
+{
+[1] = {x4=1,x1=true,x2=3,x3=128,x5=11223344,x6=1.2,x7=1.23432,x8_0=12312,x8=112233,x9=223344,x10='hq',x12={x1=10,},x13=2,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.1,y=2.2,z=3.4},v4={x=10.1,y=11.2,z=12.3,w=13.4},t1=-28800,k1={1,2,},k2={2,3,},k3={1,3,},k4={1,5,},k5={1,6,},k6={1,7,},k7={2,3,},k8={[2]=2,[4]=10,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+[2] = {x4=2,x1=true,x2=3,x3=128,x5=11223344,x6=1.2,x7=1.23432,x8_0=12312,x8=112233,x9=223344,x10='hq',x12={x1=10,},x13=2,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.1,y=2.2,z=3.4},v4={x=10.1,y=11.2,z=12.3,w=13.4},t1=-28800,k1={1,2,},k2={2,3,},k3={1,3,},k4={1,5,},k5={1,6,},k6={1,7,},k7={2,3,},k8={[2]=2,[4]=10,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbDataFromLua.lua b/config/output_lua/TbDataFromLua.lua
new file mode 100644
index 0000000..47cc016
--- /dev/null
+++ b/config/output_lua/TbDataFromLua.lua
@@ -0,0 +1,4 @@
+return
+{
+[1122] = {x4=1122,x1=false,x2=2,x3=128,x5=112233445566,x6=1.3,x7=1122,x8_0=13,x8=12,x9=123,x10='yf',x12={x1=1,},x13=5,x14={ _name='test.DemoD2',x1=1,x2=3,},v2={x=1,y=2},v3={x=0.1,y=0.2,z=0.3},v4={x=1,y=2,z=3.5,w=4},t1=-28800,k1={1,2,},k2={2,3,},k3={3,4,},k4={1,2,},k5={1,3,},k6={1,2,},k7={1,8,},k8={[2]=10,[3]=12,},k9={{y1=1,y2=true,},{y1=10,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=3,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbDataFromXml.lua b/config/output_lua/TbDataFromXml.lua
new file mode 100644
index 0000000..5d3b12d
--- /dev/null
+++ b/config/output_lua/TbDataFromXml.lua
@@ -0,0 +1,5 @@
+return
+{
+[1] = {x4=1,x1=true,x2=4,x3=128,x5=112233445566,x6=1.3,x7=1112232.43123,x8_0=123,x8=112233,x9=112334,x10='yf',x12={x1=1,},x13=4,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.2,y=2.3,z=3.4},v4={x=1.2,y=2.2,z=3.2,w=4.3},t1=-28800,k1={1,2,},k2={1,2,},k3={1,2,},k4={1,2,},k5={1,2,},k6={1,2,},k7={1,3,},k8={[2]=10,[3]=30,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+[2] = {x4=2,x1=true,x2=4,x3=128,x5=112233445566,x6=1.3,x7=1112232.43123,x8_0=123,x8=112233,x9=112334,x10='yf',x12={x1=1,},x13=4,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.2,y=2.3,z=3.4},v4={x=1.2,y=2.2,z=3.2,w=4.3},t1=-28800,k1={1,2,},k2={1,2,},k3={1,2,},k4={1,2,},k5={1,2,},k6={1,2,},k7={1,3,},k8={[2]=10,[3]=30,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbFullTypes.lua b/config/output_lua/TbFullTypes.lua
new file mode 100644
index 0000000..955f7ab
--- /dev/null
+++ b/config/output_lua/TbFullTypes.lua
@@ -0,0 +1,11 @@
+return
+{
+[1] = {x4=10000,x1=true,x2=5,x3=1,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=935460549,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=3,},},},
+[3] = {x4=10001,x1=true,x2=5,x3=3,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=935460549,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=5,},},},
+[4] = {x4=10002,x1=true,x2=5,x3=4,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=1577808000,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=6,},},},
+[5] = {x4=10003,x1=true,x2=5,x3=5,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=935460549,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=7,},},},
+[6] = {x4=10001,x1=true,x2=5,x3=6,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=1577808000,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=8,},},},
+[7] = {x4=10002,x1=true,x2=5,x3=7,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=935460549,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=9,},},},
+[8] = {x4=10003,x1=true,x2=5,x3=8,x5=2,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=1577808000,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=10,},},},
+[9] = {x4=1,x1=true,x2=5,x3=9,x5=13234234234,x6=1.28,x7=1.23457891,x8_0=1234,x8=1234,x9=111111111,x10='huang',x12={x1=1988,},x13=1,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=2,y=3,z=4},v4={x=10.2,y=2.3,z=3.4,w=12.8},t1=935460549,k1={1,2,3,},k2={1,2,4,},k3={1,2,5,},k4={1,2,6,},k5={1,2,7,},k6={1,2,8,},k7={1,2,9,},k8={[1]=2,[3]=4,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},{ _name='test.DemoE1',x1=1,x3=2,x4=11,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbMultiRowRecord.lua b/config/output_lua/TbMultiRowRecord.lua
new file mode 100644
index 0000000..f593027
--- /dev/null
+++ b/config/output_lua/TbMultiRowRecord.lua
@@ -0,0 +1,6 @@
+return
+{
+[1] = {id=1,name='xxx',one_rows={{id=1,x=2,},},multi_rows1={{id=1,x=2,},},multi_rows2={{id=1,x=2,},},multi_rows3={{id=1,x=2,y=3,},},multi_rows4={[1]={id=1,x=2,y=3,},},},
+[2] = {id=2,name='xxx',one_rows={{id=2,x=4,},},multi_rows1={{id=2,x=4,},},multi_rows2={{id=3,x=4,},{id=3,x=4,},},multi_rows3={{id=2,x=3,y=4,},{id=2,x=3,y=4,},},multi_rows4={[2]={id=4,x=5,y=4,},},},
+[3] = {id=3,name='ds',one_rows={{id=1,x=2,},},multi_rows1={{id=1,x=2,},{id=2,x=4,},},multi_rows2={{id=3,x=4,},{id=3,x=4,},},multi_rows3={{id=1,x=2,y=3,},{id=2,x=3,y=4,},},multi_rows4={[1]={id=1,x=2,y=3,},[2]={id=4,x=5,y=4,},[3]={id=4,x=5,y=4,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbMultiRowTitle.lua b/config/output_lua/TbMultiRowTitle.lua
new file mode 100644
index 0000000..c5ce13f
--- /dev/null
+++ b/config/output_lua/TbMultiRowTitle.lua
@@ -0,0 +1,4 @@
+return
+{
+[1] = {id=1,name='xxx',x1={y2={z2=2,z3=3,},y3=4,},x2={{z2=1,z3=2,},{z2=3,z3=4,},},x3={{z2=1,z3=2,},{z2=3,z3=4,},},},
+}
\ No newline at end of file
diff --git a/config/output_lua/TbSingleton.lua b/config/output_lua/TbSingleton.lua
new file mode 100644
index 0000000..acb8f3e
--- /dev/null
+++ b/config/output_lua/TbSingleton.lua
@@ -0,0 +1,2 @@
+return
+{id=5,name='aabbcc',date={ _name='test.DemoD5',x1=1,time={start_time=398966400,end_time=936806400,},},}
\ No newline at end of file
diff --git a/config/output_lua/TbTwoKey.lua b/config/output_lua/TbTwoKey.lua
new file mode 100644
index 0000000..3fc4f5d
--- /dev/null
+++ b/config/output_lua/TbTwoKey.lua
@@ -0,0 +1,8 @@
+return
+{
+[128] =
+{
+[1] = {x4=1,x1=true,x2=3,x3=128,x5=11223344,x6=1.2,x7=1.23432,x8_0=12312,x8=112233,x9=223344,x10='hq',x12={x1=10,},x13=2,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.1,y=2.2,z=3.4},v4={x=10.1,y=11.2,z=12.3,w=13.4},t1=-28800,k1={1,2,},k2={2,3,},k3={1,3,},k4={1,5,},k5={1,6,},k6={1,7,},k7={2,3,},k8={[2]=2,[4]=10,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+[2] = {x4=2,x1=true,x2=3,x3=128,x5=11223344,x6=1.2,x7=1.23432,x8_0=12312,x8=112233,x9=223344,x10='hq',x12={x1=10,},x13=2,x14={ _name='test.DemoD2',x1=1,x2=2,},v2={x=1,y=2},v3={x=1.1,y=2.2,z=3.4},v4={x=10.1,y=11.2,z=12.3,w=13.4},t1=-28800,k1={1,2,},k2={2,3,},k3={1,3,},k4={1,5,},k5={1,6,},k6={1,7,},k7={2,3,},k8={[2]=2,[4]=10,},k9={{y1=1,y2=true,},{y1=2,y2=false,},},k15={{ _name='test.DemoD2',x1=1,x2=2,},},},
+},
+}
\ No newline at end of file
diff --git a/config/output_lua/Types.lua b/config/output_lua/Types.lua
new file mode 100644
index 0000000..9ddd9c8
--- /dev/null
+++ b/config/output_lua/Types.lua
@@ -0,0 +1,331 @@
+
+--[[------------------------------------------------------------------------------
+--
+-- This code was generated by a tool.
+-- Changes to this file may cause incorrect behavior and will be lost if
+-- the code is regenerated.
+--
+--]]------------------------------------------------------------------------------
+
+
+
+local consts =
+{
+ ---@class test.DemoConst
+ ---@field public x1 int
+ ---@field public x2 long
+ ---@field public x3 float
+ ---@field public x4 double
+ ['test.DemoConst'] = { x1=0, x2=3242, x3=444.3, x4=55.3, };
+}
+
+local enums =
+{
+ ---@class test.DemoEnum
+ ---@field public A int
+ ---@field public B int
+ ---@field public C int
+ ---@field public D int
+ ['test.DemoEnum'] = { A=1, B=2, C=4, D=5, };
+ ---@class test.ETestUeType
+ ---@field public WHITE int
+ ---@field public BLACK int
+ ['test.ETestUeType'] = { WHITE=0, BLACK=1, };
+ ---@class test.ETestEmptyEnum
+ ['test.ETestEmptyEnum'] = { };
+ ---@class test.ETestEmptyEnum2
+ ---@field public SMALL_THAN_256 int
+ ---@field public X_256 int
+ ---@field public X_257 int
+ ['test.ETestEmptyEnum2'] = { SMALL_THAN_256=255, X_256=256, X_257=257, };
+}
+
+local beans = {}
+---@class test.DemoType1
+---@field public x1 int
+beans['test.DemoType1'] =
+{
+ { name='x1', type='int'},
+}
+
+---@class test.DemoDynamic
+---@field public x1 int
+beans['test.DemoDynamic'] =
+{
+ { name='x1', type='int'},
+}
+
+---@class test.DemoD2 :test.DemoDynamic
+---@field public x2 int
+beans['test.DemoD2'] =
+{
+ { name='x1', type='int'},
+ { name='x2', type='int'},
+}
+
+---@class test.DemoD3 :test.DemoDynamic
+---@field public x3 int
+beans['test.DemoD3'] =
+{
+ { name='x1', type='int'},
+ { name='x3', type='int'},
+}
+
+---@class test.DemoE1 :test.DemoD3
+---@field public x4 int
+beans['test.DemoE1'] =
+{
+ { name='x1', type='int'},
+ { name='x3', type='int'},
+ { name='x4', type='int'},
+}
+
+---@class test.DemoD5 :test.DemoDynamic
+---@field public time test.DateTimeRange
+beans['test.DemoD5'] =
+{
+ { name='x1', type='int'},
+ { name='time', type='test.DateTimeRange'},
+}
+
+---@class test.DemoE2
+---@field public y1 int
+---@field public y2 bool
+beans['test.DemoE2'] =
+{
+ { name='y1', type='int'},
+ { name='y2', type='bool'},
+}
+
+---@class test.DemoType2
+---@field public x4 int
+---@field public x1 bool
+---@field public x2 byte
+---@field public x3 short
+---@field public x5 long
+---@field public x6 float
+---@field public x7 double
+---@field public x8_0 short
+---@field public x8 int
+---@field public x9 long
+---@field public x10 string
+---@field public x12 test.DemoType1
+---@field public x13 test.DemoEnum
+---@field public x14 test.DemoDynamic
+---@field public v2 vector2
+---@field public v3 vector3
+---@field public v4 vector4
+---@field public t1 int
+---@field public k1 int[]
+---@field public k2 int[]
+---@field public k3 int[]
+---@field public k4 int[]
+---@field public k5 int[]
+---@field public k6 int[]
+---@field public k7 int[]
+---@field public k8 table
+---@field public k9 test.DemoE2[]
+---@field public k15 test.DemoDynamic[]
+beans['test.DemoType2'] =
+{
+ { name='x4', type='int'},
+ { name='x1', type='bool'},
+ { name='x2', type='byte'},
+ { name='x3', type='short'},
+ { name='x5', type='long'},
+ { name='x6', type='float'},
+ { name='x7', type='double'},
+ { name='x8_0', type='short'},
+ { name='x8', type='int'},
+ { name='x9', type='long'},
+ { name='x10', type='string'},
+ { name='x12', type='test.DemoType1'},
+ { name='x13', type='test.DemoEnum'},
+ { name='x14', type='test.DemoDynamic'},
+ { name='v2', type='vector2'},
+ { name='v3', type='vector3'},
+ { name='v4', type='vector4'},
+ { name='t1', type='int'},
+ { name='k1', type='int[]'},
+ { name='k2', type='int[]'},
+ { name='k3', type='int[]'},
+ { name='k4', type='int[]'},
+ { name='k5', type='int[]'},
+ { name='k6', type='int[]'},
+ { name='k7', type='int[]'},
+ { name='k8', type='table'},
+ { name='k9', type='test.DemoE2[]'},
+ { name='k15', type='test.DemoDynamic[]'},
+}
+
+---@class test.DateTimeRange
+---@field public start_time int
+---@field public end_time int
+beans['test.DateTimeRange'] =
+{
+ { name='start_time', type='int'},
+ { name='end_time', type='int'},
+}
+
+---@class test.DemoSingletonType
+---@field public id int
+---@field public name string
+---@field public date test.DemoDynamic
+beans['test.DemoSingletonType'] =
+{
+ { name='id', type='int'},
+ { name='name', type='string'},
+ { name='date', type='test.DemoDynamic'},
+}
+
+---@class test.MultiRowType1
+---@field public id int
+---@field public x int
+beans['test.MultiRowType1'] =
+{
+ { name='id', type='int'},
+ { name='x', type='int'},
+}
+
+---@class test.MultiRowType2
+---@field public id int
+---@field public x int
+---@field public y float
+beans['test.MultiRowType2'] =
+{
+ { name='id', type='int'},
+ { name='x', type='int'},
+ { name='y', type='float'},
+}
+
+---@class test.MultiRowRecord
+---@field public id int
+---@field public name string
+---@field public one_rows test.MultiRowType1[]
+---@field public multi_rows1 test.MultiRowType1[]
+---@field public multi_rows2 test.MultiRowType1[]
+---@field public multi_rows3 test.MultiRowType2[]
+---@field public multi_rows4 table
+beans['test.MultiRowRecord'] =
+{
+ { name='id', type='int'},
+ { name='name', type='string'},
+ { name='one_rows', type='test.MultiRowType1[]'},
+ { name='multi_rows1', type='test.MultiRowType1[]'},
+ { name='multi_rows2', type='test.MultiRowType1[]'},
+ { name='multi_rows3', type='test.MultiRowType2[]'},
+ { name='multi_rows4', type='table'},
+}
+
+---@class test.TestUeType
+---@field public x1 bool
+---@field public x2 byte
+---@field public x3 short
+---@field public x4 int
+---@field public x5 long
+---@field public x6 float
+---@field public x10 string
+---@field public x12 test.DemoType1
+---@field public x13 test.ETestUeType
+---@field public v2 vector2
+---@field public v3 vector3
+---@field public v4 vector4
+---@field public t1 int
+---@field public k1 int[]
+---@field public k2 int[]
+---@field public k3 int[]
+---@field public k4 int[]
+---@field public k5 int[]
+---@field public k6 int[]
+---@field public k7 int[]
+---@field public k8 table
+---@field public k9 test.DemoE2[]
+beans['test.TestUeType'] =
+{
+ { name='x1', type='bool'},
+ { name='x2', type='byte'},
+ { name='x3', type='short'},
+ { name='x4', type='int'},
+ { name='x5', type='long'},
+ { name='x6', type='float'},
+ { name='x10', type='string'},
+ { name='x12', type='test.DemoType1'},
+ { name='x13', type='test.ETestUeType'},
+ { name='v2', type='vector2'},
+ { name='v3', type='vector3'},
+ { name='v4', type='vector4'},
+ { name='t1', type='int'},
+ { name='k1', type='int[]'},
+ { name='k2', type='int[]'},
+ { name='k3', type='int[]'},
+ { name='k4', type='int[]'},
+ { name='k5', type='int[]'},
+ { name='k6', type='int[]'},
+ { name='k7', type='int[]'},
+ { name='k8', type='table'},
+ { name='k9', type='test.DemoE2[]'},
+}
+
+---@class test.H1
+---@field public y2 test.H2
+---@field public y3 int
+beans['test.H1'] =
+{
+ { name='y2', type='test.H2'},
+ { name='y3', type='int'},
+}
+
+---@class test.H2
+---@field public z2 int
+---@field public z3 int
+beans['test.H2'] =
+{
+ { name='z2', type='int'},
+ { name='z3', type='int'},
+}
+
+---@class test.MultiRowTitle
+---@field public id int
+---@field public name string
+---@field public x1 test.H1
+---@field public x2 test.H2[]
+---@field public x3 test.H2[]
+beans['test.MultiRowTitle'] =
+{
+ { name='id', type='int'},
+ { name='name', type='string'},
+ { name='x1', type='test.H1'},
+ { name='x2', type='test.H2[]'},
+ { name='x3', type='test.H2[]'},
+}
+
+---@class test.login.RoleInfo
+---@field public role_id long
+beans['test.login.RoleInfo'] =
+{
+ { name='role_id', type='long'},
+}
+
+
+local tables =
+{
+ { name='TbFullTypes', file='test.TbFullTypes.bin', mode='map', index='x3', value_type='test.DemoType2' },
+
+ { name='TbSingleton', file='test.TbSingleton.bin', mode='one', value_type='test.DemoSingletonType'},
+
+ { name='TbDataFromJson', file='test.TbDataFromJson.bin', mode='map', index='x4', value_type='test.DemoType2' },
+
+ { name='TbDataFromXml', file='test.TbDataFromXml.bin', mode='map', index='x4', value_type='test.DemoType2' },
+
+ { name='TbDataFromLua', file='test.TbDataFromLua.bin', mode='map', index='x4', value_type='test.DemoType2' },
+
+ { name='TbTwoKey', file='test.TbTwoKey.bin', mode='bmap', index1='x3', index2='x4', value_type='test.DemoType2' },
+
+ { name='TbMultiRowRecord', file='test.TbMultiRowRecord.bin', mode='map', index='id', value_type='test.MultiRowRecord' },
+
+ { name='TbMultiRowTitle', file='test.TbMultiRowTitle.bin', mode='map', index='id', value_type='test.MultiRowTitle' },
+
+}
+
+return { consts = consts, enums = enums, beans = beans, tables = tables }
+
diff --git a/config/生成code_cs_bin和data_bin.bat b/config/生成code_cs_bin和data_bin.bat
index 3e21584..6e1525c 100644
--- a/config/生成code_cs_bin和data_bin.bat
+++ b/config/生成code_cs_bin和data_bin.bat
@@ -1,5 +1,5 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
- -h 127.0.0.1 ^
+ -h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/root.xml ^
diff --git a/config/生成lua数据.bat b/config/生成lua数据.bat
index 05d2765..3002845 100644
--- a/config/生成lua数据.bat
+++ b/config/生成lua数据.bat
@@ -1,5 +1,5 @@
-..\src\Luban.Client\bin\Debug\netcoreapp3.1\Luban.Client.exe ^
- -h 81.69.4.240 ^
+..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
+ -h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/root.xml ^
diff --git a/docs/images/examples/ex_1.png b/docs/images/examples/ex_1.png
new file mode 100644
index 0000000..b924ba8
Binary files /dev/null and b/docs/images/examples/ex_1.png differ
diff --git a/docs/images/examples/ex_11.png b/docs/images/examples/ex_11.png
new file mode 100644
index 0000000..970323e
Binary files /dev/null and b/docs/images/examples/ex_11.png differ
diff --git a/docs/images/examples/ex_12.png b/docs/images/examples/ex_12.png
new file mode 100644
index 0000000..3fc0698
Binary files /dev/null and b/docs/images/examples/ex_12.png differ
diff --git a/docs/images/examples/ex_2.png b/docs/images/examples/ex_2.png
new file mode 100644
index 0000000..826def4
Binary files /dev/null and b/docs/images/examples/ex_2.png differ
diff --git a/docs/images/examples/ex_21.png b/docs/images/examples/ex_21.png
new file mode 100644
index 0000000..183544d
Binary files /dev/null and b/docs/images/examples/ex_21.png differ
diff --git a/docs/images/examples/ex_22.png b/docs/images/examples/ex_22.png
new file mode 100644
index 0000000..4308431
Binary files /dev/null and b/docs/images/examples/ex_22.png differ
diff --git a/docs/images/examples/ex_31.png b/docs/images/examples/ex_31.png
new file mode 100644
index 0000000..be1dc52
Binary files /dev/null and b/docs/images/examples/ex_31.png differ
diff --git a/docs/images/examples/ex_32.png b/docs/images/examples/ex_32.png
new file mode 100644
index 0000000..8b25d6e
Binary files /dev/null and b/docs/images/examples/ex_32.png differ
diff --git a/docs/images/examples/ex_41.png b/docs/images/examples/ex_41.png
new file mode 100644
index 0000000..374b498
Binary files /dev/null and b/docs/images/examples/ex_41.png differ
diff --git a/docs/images/examples/ex_42.png b/docs/images/examples/ex_42.png
new file mode 100644
index 0000000..776b041
Binary files /dev/null and b/docs/images/examples/ex_42.png differ
diff --git a/docs/images/examples/ex_52.png b/docs/images/examples/ex_52.png
new file mode 100644
index 0000000..dc0646d
Binary files /dev/null and b/docs/images/examples/ex_52.png differ
diff --git a/docs/images/examples/ex_61.png b/docs/images/examples/ex_61.png
new file mode 100644
index 0000000..2237b06
Binary files /dev/null and b/docs/images/examples/ex_61.png differ
diff --git a/docs/images/examples/ex_62.png b/docs/images/examples/ex_62.png
new file mode 100644
index 0000000..da4f1f3
Binary files /dev/null and b/docs/images/examples/ex_62.png differ
diff --git a/docs/images/examples/ex_63.png b/docs/images/examples/ex_63.png
new file mode 100644
index 0000000..e3c6db3
Binary files /dev/null and b/docs/images/examples/ex_63.png differ
diff --git a/docs/images/examples/ex_71.png b/docs/images/examples/ex_71.png
new file mode 100644
index 0000000..4805053
Binary files /dev/null and b/docs/images/examples/ex_71.png differ
diff --git a/docs/images/examples/ex_81.png b/docs/images/examples/ex_81.png
new file mode 100644
index 0000000..4701dcd
Binary files /dev/null and b/docs/images/examples/ex_81.png differ
diff --git a/docs/images/examples/ex_91.png b/docs/images/examples/ex_91.png
new file mode 100644
index 0000000..4e690a2
Binary files /dev/null and b/docs/images/examples/ex_91.png differ
diff --git a/docs/images/examples/ex_a1.png b/docs/images/examples/ex_a1.png
new file mode 100644
index 0000000..57b4865
Binary files /dev/null and b/docs/images/examples/ex_a1.png differ