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.
155 lines
4.9 KiB
155 lines
4.9 KiB
1 month ago
|
#!/usr/bin/python
|
||
|
# -*- coding: UTF-8 -*-
|
||
|
|
||
|
#从proto文件中提取数据到lua 目前只有GameCs.proto
|
||
|
|
||
|
import os
|
||
|
import re
|
||
|
import codecs
|
||
|
import time
|
||
|
import getpass
|
||
|
import shutil
|
||
|
|
||
|
|
||
|
CurDir = os.getcwd()
|
||
|
ProtoName = "GameCs.proto"
|
||
|
ProtoBytesName = "GameCs.proto.bytes"
|
||
|
|
||
|
FileHead = "local NETMSG = {}\n_ENV = NETMSG\n"
|
||
|
FileFoot = "\nreturn NETMSG"
|
||
|
|
||
|
ConstDir = CurDir+"/../../u2china_cli_proj/arpg/Assets/Lua/Const"
|
||
|
ProtocolDir = "../../u2china_cli_proj/arpg/Assets/Protocol/"
|
||
|
|
||
|
MsgFileName = "NetMsgs.lua"
|
||
|
|
||
|
MsgFilter = ["CS_MSGID_NONE", "CS_GAMEMSGID_NONE", "SC_GAMEMSGID_NONE"]
|
||
|
|
||
|
def getFileData(fileName):
|
||
|
data = None
|
||
|
with open(fileName, encoding='UTF-8') as f:
|
||
|
data = f.read()
|
||
|
return data
|
||
|
|
||
|
def fileWrite(fileName, data):
|
||
|
with codecs.open(fileName, "w", "utf8") as f:
|
||
|
#timeStr = "-- build by:" + getpass.getuser() + " " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "\n"
|
||
|
f.write(FileHead + data + FileFoot)
|
||
|
return
|
||
|
|
||
|
|
||
|
# 获取SC_GAMEMSGID_ENTER_DESK_NOTIFY = 3001
|
||
|
def getMsgIDStr(data, keyword):
|
||
|
content = re.findall(r"\s+" + keyword + r"\s*{([^{}]*)}", data)
|
||
|
if len(content) > 0:
|
||
|
lines = content[0].split("\n") #逐行
|
||
|
lineList = []
|
||
|
#del_list = []
|
||
|
for line in lines:
|
||
|
#lineList = re.findall(r"(/*\s*\w+\s*=\s*\d+)", content[0])
|
||
|
val = line
|
||
|
pos = line.find("//")
|
||
|
if pos != -1: #截取注释
|
||
|
val = line[0:pos]
|
||
|
ss = re.findall(r"(\w+\s*=\s*\d+)", val)
|
||
|
if len(ss) > 0:
|
||
|
s = ss[0]
|
||
|
if s.find(MsgFilter[0]) == -1 and s.find(MsgFilter[1]) == -1 and s.find(MsgFilter[2]) == -1: #注释掉的协议剔除
|
||
|
lineList.append(s)
|
||
|
return lineList
|
||
|
|
||
|
def getEnumKeyList(data):
|
||
|
enumKeyList = re.findall(r"enum\s+(\w+)", data)
|
||
|
delEnumKeyList = re.findall(r"/{2,}[\t\r\f ]*enum\s+(\w+)", data)
|
||
|
for s in delEnumKeyList:
|
||
|
try:
|
||
|
enumKeyList.remove(s)
|
||
|
except ValueError:
|
||
|
pass
|
||
|
return enumKeyList
|
||
|
|
||
|
#获取枚举和消息ID类型
|
||
|
def getEnumData(data):
|
||
|
msgValueMap = {}
|
||
|
msgRegex = r"([\w_]+)\s?=\s?(\d+)"
|
||
|
enumKeyList = getEnumKeyList(data)
|
||
|
|
||
|
msgIdData = ""
|
||
|
enumData = ""
|
||
|
for key in enumKeyList:
|
||
|
if key.find("MsgID") != -1:
|
||
|
msgIdData = msgIdData + "-- " + key + '\n'
|
||
|
for s in getMsgIDStr(data, key):
|
||
|
msgKeyValue = re.findall(msgRegex, s)
|
||
|
for pair in msgKeyValue:
|
||
|
msgValueMap[pair[0]] = int(pair[1])
|
||
|
msgIdData = msgIdData + s + '\n'
|
||
|
msgIdData = msgIdData + '\n'
|
||
|
else:
|
||
|
_str = key + " = {\n"
|
||
|
for s in getMsgIDStr(data, key):
|
||
|
_str = _str + '\t' + s + ',\n'
|
||
|
_str = _str + '}\n\n'
|
||
|
enumData = enumData + _str
|
||
|
for key in msgValueMap:
|
||
|
if key.find("REQ") !=-1:
|
||
|
resKey = key.replace("REQ", "RES")
|
||
|
if msgValueMap.get(resKey):
|
||
|
if msgValueMap[key] + 1 != msgValueMap[resKey]:
|
||
|
print(key, "请求和响应的消息ID不连续,需要修正")
|
||
|
else:
|
||
|
print(key,"没有响应消息")
|
||
|
|
||
|
return enumData + msgIdData
|
||
|
|
||
|
# 获取消息ID与消息名对应的值
|
||
|
'''
|
||
|
通过//注释匹配 支持多ID对应一个消息
|
||
|
//CS_MSGID_PING
|
||
|
//CS_GAMEMSGID_PING
|
||
|
message CSPing {
|
||
|
int64 clientTime = 1;
|
||
|
int64 serverTime = 2;
|
||
|
}
|
||
|
'''
|
||
|
messageRe = re.compile(r"message\s*(\w+)\s*{")
|
||
|
def getMessageByMsgID(data, msgID):
|
||
|
idSearch = re.search(r"//[ \t]*" + msgID + r"\W", data)
|
||
|
if idSearch:
|
||
|
msgNameSearch = messageRe.search(data, idSearch.span()[1])
|
||
|
if msgNameSearch:
|
||
|
return msgNameSearch.group(1)
|
||
|
return ""
|
||
|
|
||
|
def getMsgName(data):
|
||
|
msgIdList = re.findall(r"enum\s+(\w+MsgID)", data)
|
||
|
undefined = "--[[\n"
|
||
|
msgData = "MsgList = {\n"
|
||
|
for key in msgIdList:
|
||
|
for s in getMsgIDStr(data, key):
|
||
|
nameSearch = re.search(r"(\w+)\s*=", s)
|
||
|
if nameSearch:
|
||
|
name = nameSearch.group(1)
|
||
|
msg = getMessageByMsgID(data, name)
|
||
|
if len(msg) == 0:
|
||
|
log = name + " not found the annotation!"
|
||
|
undefined = undefined + log + '\n'
|
||
|
print(log)
|
||
|
else:
|
||
|
msgData = msgData + ("\t[%s] = \"%s\",\n") % (name, msg)
|
||
|
undefined = undefined + "]]"
|
||
|
msgData = msgData + "}"
|
||
|
return undefined + "\n" + msgData
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
protocolFile = os.path.join(CurDir, ProtoName)
|
||
|
if not os.path.exists(ProtocolDir):
|
||
|
os.makedirs(ProtocolDir)
|
||
|
|
||
|
shutil.copy(protocolFile, os.path.join(ProtocolDir, ProtoName))
|
||
|
#shutil.copy(protocolFile, os.path.join(ProtocolDir, ProtoBytesName))
|
||
|
fileData = getFileData(protocolFile)
|
||
|
enumData = getEnumData(fileData)
|
||
|
msgNameData = getMsgName(fileData)
|
||
|
fileWrite(os.path.join(ConstDir, MsgFileName), enumData + msgNameData)
|