Compare commits

..

No commits in common. "main" and "v3.1.0" have entirely different histories.
main ... v3.1.0

682 changed files with 14868 additions and 34253 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # [pirunxi]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: walon
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://raw.githubusercontent.com/focus-creative-games/luban/main/docs/sponsor/weixin.JPG','https://raw.githubusercontent.com/focus-creative-games/luban/main/docs/sponsor/zhifubao.JPG']

View File

@ -1,38 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: sync-gitee-mirror
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
sync:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: sync-gitee-mirror
uses: wangchucheng/git-repo-sync@v0.1.0
with:
# Target Repo URL
target-url: https://gitee.com/focus-creative-games/luban.git
# Target Repo Username
target-username: ${{ secrets.GITEE_USERNAME }}
# Target Token
target-token: ${{ secrets.GITEE_PASSWORD }}

1
.gitignore vendored
View File

@ -270,4 +270,3 @@ __pycache__/
/config/output_lua
/config/output_lua_without_test
/src/Excel2TextDiff/Properties/launchSettings.json
/src/packages

View File

@ -2,8 +2,8 @@ language: csharp
solution: src/Luban.sln
mono: none
dotnet: 6.0
dotnet: 5.0
script:
- cd src
- dotnet restore Luban.sln
- dotnet build Luban.sln
- dotnet restore
- dotnet build

File diff suppressed because it is too large Load Diff

1240
README.md

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,31 @@
{
"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},
"s1": {"key":"/asfa", "text":"aabbcc"},
"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}]
}

View File

@ -0,0 +1,31 @@
{
"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},
"s1": {"key":"/asfa32", "text":"aabbcc22"},
"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}]
}

View File

@ -0,0 +1,32 @@
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},
s1 = { key="lua/key1", text="lua text "},
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}},
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
{
"id":2001,
"value": "导出"
}

View File

@ -0,0 +1,5 @@
{
"__tag__":"any",
"id":2004,
"value": "导出"
}

View File

@ -0,0 +1,5 @@
{
"__tag__":"no",
"id":2002,
"value": "忽略"
}

View File

@ -0,0 +1,5 @@
{
"__tag__":"测试",
"id":2003,
"value": "导出"
}

View File

@ -0,0 +1,5 @@
return {
id = 100,
value = "导出",
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
return {
__tag__ = "随便",
id = 104,
value="导出",
}

View File

@ -0,0 +1,5 @@
return {
__tag__ = "no",
id = 101,
value="不导出",
}

View File

@ -0,0 +1,5 @@
return {
__tag__ = "test",
id = 102,
value="测试",
}

View File

@ -0,0 +1,4 @@
<data>
<id>3001</id>
<value>export</value>
</data>

View File

@ -0,0 +1,5 @@
<data>
<__tag__>any</__tag__>
<id>3004</id>
<value>其他</value>
</data>

View File

@ -0,0 +1,5 @@
<data>
<__tag__>no</__tag__>
<id>3002</id>
<value>不导出</value>
</data>

View File

@ -0,0 +1,5 @@
<data>
<__tag__>test</__tag__>
<id>3003</id>
<value>测试</value>
</data>

View File

@ -0,0 +1,9 @@
##,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,
__type__,x1,x2,x3,x4,x5,x6,x7,x8,x8_0,x9,x10,x11,x12,x13,,,k1,k2,k3,k4,k5,k6,k7,k8
,,,,,,,,,,,,,,,,,,,,,,,,
,½ûÖ¹,x2:byte,x3:short,x4:int,x5:long, x6:float,x7:double,,,,,,,,,,array:int,array:int,array:int,array:int,array:int,array:int,array:int,map:int:int
,,,,,,,,,,,,,,,,,,,,,,,,
DemoD2,TRUE,5,5,10000,13234234234,1.28,1.23457891,1234,1234,111111111,huang,,1988,A,,,"1,2,3","1,2,4","1,2,5","1,2,6","1,2,7","1,2,8","1,2,9","1,2,3,4"
,,,,,,,,,,,,,,,,,,,,,,,,
,FALSE,0,6,198704,34523452345,2.5,19870421.2,453234,-345,1.12233E+11,qiang,,1987,B,,,"2,4,6","2,4,7","2,4,8","2,4,9","2,4,10","2,4,11","2,4,12","1,10,2,20"
1 ##
2
3 __type__ x1 x2 x3 x4 x5 x6 x7 x8 x8_0 x9 x10 x11 x12 x13 k1 k2 k3 k4 k5 k6 k7 k8
4
5 ½ûÖ¹ x2:byte x3:short x4:int x5:long x6:float x7:double array:int array:int array:int array:int array:int array:int array:int map:int:int
6
7 DemoD2 TRUE 5 5 10000 13234234234 1.28 1.23457891 1234 1234 111111111 huang 1988 A 1,2,3 1,2,4 1,2,5 1,2,6 1,2,7 1,2,8 1,2,9 1,2,3,4
8
9 FALSE 0 6 198704 34523452345 2.5 19870421.2 453234 -345 1.12233E+11 qiang 1987 B 2,4,6 2,4,7 2,4,8 2,4,9 2,4,10 2,4,11 2,4,12 1,10,2,20

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
{
"x1" : true,
"x2" : 5,
"x3" : 1234,
"x4" : 120000,
"x5" : 12345566778899,
"x6" : 1.28,
"x7" : 123456789.1234567,
"x8" : 1234,
"x8_0" : 1122,
"x9" : 112233445566,
"x10": "huang",
"x11": "hiasf",
"x12" : { "x1":1987 },
"x13" : "B",
"k1" : [1,2,3],
"k2" : [11,22,33],
"k3" : [1,2,3],
"k4": [11,22],
"k5" : [2,3],
"k6" : [4,5],
"k7" : [10,20],
"k8" : { "1":100, "2":200, "3":300}
}

Binary file not shown.

View File

@ -0,0 +1,78 @@
<data>
<x1>true</x1>
<x2>4</x2>
<x3>128</x3>
<x4>1</x4>
<x5>112233445566</x5>
<x6>1.3</x6>
<x7>1112232.43123</x7>
<x8>112233</x8>
<x8_0>123</x8_0>
<x9>112334</x9>
<x10>yf</x10>
<x12>
<x1>1</x1>
</x12>
<x13>C</x13>
<x14 __type__="DemoD2">
<x1>1</x1>
<x2>2</x2>
</x14>
<s1><key>xml_key1</key><text>xml text</text></s1>
<v2>1,2</v2>
<v3>1.2,2.3,3.4</v3>
<v4>1.2,2.2,3.2,4.3</v4>
<t1>1970-01-01 00:00:00</t1>
<k1>
<item>1</item>
<item>2</item>
</k1>
<k2>
<item>1</item>
<item>2</item>
</k2>
<k3>
<item>1</item>
<item>2</item>
</k3>
<k4>
<item>1</item>
<item>2</item>
</k4>
<k5>
<item>1</item>
<item>2</item>
</k5>
<k6>
<item>1</item>
<item>2</item>
</k6>
<k7>
<item>1</item>
<item>3</item>
</k7>
<k8>
<item> <key>2</key><value>10</value></item>
<item> <key>3</key><value>30</value></item>
</k8>
<k9>
<item>
<y1>1</y1>
<y2>true</y2>
</item>
<item>
<y1>2</y1>
<y2>false</y2>
</item>
</k9>
<k15>
<item __type__="DemoD2">
<x1>1</x1>
<x2>2</x2>
</item>
</k15>
</data>

View File

@ -0,0 +1,78 @@
<data>
<x1>true</x1>
<x2>4</x2>
<x3>128</x3>
<x4>2</x4>
<x5>112233445566</x5>
<x6>1.3</x6>
<x7>1112232.43123</x7>
<x8>112233</x8>
<x8_0>123</x8_0>
<x9>112334</x9>
<x10>yf</x10>
<x12>
<x1>1</x1>
</x12>
<x13>C</x13>
<x14 __type__="DemoD2">
<x1>1</x1>
<x2>2</x2>
</x14>
<s1><key>xml_key2</key><text>xml text222</text></s1>
<v2>1,2</v2>
<v3>1.2,2.3,3.4</v3>
<v4>1.2,2.2,3.2,4.3</v4>
<t1>1970-01-01 00:00:00</t1>
<k1>
<item>1</item>
<item>2</item>
</k1>
<k2>
<item>1</item>
<item>2</item>
</k2>
<k3>
<item>1</item>
<item>2</item>
</k3>
<k4>
<item>1</item>
<item>2</item>
</k4>
<k5>
<item>1</item>
<item>2</item>
</k5>
<k6>
<item>1</item>
<item>2</item>
</k6>
<k7>
<item>1</item>
<item>3</item>
</k7>
<k8>
<item> <key>2</key><value>10</value></item>
<item> <key>3</key><value>30</value></item>
</k8>
<k9>
<item>
<y1>1</y1>
<y2>true</y2>
</item>
<item>
<y1>2</y1>
<y2>false</y2>
</item>
</k9>
<k15>
<item __type__="DemoD2">
<x1>1</x1>
<x2>2</x2>
</item>
</k15>
</data>

View File

@ -0,0 +1,17 @@
<root>
<topmodule name="cfg"/>
<group name="c" default="1"/> client 分组
<group name="s" default="1"/> server 分组
<group name="e" default="1"/> editor分组
<import name="."/>
<branch name="en"/>
<branch name="jp"/>
<branch name="cn"/>
<service name="server" manager="Tables" group="s"/>
<service name="client" manager="Tables" group="c"/>
<service name="all" manager="Tables" group="c,s,e"/>
</root>

View File

@ -0,0 +1,213 @@
<module name="test">
<const name="DemoConst">
<var name="x1" type="int" value="0"/>
<var name="x2" type="long" value="3242"/>
<var name="x3" type="float" value="444.3"/>
<var name="x4" type="double" value="55.3"/>
<!--var name="x5" type="string" value="abcdefg"/-->
</const>
<enum name="DemoEnum">
<var name="A" value="1"/>
<var name="B"/>
<var name="C" value="4"/>
<var name="D"/>
</enum>
<bean name="DemoType1">
<var name="x1" type="int"/>
</bean>
<bean name="DemoDynamic"> 多态数据结构
<var name="x1" type="int"/>
<bean name="DemoD2" alias="测试别名">
<var name="x2" type="int"/>
</bean>
<bean name="DemoD3">
<var name="x3" type="int"/>
<bean name="DemoE1">
<var name="x4" type="int"/>
</bean>
</bean>
<bean name="DemoD5">
<var name="time" type="DateTimeRange"/>
</bean>
</bean>
<bean name="DemoE2">
<var name="y1" type="int?"/>
<var name="y2" type="bool"/>
</bean>
<bean name="DemoType2" >
<var name="x4" type="int" convert="DemoEnum"/>
<var name="x1" type="bool"/>
<var name="x2" type="byte"/>
<var name="x3" type="short" ref="test.TbFullTypes"/>
<var name="x5" type="long" convert="DemoEnum"/>
<var name="x6" type="float"/>
<var name="x7" type="double"/>
<var name="x8_0" type="fshort"/>
<var name="x8" type="fint"/>
<var name="x9" type="flong"/>
<var name="x10" type="string" path="normal;*.txt"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="DemoEnum"/>
<var name="x14" type="DemoDynamic" sep=","/>多态数据结构
<var name="s1" type="text"/>
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/> 使用;来分隔
<var name="k2" type="list,int"/>
<var name="k3" type="linkedlist,int"/>
<var name="k4" type="arraylist,int"/>
<var name="k5" type="set,int"/>
<var name="k6" type="treeset,int"/>
<var name="k7" type="hashset,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2" sep="," index="y1"/>
<var name="k15" type="array,DemoDynamic" sep=","/>
</bean>
<table name="TbFullTypes" index="x3" value="DemoType2" input="test/full_type.xlsx" branch_input="cn:test/full_type_cn1.xlsx,test/full_type_cn2.xlsx|en:texx/full_type_en.xlsx"/> 最常见的普通 key-value表
<bean name="DateTimeRange" sep=";">
<var name="start_time" type="datetime"/>
<var name="end_time" type="datetime"/>
</bean>
<bean name="DemoSingletonType">
<var name="id" type="int"/>
<var name="name" type="text"/>
<var name="date" type="DemoDynamic"/>
</bean>
<table name="TbSingleton" mode="one" value="DemoSingletonType" input="test/table_one.xlsx"/> 单例表,只有一个记录
<table name="TbDataFromJson" value="DemoType2" input="test/json_datas"/> 普通表不过数据从tbrole_datas目录递归读入每个文件是一个记录
<table name="TbDataFromXml" value="DemoType2" input="test/xml_datas"/> 普通表不过数据从tbrole_datas目录递归读入每个文件是一个记录
<table name="TbDataFromLua" value="DemoType2" input="test/lua_datas"/> 普通表不过数据从tbrole_datas目录递归读入每个文件是一个记录
<bean name="MultiRowType1">
<var name="id" type="int"/>
<var name="x" type="int"/>
</bean>
<bean name="MultiRowType2">
<var name="id" type="int"/>
<var name="x" type="int"/>
<var name="y" type="float"/>
</bean>
<bean name="MultiRowRecord">
<var name="id" type="int"/>
<var name="name" type="string"/>
<var name="one_rows" type="list,MultiRowType1"/>
<var name="multi_rows1" type="list,MultiRowType1" multi_rows="1"/>
<var name="multi_rows2" type="array,MultiRowType1" multi_rows="1"/>
<var name="multi_rows3" type="set,MultiRowType2" multi_rows="1"/>
<var name="multi_rows4" type="map,int,MultiRowType2" multi_rows="1"/>
</bean>
<table name="TbMultiRowRecord" value="MultiRowRecord" input="test/multi_rows_record.xlsx"/>
<enum name="ETestUeType">
<var name="WHITE" alias="白"/>
<var name="BLACK"/>
</enum>
<enum name="ETestEmptyEnum">
</enum>
<enum name="ETestEmptyEnum2">
<var name="SMALL_THAN_256" value="255"/>
<var name="X_256" value="256"/>
<var name="X_257" value="257"/>
</enum>
<bean name="TestUeType">
<var name="x1" type="bool"/>
<var name="x2" type="byte"/>
<var name="x3" type="short"/>
<var name="x4" type="int"/>
<var name="x5" type="long"/>
<var name="x6" type="float"/>
<var name="x10" type="string"/>
<var name="x12" type="DemoType1"/>
<var name="x13" type="ETestUeType"/>
<var name="v2" type="vector2"/>
<var name="v3" type="vector3"/>
<var name="v4" type="vector4"/>
<var name="t1" type="datetime"/>
<var name="k1" type="array,int"/>
<var name="k2" type="list,int"/>
<var name="k3" type="linkedlist,int"/>
<var name="k4" type="arraylist,int"/>
<var name="k5" type="set,int"/>
<var name="k6" type="treeset,int"/>
<var name="k7" type="hashset,int"/>
<var name="k8" type="map,int,int"/>
<var name="k9" type="list,DemoE2"/>
</bean>
<bean name="H1">
<var name="y2" type="H2"/>
<var name="y3" type="int"/>
</bean>
<bean name="H2">
<var name="z2" type="int"/>
<var name="z3" type="int"/>
</bean>
<bean name="MultiRowTitle">
<var name="id" type="int"/>
<var name="name" type="string"/>
<var name="x1" type="H1"/>
<var name="x2" type="list,H2" multi_rows="1"/>
<var name="x3" type="array,H2" multi_rows="1"/>
</bean>
<table name="TbMultiRowTitle" value="MultiRowTitle" input="test/multi_level_title.xlsx"/>
<bean name="TestNull">
<var name="id" type="int"/>
<var name="x1" type="int?"/>
<var name="x2" type="DemoEnum?"/>
<var name="x3" type="DemoType1?"/>
<var name="x4" type="DemoDynamic?"/>
</bean>
<table name="TbTestNull" value="TestNull" input="test/test_null.xlsx"/>
<!--table name="TbDynamic" value="DemoDynamic" input="多态数据源"/-->
<module name="login">
支持在一个定义文件中 定义多个模块。 一般来说一个定义文件中一个模块比较好,但有些情况下为了方便可以定义多个。
<bean name="RoleInfo">
<var name="role_id" type="long"/>
</bean>
</module>
<bean name="TestTag">
<var name="id" type="int"/>
<var name="value" type="string"/>
</bean>
<table name="TbTestTag" value="TestTag" input="test/tag_datas"/>
</module>

View File

@ -0,0 +1,14 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/__root__.xml ^
--input_data_dir Datas ^
--output_data_dir output_lua ^
-s client ^
--gen_types data_lua ^
--export_test_data ^
--input_l10n_text_files l10n/cn/TextTable_CN.xlsx ^
--output_l10n_not_converted_text_file NotLocalized_CN.txt
pause

View File

@ -0,0 +1,15 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/__root__.xml ^
--input_data_dir Datas ^
--output_data_dir output_lua ^
-s client ^
--gen_types data_lua ^
--export_test_data ^
--input_l10n_text_files l10n/cn/TextTable_CN.xlsx ^
--l10n_text_field_name text_tw ^
--output_l10n_not_converted_text_file NotLocalized_TW.txt
pause

View File

@ -0,0 +1,9 @@
/asfa|aabbcc
/asfa32|aabbcc22
key_name|aabbcc
key1|asdfa4
key2|asdfa7
key3|asdfa8
lua/key1|lua text
xml_key1|xml text
xml_key2|xml text222

View File

@ -0,0 +1,9 @@
/asfa|aabbcc
/asfa32|aabbcc22
key_name|aabbcc
key1|asdfa4
key2|asdfa7
key3|asdfa8
lua/key1|lua text
xml_key1|xml text
xml_key2|xml text222

View File

@ -0,0 +1,14 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/__root__.xml ^
--input_data_dir Datas ^
--output_data_dir output_lua ^
-s client ^
--gen_types data_lua ^
--export_test_data ^
--branch cn ^
--branch_input_data_dir Datas/l10n/cn
pause

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,13 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/root.xml ^
--input_data_dir Datas ^
--output_code_dir output_code ^
--output_data_dir output_data ^
-s server ^
--gen_types code_cs_bin,data_bin ^
--export_test_data
pause

View File

@ -0,0 +1,11 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/__root__.xml ^
--input_data_dir Datas ^
--output_data_dir output_lua_without_test ^
-s client ^
--gen_types data_lua
pause

View File

@ -0,0 +1,12 @@
..\src\Luban.Client\bin\Debug\net5.0\Luban.Client.exe ^
-h %LUBAN_SERVER_IP% ^
-j cfg ^
-- ^
-d Defines/__root__.xml ^
--input_data_dir Datas ^
--output_data_dir output_lua ^
-s client ^
--gen_types data_lua ^
--export_test_data
pause

View File

@ -1 +1 @@
theme: jekyll-theme-slate
theme: jekyll-theme-cayman

126
docs/catalog.md 100644
View File

@ -0,0 +1,126 @@
* start up
- [下载 dotnet 5](https://dotnet.microsoft.com/download/dotnet/5.0)
- [下载 luban.client&luban.server](https://github.com/focus-creative-games/luban_examples/tree/main/Tools)
- 启动 luban.server
- 创建游戏配置
- root.xml
- 新增一个表定义
- 新增一个excel文件
- 生成
- c# dotnet core
- gen.client 命令行
- c# unity
- c# unity + ILRuntime
- lua unity xlua
- lua unity tolua
- 其他lua
- java
- go
- cpp
- typescript
- python 2.7及3.0
* 进阶
- 游戏配置
- excel 篇
- 标题头定义
- 定义和配置更多基础类型
- 定义枚举
- 定义bean
- 数据格式
- 指定某个或者多个sheet或者文件
- list 或者其他类型
- group 分组导出
- tag
- sep
- multi_rows
- 多级标题头
- 单例表
- 行表与列表
- 可空变量
- datetime
- convert
- 多态bean
- json 篇
- lua
- xml
- 一个同时包含 excel 、 json 配置的项目
- 数据校验
- ref
- path
- 导出格式
- bin 格式
- lua 格式
- 本地化
* gen.client & gen.server 工作模型
![](docs/images/Client_Server.png)
* 定义 + 数据的 抽象模型
* 定义
* 根定义文件
* group
* service
* topmodule
* import
* 子模块定义
* 类型系统
- 基础类型
- 可空类型
- 枚举
- const
- bean
- field
- convert 常量替换
- 多态
* table
* module
* 源数据格式
- excel
- json
- lua
- xml
* 导出数据格式
- bin
- json
- lua
- emmylua anntations
* input 多种数据文件来源
* group 数据分组
* tag
* 资源列表导出
* validator 数据检验
* 本地化
* editor 相关。导出符合luban数据约束的文件。
* ide支持
- emmylua anntations
- luban.client 命令行介绍
- luban.client 命令行参数
- job cfg 命令行参数
* 各个语言和引擎及平台下的项目搭建
- c# + dotnet core
- c# + unity
- c# + unity + ILRuntime
- 其他 c# 平台
- lua + unity + tolua
- lua + unity + xlua
- lua + unity + slua
- lua + unreal + unlua
- lua + cocos2dx
- 其他使用 lua 的 平台
- c++ + unreal
- c++ + 其他平台
- go
- java
- python 2.7
- python 3.0
- typescript + 微信小游戏
- typescript + 其他平台
* luban 开发
- git clone 项目
- luban 构建与发布
- 普通构建
- docker
- 代码结构介绍
- 自定义 job

428
docs/data_excel.md 100644
View File

@ -0,0 +1,428 @@
[//]: # "Author: bug"
[//]: # "Date: 2020-11-01 15:40:11"
## bool 类型
- 新增 一个字段 batch_useable表示能否批量使用
- 用 true 或 false 表示 bool 值,只需要小写后是这两个值即可,比如 true,True,True 都是合法的值。excel 会自动将输入的值大写化。
- [定义](images/adv/def_02.png):
```xml
<module name = "item">
<bean name = "Item">
<var name = "batch_usable" type = "bool" />
</bean>
</module>
```
- 配置:
![如图](images/adv/def_01.png)
## float 类型
- 新增一个 float 类型字段,掉落概率 drop_prob.
- [定义](images/adv/def_04.png):
```xml
<module name = "item">
<bean name = "Item">
<var name = "drop_prob" type = "float" />
</bean>
</module>
```
- 配置:
![如图](images/adv/def_03.png)
## byte,short,int,long,string
与 float 相似,不再赘述
## string 类型
填法与 float相似但又特殊性。当string类型数据出现在**连续单元格**比如多列bean占了多个单元格或者用**sep分割**的数据中时,由于工具无法区别空白到底算空白字符串还是应该跳过,所以在连续多字段模式下,强制用""来表示空白字符串。
下面示例中s1是string单独占一个列可以用空白单元格表示空白字符串。 cs1和cs2要么是连续单元格模式要么是sep分割产生的连续数据模式表达空白字符串必须用""。
可能会有疑问,如何恰好想表达 ""是怎么办呢? 如果真遇到这种需求,再寻找解决方案吧。
定义:
```xml
<bean name="CompactString">
<var name="id" type="int"/>
<var name="s2" type="string"/>
<var name="s3" type="string"/>
</bean>
<bean name="TestString">
<var name="id" type="int"/>
<var name="s1" type="string"/>
<var name="cs1" type="CompactString"/>
<var name="cs2" type="CompactString" sep=","/>
</bean>
<table name="TbTestString" value="TestString" input="test/test_string.xlsx"/>
```
配置数据:
![配置](images/examples/ex_string_01.png)
## text 类型
该类型数据包含两个字段, key和text 其中 key 可以重复出现但要求text完全相同否则报错。这么设计是为了防止意外写重了key。**注意不允许key为空而text不为空**
如果想填空的本地化字符串, key和text完全留空即可工具会特殊对待不会加入 key集合。
text的key和text字段都是string类型因此在连续单元格或者sep产生的连续数据流模式中同样要遵循用""来表达空白字符串的规则。
定义:
```xml
<bean name="L10NDemo">
<var name="id" type="int"/>
<var name="text" type="text"/>
</bean>
<table name="TbL10NDemo" value="L10NDemo" input="l10n/Demo.xlsx"/>
```
配置数据:
![数据](images/examples/ex_i10n_2.png)
## 列表类型 list,int
- 我们新增一个字段, 宝箱的随机抽取道具列表 random_item_ids。
- [定义](images/adv/def_06.png)
```xml
<module name = "item">
<bean name = "Item">
<var name = "random_item_ids" type = "list, int" />
</bean>
</module>
```
- 配置:
![如图](images/adv/def_05.png)
## 向量类型 vector3
- vector3 有三个字段 float x, float y, float z, 适合用于表示坐标之类的数据。
- 我们新增一个 spawn_location 字段,表示物品产生的场景位置。
- [定义](images/adv/def_08.png):
```xml
<module name = "item">
<bean name = "Item">
<var name = "spawn_location" type = "vector3" />
</bean>
</module>
```
- 配置:
![如图](images/adv/def_07.png)
## 枚举类型
- 道具有品质,白绿蓝紫橙。 虽然可以直接填 1-5 这几个数据,但不直观,而且对程序非常不友好。
- 有一种更优雅的方式是定义枚举。
- [枚举定义](images/adv/def_09.png)
``` xml
<enum name = "EQuality">
<var name = "WHITE" alias = "白" value = "1">
<var name = "GREEN" alias = "绿" value = "2">
<var name = "BLUE" alias = "蓝" value = "3">
<var name = "PURPLE" alias = "紫" value = "4">
<var name = "ORANGE" alias = "橙" value = "5">
</enum>
```
- 之前用 bean 来定义结构,我们引入的新的 tag “enum” 来定义 枚举。
- enum 的 name 属性表示 枚举名。
- 如果生成 c#代码的话,会生成 cfg.item.Equality 类。
- `<var name=”xxx” alias=”xx” value=”xx”/>` 为检举项。
- 其中 name 为必填项,不可为空,也不能重复。
- alias 是可选项,枚举项别名。
- value 是枚举值,主要给程序使用。
- [完整用法](images/adv/def_10.png)
``` xml
<module name = "item">
<enum name = "EQuality">
<var name = "WHITE" alias = "白" value = "1">
<var name = "GREEN" alias = "绿" value = "2">
<var name = "BLUE" alias = "蓝" value = "3">
<var name = "PURPLE" alias = "紫" value = "4">
<var name = "ORANGE" alias = "橙" value = "5">
</enum>
<bean name = "Item">
<var name = "quality" type = "EQuality">
</bean>
</module>
```
- excel 表中,想表达一个枚举值,既可以用检举项 name,也可以用枚举项的 alias但不能是相应的整数值。
- 注意!如果想引用其他模块定义的 enum 或者 bean, type 里必须指定全名。
比如 type=”mall.TradeInfo” 。
- ![如图](images/adv/def_11.png)
## bean 类型
- 有时候希望一个字段是复合类型。
- 比如,我们想用一个字段 level_range 来表示道具可以使用的等级范围,它包含两个字段,最小等级和最大等级。
- 此时,可以通过定义 bean 来解决。
[定义](images/adv/def_12.png)
``` xml
<bean name="IntRange">
<var name="min" type="int">
<var name="max" type="int">
</bean>
<bean name="Item">
<var name="level_range" type="IntRange">
</bean>
```
- 之前的字段都在一个单元格内填写,现在这个字段是 bean 类型,有两个值,该怎么填写呢?
如果也像 list,int 那样把两个数写在一个单元格里(如下图),会发现工具报错了: “10,20” 不是合法的整数值。
![如图](images/adv/def_13.png)
- 填写这些占据多个单元格的数据有两种办法:
1. 合并标题头
让 level_range 标题头占据两列,这样就能在两个单元格里分别填写最小最大等级了。
![如图](images/adv/def_14.png)
2. 使用 sep 分割单元格
字段定义中指定 sep 属性,用某些字符分割单元格,这样就能识别为两个整数了。
[定义](images/adv/def_15.png)
``` xml
<bean name="IntRange">
<var name="min" type="int">
<var name="max" type="int">
</bean>
<bean name="Item">
<var name="level_range" type="IntRange" sep="|">
</bean>
```
如果想用 分号; 或者 竖号 | 分割,只要 sep=”;” 或者 sep=”|“ 即可。
![如图](images/adv/def_16.png)
## list,bean 类型
- 有些时候,我们需要一个 结构列表字段。
比如说 道具不同等级会增加不同的血量。我们定义一个 ItemLevelAttr 结构。
[定义](images/adv/def_17.png)
``` xml
<module name="item">
<bean name="ItemLevelAttr">
<var name="level", type="int">
<var name="desc", type="string">
<var name="attr", type="float">
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" />
</bean>
</module>
```
配置:
![如图](images/adv/def_18.png)
- 对于多个值构成的字段,填写方式为 在标题头(level_attrs)对应的列范围内,按顺序填值。不需要跟策划的标题头名有对应关系。空白单元格会被忽略。也就是如下填法也是可以的:
![如图](images/adv/def_19.png)
- 这种填法的缺点是占据在太多的列。如果想如下填,该怎么办呢?
![如图](images/adv/def_20.png)
- 有两种办法。
1. bean ItemLevelAttr 增加属性 sep=”,”
[定义](images/adv/def_21.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
```
如果不想用逗号”,” ,想用;来分割单元格内的数据,只要将 sep=”;” 即可。
2. 字段 level_attrs 增加属性 sep=”,”,即
[定义](images/adv/def_22.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" sep=",">
</bean>
```
如果想所有数据都在一个单元格内填写,又该怎么办呢?
![如图](images/adv/def_23.png)
想用 | 来分割不同 ItemLevelAttr ,用 , 来分割每个记录的数据。只需要 字段 level_attrs 的 sep=”,|” 即可。
[定义](images/adv/def_24.png)
``` xml
<bean name="ItemLevelAttr" sep=",">
<var name="level" type="int"/>
<var name="desc" type="string"/>
<var name="attr" type="float"/>
</bean>
<bean name="Item">
<var name="level_attrs" type="list,ItemLevelAttr" sep=",|">
</bean>
```
## 多态 bean
- 多态 bean 的 Luban 类型系统的核心,没有它就不可能比较方便简洁地表达游戏内的复杂数据。
- 常见的结构都是固定,但有时候会有需求,某个字段有多种类型,每种类型之间可能有一些公共字段,但它们也有一部分不一样的字段。简单的做法是强行用一个结构包含所有字段,这在类型种类较少时还勉强能工作,但类型很多,字段个数变化极大时,最终的复合结构体过于庞大笨拙,故而难以在实际采用。
- Luban 引入了 OOP 中类型继承的概念,即多态 bean。方便表达那些复杂配置需求。
- 假设 item 有一个形状 Shape 类型的字段。Shape 有两种 Circle 和 Rectangle.
Cicle 有 2 个字段 int id; float radius;
Rectangle 有 3 个字段 int id; float width; float height;
[定义](images/adv/def_25.png)
``` xml
<bean name="Shape">
<var name="id" type="int">
<bean name="Circle">
<var name="radius" type="float">
</bean>
<bean name="Rectangle">
<var name="width" type="float"/>
<var name="height" type="float"/>
</bean>
</bean>
<bean name="Item">
<var name="shape" type="Shape"/>
</bean>
```
配置:
![如图](images/adv/def_26.png)
- 注意到,多态 bean 与普通 bean 填写区别在于,多态 bean 需要一个类型名。这也好理解,如果没有类型名,如何知道使用哪个 bean 呢。
- 有时间策划不太习惯填写英文,或者说类型名有时候会调整,不希望调整类型名后配置也跟着改变,因为,多态 bean 支持别名的概念。
[定义](images/adv/def_27.png)
``` xml
<bean name="Shape">
<var name="id" type="int"/>
<bean name="Circle" alias="圆">
<var name="radius" type="float"/>
</bean>
<bean name="Rectangle" alias="长方形">
<var name="width" type="float"/>
<var name="height" type="float"/>
</bean>
</bean>
```
- 配置
![如图](images/adv/def_28.png)
- 使用类型名和别名来标识多态都是支持的,可以混合使用。
## multi_rows 多行 记录
- 使用数据表经常会遇到某个字段是列表类型的情形。有时候列表的 bean 的字段特别多,比如多达 10 个字段,列表包含了好几个 bean。如果此时配置成一行会导致 excel 列过多,策划编辑维护不方便直观。 Luban 支持这个列表 多行配置。
- [定义](images/adv/def_29.png)
``` xml
<bean name="MultiLineType">
<var name="x1" type="int"/>
<var name="x2" type="int"/>
<var name="x3" type="int"/>
<var name="x4" type="int"/>
<var name="x5" type="int"/>
<var name="x6" type="int"/>
<var name="x7" type="int"/>
</bean>
<bean name="Item">
...
<var name="lines" type="list,MultiLineType" multi_rows="1"/>
</bean>
```
- 和 普通 非多行记录的区别在于 lines 字段多了一个 multi_rows=”1” 字段,表示这个字段要多行配置。
- ![如图](images/adv/def_30.png)
## 多级标题头
- 经常会有字段占了多列,比如 Shape, 如果按顺序填写,有个问题在于,字段很多时,容易对应错误,不方便定位。
- 假设 有个 show_info 字段,包含 如下字段 string name; string desc; string tip;
- [定义](images/adv/def_31.png)
``` xml
<bean name="ShowInfo">
<var name="name" type="string" />
<var name="desc" type="string" />
<var name="tip" type="string" />
</bean>
<bean name="Item">
...
<var name="show_info" type="ShowInfo"/>
</bean>
```
- 配置
![如图](images/adv/def_32.png)
- 有几处改动
1. 我们新插入了一行标题头,第 2 行变成了两行。同时 A2,A3 单元格合并,表示标题头占了 2 行。
2. show_info 下一行,填上 子字段名 (顺序不重要)
- 我们称之为多级标题头,通过多级标题头的方式,可以精确定位深层次字段的列。方便策划填。
## 单例表
- 不是所有数据都是 类似 map 这样的多记录结构。有些配置只有一份,比如 开启装备系统的最小角色等级。 这些数据 所在的表,也只有一个记录。称之为 单例表。
- 我们创建一个单例表,来存放这些数据。
- [定义](images/adv/def_33.png)
``` xml
<bean name="GlobalConfig">
<var name="unlock_equip_sys_level" type="int"/>
<var name="unlock_mall_sys_level" type="int"/>
</bean>
<table name="TbGlobalConfig" value="GlobalConfig" mode="one" input="item/全局参数表.xlsx"/>
```
- 配置
![如图](images/adv/def_34.png)
## 横表与纵表
- 之前介绍的表都是 面向行,沿着行方向填写数据。有时候我们希望 以列为方向填写。
- 比如 上面的单例表。 如果改成一行一个字段,看起来会更清楚。 我们引入纵表支持。
- 定义不变,但 excel 的填法有区别,数据如下:
- ![如图](images/adv/def_35.png)
## 可空变量
- 有时候会有一种变量,我们希望它 功能生效时填一个有效值,功能不生效里,用一个值来表示。 例如 int 类型,常常拿 0 或者-1 作无效值常量。 但有时候0 或-1 也是有效值时,这种做法就不生效了。或者说 项目组内 有时候拿 0有时候拿-1 作无效值标记,很不统一。我们借鉴 sql 及 c#,引入 可空值概念,用 null 表达空值。
- 我们为 Item 添加 min_use_level 字段,类型为 int? 当填有效值时,使用时要检查等级,否则不检查。
- [定义](images/adv/def_36.png)
``` xml
<bean name="Item">
...
<var name="min_use_level" type="int?"/>
</bean>
```
- 配置
![如图](images/adv/def_37.png)
## datetime 类型
- 时间是常用的数据类型。Luban 特地提供了支持。
填写格式为 以下 4 种。
- yyyy-mm-dd hh:mm:ss 如 1999-08-08 01:30:29
- yyyy-mm-dd hh:mm 如 2000-08-07 07:40
- yyyy-mm-dd hh 如 2001-09-05 07
- yyyy-mm-dd 如 2003-04-05
- 为 Item 新增一个 失效时间字段 expire_time 。
- [定义](images/adv/def_38.png)
``` xml
<bean name="Item">
...
<var name="expire_time" type="datetime"/>
</bean>
```
- 配置
![如图](images/adv/def_39.png)
## convert 常量替换
游戏里经常会出现一些常用的类似枚举的值,比如说 升级丹的 id,在很多地方都要填,如果直接它的道具 id,既不直观,也容易出错。 Luban 支持常量替换。对于需要常量替换的字段,添加 convert=”枚举类”。 如果填写的值是 枚举名或者别名,则替换为 相应的整数。否则 按照整数解析。
定义
``` xml
<enum name="EFunctionItemId">
<var name="SHENG_JI_DAN" alias="升级丹" value="11220304"/>
<var name="JIN_JIE_DAN" alias="进阶丹" value="11220506"/>
</enum>
<bean name="Item">
<var name="cost_item_on_use" type="int" convert="EFunctionItemId"/>
</bean>
```
配置:
![如图](images/adv/def_41.png)

19
docs/data_json.md 100644
View File

@ -0,0 +1,19 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
# Json 数据
##
* Luban 支持 json 数据为数据源。 一般来说json数据是由编辑器制作导出的而不像excel那样由 人工直接编辑。
* 我们新增一个定义表,覆盖了常见数据类型。
![如图](images/adv/def_42.png)
* 我们在 item目录下 新增一个目录,叫 DemoJsonDatas, 里面放两个数据:
![如图](images/adv/def_43.png)
* json 的内容如下:
![如图](images/adv/def_44.png)
* 自行参数每种数据类型 在 json格式的填法大多数都是合乎常理的。唯一特殊的是map类型。
* 由于json 的 key 类型必须为 string, 所以对于 map类型。数据格式为
```
[ [key1,value1], [key2, value2], ,,,]
```

11
docs/data_lua.md 100644
View File

@ -0,0 +1,11 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-01 16:26:41)
# Lua 数据
##
* 与 json 相似定义。
* 唯一区别在于, lua 的table的key支持任意格式所以 lua 的map 可以直接 {[key1] = value1, [key2] = value2, ,,,}
* ![如图](images/adv/def_42.png)
* 注意 数据前有一个 return 语句。因为 lua 数据是当作 lua 文件加载的,每个加载后的结果当作一个记录读入。

20
docs/deploy.md 100644
View File

@ -0,0 +1,20 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-11-23 00:21:21)
# 服务端布署
## Docker 镜像布署
- 镜像会自动更新至最新版
- 在有 docker 的环境下,执行下面的指令
``` bash
docker pull hugebug4ever/luban:latest
docker run --name luban-server -d -p 8899:8899 hugebug4ever/luban:latest
```
## Windows 下命令行布署
- 下载 [release](https://github.com/focus-creative-games/luban/releases) 版本
- 解压 Luban.Server.zip
- 执行下面的命令即可
```
Luban.Server.exe
```

26
docs/faq.md 100644
View File

@ -0,0 +1,26 @@
[//]: # "Author: bug"
[//]: # "Date: 2020-11-15 23:59:21"
===============================================================================
## 为什么要使用"客户端/服务器"模式
- 最初的想法是服务端闭源,因为代码生成部分花了很多心思,也方便加密之类的操作
- 为了方便与社区开发者交流开源后,还保留了这一模式,因为觉得
- 这一模式,也能作为 ddc 的基础 (distributed data cache)
- 配置文件需要反复生成与测试
- 文件数量上升后,配置生成不可避免地变慢
- 再快的技术,也挡不住大量数据的处理
## 如果用客户端生成,再通过服务器端分享缓存,不是更快么
- 是的。
- 但服务器模式还有方便更新的优势,就像网页访问,不需要每个客户端升级浏览器。
- 通知每个使用者要更新本地目录这件事,在实践中也产生过很多麻烦。
- 如果有效率提升,更佳的 feature (比如统计?), 在服务端实施更方便。
- c-s 本身是个流行的设计,虽然万物皆可客户端 ^_^。
- 考虑至此,就没有继续深究这个问题。
## 为什么 excel 的配置不像别的工具,用文件头描述数据?
- 数据描述除了 excel 还可以为 json 等其它数据源。用 xml 可以更统一。
- 数据类型可以描述地更详细,毕竟 excel 的表达只是强在数据。
- 数据关系可以更好地表达,比在 excel 中用一些技巧实现更舒服。

148
docs/feature.md 100644
View File

@ -0,0 +1,148 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-10-18 15:35:26)
## 特性说明
--------------------
### 支持的数据类型
* 基础内置类型
- bool,byte,short,fshort,int,fint,long,flong,float,double,string,text,bytes
- vector2, vector3,vector4
- datetime
* 可空类型
- bool?,byte?,short?,fshort?,int?,fint?,long?,flong?,float?,double?
- vector2?,vector3?,vector4?
- datetime?
* 自定义枚举 enum
* 自定义常量 const
* 自定义结构 bean
- 可以定义所有类型的字段
- 支持无限制的结构继承,对于表达中大型项目的复杂数据(技能,buff,ai 等等) 极其有用。 (比如基类Shape, 子类 Circle,Rectangle
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
B-->E;
```
* 支持容器类型 array。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 list。 value 可以为内置类型,也可以为自定义类型
* 支持容器类型 set。 value 只能为内置类型或者enum类型不支持 bean 类型
* 支持容器类型 map。 key 只能为内置类型或者enum类型不支持 bean 类型。 value 可以为内置类型,也可以为自定义类型
### 多数据源支持
* 支持excel族。 csv 及 xls,xlsx等格式
* 支持从指定excel里的某个单元薄读入。
* 支持json。 每个json文件当作一个记录读入
* 支持lua。 每个lua文件当作一个记录读入
* 支持xml。 每个xml文件当作一个记录读入
* 支持目录。 递归目录下的所有文件每个文件当作一个记录读入。允许不同类型的文件混合比如目录下可以同时有json,lua,xml,excel之类的格式。
* 允许指定多个数据源,可以使用以上所有的组合。
* 扩展新的数据源也非常容易 (像支持lua,json,xml数据源只用了200行左右代码)
### 多种数据表模式
* one 格式,即单例表模式
* map 格式即普通key-value表模式。 任何符合set 的value要求的类型都可以做key
* bmap 格式,即双主键模式。 任何符合 set 的value要求的类型都可以作 key1和key
### 如何自定义导出分组
* 可以按照自定义需求选择性导出表及字段
### 生成极快
* 大项目几十M配置数据也能1秒导出
* 生成工具使用客户端/服务器架构
* 服务器使用多线程加速生成,数十倍提高生成速度
* 服务器使用缓存直接返回未改动的代码或者数据的生成结果
* 支持增量生成
### 增强的 excel 格式
* 支持填写任意复杂的数据(比如 常见的 list,bean 这种类型)
* 支持 sep 在单个单元格内填写多个数据
* 支持 多行数据。即 对于 list,bean 类型的字段,可以多行填写
* 支持多级标题头,对填写 层次很深的数据时非常有用
* 支持导出标记。比如 是、否、test 等等,用于标记某行数据是否导出
* 支持用 true,false表示 bool 值,语义更清晰。
* 支持枚举 alias 别名,填写枚举类型不再需要写数字了
* 支持可空变量。可以用null表达空。 某些场合下语义更清晰。
* 支持 datetime 数据类型. 时间格式标准为以下几种最终被转化为utc时间方便程序处理
- yyyy-MM-dd HH:mm:ss
- yyyy-MM-dd HH:mm
- yyyy-MM-dd HH
- yyyy-MM-dd
### 代码编辑器支持
* 根据配置表定义生成相应的json文件的 load 及 save 代码(c#或者c++)方便编辑器加载和导出。每个记录对应一个json文件。
* 支持 unity 下用c# 开发编辑器
* 支持 unreal 下用c++ 开发的编辑器
### 支持多种导出数据格式
* **导出格式与源数据解耦**。无论源数据是 excel、lua、xml、json 或者它们的混合, 最终都被以统一的格式导出,极大简化了生成代码的复杂性。
* 导出binary。 内置binary格式加载最快占空间最少。
* 导出json 格式
* 导出 lua 格式
* 非常容易扩展其他输出格式(一般来说不到300行代码)
### 本地化支持
* 支持**本地化时间**。 配置中的 datetime会根据指定的timezone及localtime转化为正确的utc时间方便程序处理
* 支持**静态本地化**。 配置中的text类型在导出时已经转化为正确的本地化后的字符串
* 支持**动态本地化**。 配置中的text类型能运行时全部切换为某种本地化后的字符串
### 代码编辑器支持
* 支持 emmylua anntations。生成的lua包含符合emmylua 格式anntations信息。配合emmylua有强大的配置代码提示能力。
### 强大的数据校验能力
* 完整的数据内建约束检查
* ref 检查。检查表引用合法性。
* path 检查。检查资源引用合法性,对于防止策划填错极其有用,不再需要运行时才发现资源配置错误了。
* range 检查。检查数值范围。
* 扩展的自定义检查。使用自定义代码进行高级检查。提交配置前就能完成本地检查,避免运行时才发现错误,极大减少迭代成本。
### 资源导出支持
* 支持 res 资源标记。可以一键导出配置中引用的所有资源列表(icon,ui,assetbundle等等)
### 优秀的代码生成
- 良好模块化。比如对于c#语言生成cfg.item.Item,cfg.equip.EquipInfo这样的类
- 内存性能优化。支持c#值类型以及lua的紧凑格式保存数据节约内存。
- 支持为ref的字段生成resolve后的字段定义及加载后设置。读取所引用的字段不用再查表了。
- 支持对 list 类型数据 生成 index, 方便按列表和索引方式访问的需求。
### 良好的数据组织
- 数据模块化。允许策划按模块目录自由组织数据。
- 数据多源化。允许策划按需求选择最合适的源数据类型。
### 支持的语言 (覆盖主流的语言)
* 支持 c# (所有 .net framework 2 及以上, .net core平台)
* 支持 java (java 1.6 及以上)
* 支持 c++ ( c++ 11 及以上)
* 支持 go
* 支持 lua (5.1 及以上)
* 支持 typescript
* **新增其他语言支持非常容易**
### 支持的服务器引擎(满足语言版本的情况下)
* 纯 c# 的所有引擎
* 纯 java 的所有引擎
* 纯 go 的所有引擎
* 纯 c++ 的所有引擎
* 纯 lua 的所有引擎
* 纯 js或typescript的所有引擎
### 支持的客户端引擎(满足语言版本的情况下)
* unity + c#
* unity + tolua
* unity + xlua
* unity + ILRuntime
* cocosx-lua
* cocosx-js
* unreal + 纯 c++
* unreal + unlua
* unreal + puerts (typescript)
* 支持微信小程序和小游戏 sdk
* 支持 lua 的其他任何引擎
* 支持 js 或 typescript的 其他任何引擎
### 强大的扩展能力
* 支持插件形式,扩展其他生成极其方便

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

22
docs/index.md 100644
View File

@ -0,0 +1,22 @@
# 欢迎使用 Luban
## 介绍
Luban 是一个强大的生成与缓存工具。最初只用于对象生成对象可以是常规代码、配置数据、类似protobuf的消息代码也可以是游戏资源如assetbundle。
在大型项目中由于配置或资源数据庞大生成对象可能会花费相当多的时间。比如一个典型的MMORPG项目后期全量生成配置即使用了多线程加速所需时间
也在10秒的级别。因此使用client/server模式配合缓存机制来大幅加速生成过程。
Luban 最初是为了解决传统excel导出工具功能过于薄弱无法很好解决MMORPG游戏复杂配置需求的痛点问题。 自2015年以来经历过 MMORPG、卡牌、SLG 等多个上线项目的考验,
实际项目过程中不断迭代和优化,理解逐渐深入,最终由一个增强型的配置工具成为一个 **相对完备的游戏配置数据解决方案**。
## 文档
* [目录](docs/catalog.md)
## 支持和联系
QQ 群 : 692890842
QQ 群名 : Luban 开发交流群
邮箱 : taojingjian#gmail.com

177
docs/install.md 100644
View File

@ -0,0 +1,177 @@
# 安装与执行
## 安装
1. dotnet sdk 5.0
1. 下载luban_examples项目
下载项目 [luban_examples](https://github.com/focus-creative-games/luban_examples)。
项目中包含测试配置、最新的luban_client&luban_server工作以及大量的示例项目。为方便起见后续提及到的文件默认都指这个项目中的文件。
1. 部属 luban-server
- 基于 docker
docker run -d --rm --name luban-server -p 8899:8899 focuscreativegames/luban-server:latest
- 基于 .net 5 runtime 推荐win平台使用可跨平台不需要重新编译
- 从[示例项目](https://github.com/focus-creative-games/luban_examples/tree/main/Tools/Luban.Server)拷贝 Luban.Server**可跨平台即使在linux、mac平台也不需要重新编译**
- 在Luban.Server目录下运行 dotnet Luban.Server.dll
1. 使用 luban-client
- 基于 docker (推荐 linux、mac平台使用)
docker run --rm -v $PWD/.cache.meta:/bin/.cache.meta focuscreativegames/luban-client <参数>
提醒! .cache.meta这个文件用于保存本地生成或者提交到远程的文件md5缓存**强烈推荐** 添加-v 映射不然每次重新计算所有涉及文件的md5,这可能在项目后期会造成多达几秒的延迟。
- 基于 .net 5 runtime 推荐win平台使用可跨平台不需要重新编译
- 从[示例项目](https://github.com/focus-creative-games/luban_examples/tree/main/Tools/Luban.Client)拷贝 Luban.Client**可跨平台即使在linux、mac平台也不需要重新编译**
- 在Luban.Client目录下运行 dotnet Luban.Client.dll <参数>
1. 设置全局环境变量
set_global_envs.bat 脚本文件,它会设置全局环境变量 LUBAN_SERVER_IP 为 127.0.0.1。如果你在其他机器上部属luban-server请将LUBAN_SERVER_IP改为相应地址。
## 创建游戏配置
1. 创建目录结构
config 为根目录,下面创建两个子目录 Datas 和 Defines分别用于 存放策划 excel 及各种配置数据 以及 配置定义。
![如图](images/install/install_01.png)
2. 在 Defines 目录下创建 \_\_root__.xml 根定义文件
![如图](images/install/install_02.png)
可以直接从 [示例配置](https://github.com/focus-creative-games/luban_examples/tree/main/DesignerConfigs/Defines) 拷贝这个文件。
这个 root 文件描述了:
- 生成代码的默认顶层命名空间为 cfg
- 有 3 个分组 c,s,e 对应 clientservereditor 分组。 分组用于配置选择性导出。后面再介绍。
- import name=”.” 表明从当前目录导入所有子模块定义文件。我们会把所有子模块定义文件也放到 Defines 目录下。
- server 表示最终输出的目标。当前定义了 4 个目标。service 的 group 属性指明了这个目标会包含哪些分组。例如: server 目标就只包含 s 分组,而 all 目标包含了所有分组。我们先不细究这些定义的含义。
7. 创建第一个配置表 物品表
8. 添加物品表 excel 文件
我们可以直接在 Datas 目录下添加 物品表.xlsx 文件,不过如果所有表都放到 Datas 目录下,查找起来很不方便。
为了方便,我们按模块组织配置文件,在 Datas 目录下新建一个 item 目录,目录下创建一个 “物品表.xlsx” 文件。
![如图](images/install/install_03.png)
文件内容如下
![配置](images/install/install_04.png)
- 第 1 行是 meta 行。有一些关于 excel 文件的元描述,默认全空,使用默认默认值即可。
单元格 A1 必须是 ##。表示这是一个有效数据表。
- 第 2 行是程序字段名行。
- 第 3 行是标题头行。策划自行填写,可留空。
- 第 4 行是描述行。策划可以填写字段的补充描述。可留空。
- 从第 5 开始为实际的数据行。如果某个数据行整行为空,则会被跳过。
我们定义一个简单的物品表,有 4 个字段。
- id 道具 id
- name 道具名
- desc 道具描述
- price 道具购买价格
9. 创建定义
我们已经填好了第一个配置表,此时应该会有疑问:
1. 字段类型呢?字段类型怎么没有定义啊?
2. 生成的代码中相关的类名又在哪儿获得呢?
3. 如何导出?最终导出的数据在哪个文件? 导出文件又是啥格式?
---
我们正式开始:
每个配置表都需要在某个子模块定义文件中添加一个相应的定义描述,每个模块可以包含多个表定义。
我们在 Defines 目录创建 item.xmlitem.xml 是一个子模块定义文件,用于包含物品模块的所有结构,枚举及配表定义。接着在 item.xml 里添加物品表相关定义。
文件内容如下:
![定义](images/install/install_05.png)
- 简略介绍一下定义:
- table 是表定义,每个表都有一个对应的表定义。
- name 表名。推荐采取 TbXXXX 这种名字约定。
- value 记录的类型。即配置表里每行记录的类型。
- index 以 value 的哪个字段为主键。这里用 Item 结构里的 id 字段做主键。可为空,默认为第一个字段。
- input 数据源。这个表的数据文件来源,相对 Datas 目录。可以是多个,以英文分号 ; 分割。
- bean 用于定义公用结构,同时也用于定义表记录结构。
- name 类型名。 这儿取 Item最终生成的 c#代码会使用 cfg.item.Item 这样的类名。
- var 用于定义字段。
- name 字段名。推荐统一 xx_yy_zz 这种风格。
- type 字段类型。 可以是 bool,int,float,string 等等,完整的类型参见链接。
10. 至此,物品表的创建工作大功告成!
## 生成代码和数据以及在程序中使用
- 根据前后端以及引擎和平台类型以及所用语言,介绍常见组合下,如何生成代码和数据。
1. 项目准备。
拷贝示例项目中 Csharp_DotNetCore_bin\Core 目录到项目中,可以自由组织位置。
此时尝试编译项目,理论上应该能成功编译。
2. 运行生成命令
```bat
<luban.client>
-h 127.0.0.1 ^
-p 8899 ^
-j cfg ^
--^
--define_file <root.xml >^
--input_data_dir <配置数据根目录(Datas)的路径>^
--output_code_dir <输出的代码文件的路径>^
--output_data_dir <导出的数据文件的路径>^
--service server^
--export_test_data^
--gen_types "code_cs_bin,data_bin"
```
**============提醒=============**
**如果你们项目使用json导出格式需要将 --gen_types的参数改为 "code_cs_json,data_json"**
**如果你们项目使用typescript并且json导出格式需要将 --gen_types的参数改为 "code_typescript_json, data_json"**
更多语言或者导出类型的组合,请参考 [luban_examples](https://github.com/focus-creative-games/luban_examples)
**=============================**
如果一切正常,会产生一系列日志,最终一行是 == succ == 。
![类似这样](images/install/install_07.png)
如果遇到 类似这样的错误,说明服务器未启动。 启动 luban-server 即可。
![错误例子](images/install/install_08.png)
如果一切顺利。生成的代码文件会在 output_code_dir 参数指定的 目录中,生成的配置数据会在 output_data_dir 参数指定的目录中。
output_code_dir 加入到 项目中,编译。此时应该能编译成功。
3. 加载配置
只需一行代码既可完成所有配置表的加载工具
```c#
var tables = new cfg.Tables(file =>
new Bright.Serialization.ByteBuf(
System.IO.File.ReadAllBytes( <output_data_dir > + "/" + file)));
```
![代码](images/install/install_09.png)
4. 使用加载后的配置表
cfg.Tables 里包含所有配置表的一个实例字段。
加载完 cfg.Tables 后,只需要用 tables.<表名> 就能获得那个表实例,接着可以做各种操作。
例如我们要访问 id = 1 的那个记录。代码如下
```c#
cfg.item.Item itemInfo = tables.TbItem.Get(1);
Console.WriteLine(“{0} {1} {2} {3}”,
itemInfo.Id, itemInfo.Name, itemInfo.Desc,itemInfo.Price)
```
可能你会注意到item.xml 里定义 Item 时,字段名 id,name,desc,price 首字母被大写了。
工具会根据输出的语言,自动作相应代码风格的字段名转换,也即 boo_bar 会被转换为 BooBar 这样的名字。
这也是为什么推荐 配置字段定义时统一使用 xx_yy_zz 的风格。
5. 至此完成 配置加载与使用!

2
docs/manual.md 100644
View File

@ -0,0 +1,2 @@
# TODO 待补充

14
docs/roadmap.md 100644
View File

@ -0,0 +1,14 @@
## road map 1
* 补充单元测试
* 新增静态本地化支持
* 新增动态本地化支持
* 新增生成用于unreal编辑器的 加载及保存json配置的cpp代码
* 新增生成用于unity 编辑器的 加载及保存json配置的c#代码
## road map 2
* 新增 unity 内嵌编辑器
* 新增 unreal 内嵌编辑器

26
docs/samples.md 100644
View File

@ -0,0 +1,26 @@
[//]: # (Author: bug)
[//]: # (Date: 2020-10-20 20:22:07)
## Python 示例
```Python
```
## TS 示例
``` typescript
```
## C# 示例
``` csharp
```
## C++ 示例
``` c_cpp
```
## Java 示例
``` java
```
## Go 示例
``` go
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Some files were not shown because too many files have changed in this diff Show More