You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
15 KiB

1 month ago
# -*- coding: UTF-8 -*-
import xlrd
import os
import shutil
import re
import sys
import json
from functools import cmp_to_key
INT_KEY_TYPE = "int_key"
UINT_KEY_TYPE = "uint_key"
STRING_KEY_TYPE = "string_key"
INT_TYPE = "int"
FLOAT_TYPE = "float"
UINI_TYPE = "uint"
STRING_TYPE = "string"
STRING_LAN_TYPE = "string_lan"
STRING_LUA_TYPE = "string_lua"
STRING_LIST_TYPE = "string[]"
INT_LSIT_TYPE = "int[]"
UINT_LSIT_TYPE = "uint[]"
LONG_LSIT_TYPE = "long[]"
FLOAT_LIST_TYPE = "float[]"
LONG_TYPE = "long"
NONE_TYPE = "none"
LUA_WORD = "(LUA)"
excel_dir = "./Excel"
generate_lua_dir = "../../client/pandora/Assets/Lua/Desc"
generate_lua_lang_dir = "../../client/pandora/Assets/Lua/Desc/LanguageDesc"
excel_suffix = ".xlsx"
temp_excel_prefix = "~$"
alone_save_excel = [
]
excel_config_file = "ClientExcelConfig.json"
excel_self_config_file = "./selfExcelConfig/ClientExcelConfig.json"
class FirstColumn:
def __init__(self, key):
self._rawKey = key
self._key = key
self._list_count = 1
self._list_index = 0
self._inew_table = 0
self.parse()
def parse(self):
match = re.match(r"(\w+)_(\d+)_(\d+)", self._key)
if match:
self._key = match.group(1)
self._list_count = int(match.group(2))
self._list_index = int(match.group(3))
match2 = re.match(r"(\w+)_(\d+)_(\w+)",self._key)
if match2:
self._key = match2.group(1)
self._list_index = int(match2.group(2))
self._list_key = match2.group(3)
self._inew_table = 1
def get_key(self):
return self._key
def get_list_key(self):
return self._list_key
def is_list(self):
return self._list_count > 1
def get_list_index(self):
return self._list_index
def is_newtable(self):
return self._inew_table > 0
def get_cell_value(value_type, value,key=None):
if value is None or value == "":
return "nil"
elif value_type == INT_KEY_TYPE or value_type == INT_TYPE or value_type == UINT_KEY_TYPE or value_type == UINI_TYPE or value_type == LONG_TYPE:
return int(round(float(value)))
elif value_type.startswith(INT_LSIT_TYPE):
# if type(value) is str:
# value = value.encode("utf8")
value = str(value)
value = value.replace(',',';')
value = value.split(';')
value = [int(round(float(x))) for x in value]
return value
elif value_type.startswith(UINT_LSIT_TYPE):
# if type(value) is str:
# value = value.encode("utf8")
value = str(value)
value = value.replace(',',';')
value = value.split(';')
value = [int(round(float(x))) for x in value]
return value
elif value_type.startswith(LONG_LSIT_TYPE):
# if type(value) is str:
# value = value.encode("utf8")
value = str(value)
value = value.replace(',',';')
value = value.split(';')
value = [int(round(float(x))) for x in value]
return value
elif value_type.startswith(FLOAT_LIST_TYPE):
# if type(value) is str:
# value = value.encode("utf8")
value = str(value)
value = value.replace(',',';')
value = value.split(';')
value = [float(x) for x in value]
return value
elif value_type == FLOAT_TYPE:
return float(value)
elif value_type.startswith(STRING_LIST_TYPE):
# if type(value) is str:
# value = value.encode("utf8")
value = str(value)
value = value.replace(',',';')
value = value.split(';')
value = [x.strip() for x in value]
return value
elif value_type == STRING_KEY_TYPE or value_type == STRING_TYPE or value_type == STRING_LAN_TYPE:
# if type(value) is str or type(value) is str:
# value = value.encode("utf8")
value = str(value)
#语言表
value = value.replace("\n", "\\n")
value = value.replace("\"", "\\\"")
value = value.replace("<String>", "%s")
value = value.replace("<Number>", "%s")
value = value.replace("<string>", "%s")
value = value.replace("<number>", "%s")
return value
elif value_type == STRING_LUA_TYPE:
return LUA_WORD+str(value)
# elif value_type == STRING_LAN_TYPE:
# value = value.encode("utf8")
# lang_key = str(value).replace("#", "")
# return LUA_WORD+"GM and GM.Lang(\"%s\") or \"%s\"" % (lang_key, lang_key)
return None
def sort_spell_skin_show(table):
items = []
for key in table:
items.append(table[key])
def sort_method(item1,item2):
if item1["spellId"] < item2["spellId"]:
return -1
elif item1["spellId"] > item2["spellId"]:
return 1
else:
if item1["skinIndex"] < item2["skinIndex"]:
return -1
elif item1["skinIndex"] > item2["skinIndex"]:
return 1
else:
if item1.get("layer") != "nil":
if item1["layer"] < item2["layer"]:
return -1
else:
return 1
else:
return 0
sorted_items = sorted(items,key = cmp_to_key(sort_method))
return sorted_items
def excel_to_lua_data(path, isLanguage):
excel_data = {}
xml_data = xlrd.open_workbook(path) # 打开xls文件
sheet = xml_data.sheets()[0] # 打开第一张表
# 先判断key的数量
row_num = sheet.nrows # 获取表的行数
col_num = sheet.ncols # 获取表的列数
row_key_values = sheet.row_values(0) # 获取表的第一行的所有数据
row_type_values = sheet.row_values(1) # 获取表的第二行的所有数据
row_cs_values = sheet.row_values(2) # 获取表的第三行的所有数据
row_desc_values = sheet.row_values(3) # 获取表的第四行的所有数据
index_list = [] # 需要导出的列索引
key_list_map = {} # 所有key_value的列表
key_list = [] # key的列表
for i in range(0, col_num):
key_value = row_key_values[i]
type_value = row_type_values[i]
cs_value = row_cs_values[i]
if type_value == INT_KEY_TYPE or type_value == UINT_KEY_TYPE or type_value == STRING_KEY_TYPE:
key_list.append(key_value)
if key_value not in key_list_map:
key_list_map[key_value] = []
for row in range(4, row_num):
try:
key_list_map[key_value].append(get_cell_value(type_value, sheet.row_values(row)[i]))
except:
print("error file:" + path + ",key:" + key_value + ",row:" + str(row))
sys.exit()
#忽略的部分列
if key_value != NONE_TYPE and cs_value != "skip" and cs_value.find("c") != -1:
if isLanguage:
if type_value != STRING_KEY_TYPE:
index_list.append(i)
else:
index_list.append(i)
def set_row_value(row, obj):
row_values = sheet.row_values(row)
for i in index_list:
first_column = FirstColumn(row_key_values[i])
column_key = first_column.get_key()
try:
#数组单独处理
if first_column.is_list():
if column_key not in obj:
obj[column_key] = {}
obj[column_key][first_column.get_list_index()+1] = get_cell_value(row_type_values[i], row_values[i])
elif first_column.is_newtable():
if column_key not in obj:
obj[column_key] = {}
if (first_column.get_list_index()+1) not in obj[column_key]:
obj[column_key][first_column.get_list_index()+1] = {}
obj[column_key][first_column.get_list_index()+1][first_column.get_list_key()] = get_cell_value(row_type_values[i], row_values[i])
else:
obj[column_key] = get_cell_value(row_type_values[i], row_values[i])
except:
print("error file:" + str(path) + ",key:" + str(column_key), ",row:" + str(row))
sys.exit()
table = {}
if len(key_list) == 2:
#暂时只支持2个key
row_index = 0
for row in range(4, row_num):
first_key = key_list_map[key_list[0]][row_index]
second_key = key_list_map[key_list[1]][row_index]
row_index = row_index + 1
if first_key == "" or first_key == "nil" or second_key == "" or second_key == "nil":
print("%s key is nil,row:%d" % (path, row))
continue
if first_key not in table:
table[first_key] = {}
if second_key not in table[first_key]:
table[first_key][second_key] = {}
obj = table[first_key][second_key]
set_row_value(row, obj)
elif len(key_list) <= 1:
#没有key或者单个key
row_index = 0
row_key_list = None
if len(key_list) > 0:
row_key_list = key_list_map[key_list[0]]
for row in range(4, row_num):
row_index = row_index + 1
row_key = row_index
if not (row_key_list is None):
row_key = row_key_list[row_index-1]
if row_key == "nil" or row_key == "":
print("%s key is nil,row:%d" % (path, row))
continue
if row_key not in table:
table[row_key] = {}
obj = table[row_key]
set_row_value(row, obj)
file_name = os.path.basename(path)
if file_name == "SpellActionSkinShowDesc.xlsx":
try:
table = sort_spell_skin_show(table)
except Exception as e:
print(e)
return obj_to_lua(table)
#######################################################################
def value_tostring(value):
value_type = type(value)
if value_type is str:
value = str(value)
value_type = type(value)
if value is None:
return "nil"
if value_type == str:
if value == "" or value == "nil":
return "nil"
if value.find(LUA_WORD, 0, len(LUA_WORD)) == -1:
return "\"%s\"" % value
else:
return value.replace(LUA_WORD, "")
elif value_type == bool:
if value:
return "true"
else:
return "false"
else:
return value
def key_tostring(key):
key_type = type(key)
if key_type == int:
return "[%d]" % key
elif key_type == str:
return key
def obj_to_lua(obj):
result = []
def _encode_to_lua(value, key, indent):
if value is None:
return
key_type = type(key)
if key_type != str and key_type != int:
return
value_type = type(value)
if value_type == list or value_type == dict:
result.append("%s%s = {" % (indent, key_tostring(key)))
indent2 = indent + "\t"
if value_type == list:
for i in range(len(value)):
_encode_to_lua(value[i], i + 1, indent2)
elif value_type == dict:
for k in list(value.keys()):
_encode_to_lua(value[k], k, indent2)
if indent == "":
result.append("%s}" % (indent))
else:
result.append("%s}," % (indent))
else:
valueStr = value_tostring(value)
if valueStr != "nil":
result.append("%s%s = %s," % (indent, key_tostring(key), valueStr))
_encode_to_lua(obj, "local M", "")
result.append("return M")
return "\n".join(result)
def excel_to_lua_file(excel_path, lua_path, isLanguage):
if not os.path.exists(excel_path):
print("excel not exists.", excel_path)
return
try:
lua_data = excel_to_lua_data(excel_path, isLanguage)
f = open(lua_path, "w", encoding="UTF-8",newline="\n")
f.write(lua_data)
f.close()
except:
print(excel_path+" 配置错误,检查该表")
exit(-1)
def excel_list_to_lua_file(file_path):
excel_names = os.listdir(file_path)
for name in excel_names:
if name in configs['included'] and name.endswith(excel_suffix) and not name.startswith(temp_excel_prefix):
print(name)
excel_file_path = file_path + os.sep + name
lua_file_name = name[:name.find(excel_suffix)]
lua_dir = generate_lua_dir
if name == "LanguageDesc.xlsx":
lua_dir = generate_lua_lang_dir
if lua_file_name in alone_save_excel:
print("need alone save",name)
lua_file_dir = lua_dir + os.sep + lua_file_name
if not os.path.exists(lua_file_dir):
os.mkdir(lua_file_dir)
lua_file_path = lua_dir + os.sep + lua_file_name + os.sep + lua_file_name + ".lua"
else:
lua_file_path = lua_dir + os.sep + name[:name.find(excel_suffix)] + ".lua"
is_language = name == "LanguageDesc.xlsx"
excel_to_lua_file(excel_file_path, lua_file_path, is_language)
if __name__ == "__main__":
if not os.path.exists(generate_lua_dir):
os.makedirs(generate_lua_dir)
change_region_dir="" #需要替换的区域目录
clean_old_file = True
config_file_name = excel_config_file
if (len(sys.argv) > 1 and sys.argv[1] == "self" ):
config_file_name = excel_self_config_file
clean_old_file = False
elif (len(sys.argv) > 2 and sys.argv[1] == "region" ):
change_region_dir=sys.argv[2] #需要替换的区域目录
if clean_old_file:
for file_name in os.listdir(generate_lua_dir):
if not file_name.startswith("SpellShowDesc") and not file_name.startswith("QuestEventDesc") and not file_name.startswith("DramaDesc") and not file_name.startswith("WorldDesc"):
file_path = os.path.join(generate_lua_dir, file_name)
if os.path.isdir(file_path):
shutil.rmtree(file_path)
else:
os.remove(file_path)
if not os.path.exists(generate_lua_lang_dir):
os.makedirs(generate_lua_lang_dir)
config_file = open(config_file_name)
configs = json.load(config_file)
# print(configs)
config_file.close()
#默认目录xls文件转lua文件
excel_list_to_lua_file(excel_dir)
#区域目录xls文件覆盖,重新生成lua文件
if change_region_dir != "" :
region_file_path = excel_dir + os.sep + change_region_dir
if not os.path.exists(region_file_path):
print(region_file_path+" 目录不存在")
exit(-1)
print(region_file_path+" 目录文件进行覆盖处理")
excel_list_to_lua_file(region_file_path)