From 8c4e52f6f626b1d6dd5f2b8426f51cc5f9b4d63e Mon Sep 17 00:00:00 2001 From: AleaJactaEst Date: Wed, 11 Nov 2020 16:33:08 +0100 Subject: [PATCH] update decoder database.xml --- spykhanat.py | 6 +- tools/BitStream.py | 124 ++++++++++-- tools/CBitSet.py | 24 +++ tools/DecodeDatabase.py | 437 ++++++++++++++++++++++++++++++++++++++-- tools/Enum.py | 15 +- tools/Impulse.py | 112 +++++++--- tools/getPowerOf2.py | 11 + 7 files changed, 654 insertions(+), 75 deletions(-) diff --git a/spykhanat.py b/spykhanat.py index 8589c83..7009b8f 100755 --- a/spykhanat.py +++ b/spykhanat.py @@ -107,9 +107,10 @@ class SpyPcap(): databaseRawXml = fp.read() fp.close() self.databaseXml = ET.fromstring(databaseRawXml) - self.decodeImpulseSimple.loadDatabase(self.databaseXml) + #self.decodeImpulseSimple.loadDatabase(self.databaseXml) self.decodeDatabase = DecodeDatabase.DecodeDatabase() self.decodeDatabase.loadDatabase(self.databaseXml) + self.decodeImpulseSimple.loadDatabase(self.decodeDatabase) # outyaml self.outyaml = outyaml @@ -946,12 +947,13 @@ def main(): # logger.append(logging.getLogger(CStringManager.LOGGER)) #logger.append(logging.getLogger(CAction.LOGGER)) #logger.append(logging.getLogger(CActionFactory.LOGGER)) -# logger.append(logging.getLogger(BitStream.LOGGER)) + logger.append(logging.getLogger(BitStream.LOGGER)) #logger.append(logging.getLogger(DecodeDatabase.LOGGER)) #logger.append(logging.getLogger(Impulse.LOGGER)) #logger.append(logging.getLogger(TVPNodeBase.LOGGER)) # CImpulseDecoder # logger.append(logging.getLogger('CGenericMultiPartTemp')) + logger.append(logging.getLogger(DecodeDatabase.LOGGER)) parser = argparse.ArgumentParser() parser.add_argument("--khanat-host-service", help="filter to detect khanat host:service (FES)") diff --git a/tools/BitStream.py b/tools/BitStream.py index 890b5db..6e05391 100644 --- a/tools/BitStream.py +++ b/tools/BitStream.py @@ -24,6 +24,7 @@ import sys import inspect import copy import struct +from tools import CBitSet LOGGER='BitStream' @@ -536,7 +537,7 @@ class BitStream(): self._groupWrite.append((p1, p2, name, 'BitStream', '')) # ------------------------------------ - def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False, signed=False): + def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False, signed=False, commentValue=None): v1 = self._read if nbits == 0: return @@ -564,10 +565,10 @@ class BitStream(): if decode and not emulate: if signed: value = c_int32(value).value - self._groupRead.append((v1, v1+nbits, name, typeName, value)) + self._groupRead.append((v1, v1+nbits, name, typeName, value, commentValue)) return value - def readSerial64(self, nbits, name="", decode=True, typeName=None): + def readSerial64(self, nbits, name="", decode=True, typeName=None, commentValue=None): if nbits > 32: v1 = self._read msd = self.readSerial(nbits - 32, name, False, typeName) @@ -576,17 +577,83 @@ class BitStream(): if decode: if typeName is None: typeName = 'Uint{0}'.format(nbits) - self._groupRead.append((v1, v1+nbits, name, typeName, value)) + self._groupRead.append((v1, v1+nbits, name, typeName, value, commentValue)) return value else: if typeName is None: typeName = 'Uint{0}'.format(nbits) - return self.readSerial(nbits, name, decode, typeName) + return self.readSerial(nbits, name, decode, typeName, commentValue=commentValue) + + def readCBitSet(self, nbits, name="", decode=True, typeName=None, commentValue=None): + # khanat-opennel-code/code/nel/src/misc/bit_mem_stream.cpp void CBitMemStream::readBits( NLMISC::CBitSet& bitfield ) + cBitSet = CBitSet.CBitSet() + v1 = self._read + cBitSet.resize(nbits) + pos = 0 + last = nbits + logging.getLogger(LOGGER).debug("nbits:%d" % nbits) + while last >= cBitSet.NL_BITLEN: + v = self.readSerial(cBitSet.NL_BITLEN, decode=False) + logging.getLogger(LOGGER).debug("pos:%d v:%d reel:%d" % (pos, v, (nbits//32)-pos-1)) + cBitSet.setUint(v, (nbits//32)-pos-1) + last -= cBitSet.NL_BITLEN + pos += 1 + if last > 0: + v = self.readSerial(last, decode=False) + logging.getLogger(LOGGER).debug("pos:%d v:%d reel:%d" % (pos, v, (nbits//32)-pos-1)) + cBitSet.setUint(v, (nbits//32)-pos-1) +# pos = 0 +# while pos < nbits: +# v = self.readSerial(1, decode=False) +# cBitSet.set(pos, v) +# pos += 1 + if decode: + valuereal = cBitSet.showBitString() + _size = len(valuereal) + _start = _size - nbits + self._groupRead.append((v1, v1+nbits, name, typeName, valuereal[0:nbits], commentValue)) + return cBitSet + + def readCBitSetOld2(self, nbits, name="", decode=True, typeName=None, commentValue=None): + # khanat-opennel-code/code/nel/src/misc/bit_mem_stream.cpp void CBitMemStream::readBits( NLMISC::CBitSet& bitfield ) + cBitSet = CBitSet.CBitSet() + v1 = self._read + cBitSet.resize(nbits) + pos = 0 + logging.getLogger(LOGGER).debug("nbits:%d" % nbits) + pos = 0 + while pos < nbits: + v = self.readSerial(1, decode=False) + logging.getLogger(LOGGER).debug("pos:%d value:%d" % (nbits-pos-1, v)) + cBitSet.set(nbits-pos-1, v) + pos += 1 + if decode: + self._groupRead.append((v1, v1+nbits, name, typeName, '', commentValue)) + logging.getLogger(LOGGER).debug("cBitSet:%s" % cBitSet.showBitString()) + return cBitSet + + def readCBitSetOld3(self, nbits, name="", decode=True, typeName=None, commentValue=None): + # khanat-opennel-code/code/nel/src/misc/bit_mem_stream.cpp void CBitMemStream::readBits( NLMISC::CBitSet& bitfield ) + cBitSet = CBitSet.CBitSet() + v1 = self._read + cBitSet.resize(nbits) + pos = 0 + logging.getLogger(LOGGER).debug("nbits:%d" % nbits) + pos = 0 + while pos < nbits: + v = self.readSerial(1, decode=False) + logging.getLogger(LOGGER).debug("pos:%d value:%d" % (nbits-pos-1, v)) + cBitSet.set(pos, v) + pos += 1 + if decode: + self._groupRead.append((v1, v1+nbits, name, typeName, '', commentValue)) + logging.getLogger(LOGGER).debug("cBitSet:%s" % cBitSet.showBitString()) + return cBitSet def readBool(self, name): v1 = self._read v = self.readSerial(1, name=name, decode=False, typeName='Bool') - self._groupRead.append((v1, v1+1, name, 'Bool', 'True' if v != 0 else 'False')) + self._groupRead.append((v1, v1+1, name, 'Bool', 'True' if v != 0 else 'False', None)) if v != 0: return True else: @@ -638,7 +705,7 @@ class BitStream(): v7 = self.readSerial(8, decode=False) v8 = self.readSerial(8, decode=False) ret = v8 << 56 | v7 << 48 | v6 << 40 | v5 << 32 | v4 << 24 | v3 << 16 | v2 << 8 | v1 - self._groupRead.append((p1, p1+64, name, 'Uint64', ret)) + self._groupRead.append((p1, p1+64, name, 'Uint64', ret, None)) return v3 def readSint64(self, name): @@ -663,7 +730,7 @@ class BitStream(): v7 = self.readSerial(8, decode=False) v8 = self.readSerial(8, decode=False) ret = v8 << 56 | v7 << 48 | v6 << 40 | v5 << 32 | v4 << 24 | v3 << 16 | v2 << 8 | v1 - self._groupRead.append((p1, p1+64, name, 'Sint64', c_int64(ret).value)) + self._groupRead.append((p1, p1+64, name, 'Sint64', c_int64(ret).value, None)) return c_int64(v3).value def readFloat(self, name): @@ -671,7 +738,7 @@ class BitStream(): v = self.readSerial(32, name=name, decode=False, typeName='Float') v1 = struct.pack('I', v) v2 = struct.unpack(' self._pos: raise ValueError if v1 < v2: - self._groupRead.append((v1, v2, name + ':string', 'String', tmp)) + self._groupRead.append((v1, v2, name + ':string', 'String', tmp, None)) return tmp def readUtf8String(self, name): @@ -716,7 +783,7 @@ class BitStream(): if v2 > self._pos: raise ValueError if v1 < v2: - self._groupRead.append((v1, v2, name + ':ustring', 'UString', tmp)) + self._groupRead.append((v1, v2, name + ':ustring', 'UString', tmp, None)) return tmp.decode(encoding='utf-8') def readUString(self, name): @@ -731,7 +798,7 @@ class BitStream(): if v2 > self._pos: raise ValueError if v1 < v2: - self._groupRead.append((v1, v2, name + ':ustring', 'UString', tmp)) + self._groupRead.append((v1, v2, name + ':ustring', 'UString', tmp, None)) return tmp def readArrayUint8(self, size, name): @@ -740,7 +807,7 @@ class BitStream(): for i in range(0, size): ret.append(self.readUint8('', decode=False)) v2 = self._read - self._groupRead.append((v1, v2, name, 'ArrayUint8', '')) + self._groupRead.append((v1, v2, name, 'ArrayUint8', '', None)) return ret def readBitStreamUint8(self, size, name): @@ -749,7 +816,7 @@ class BitStream(): for i in range(0, size): ret.pushUint8(self.readUint8('', decode=False), decode=False) v2 = self._read - self._groupRead.append((v1, v2, name, 'StreamUint8', '')) + self._groupRead.append((v1, v2, name, 'StreamUint8', '', None)) return ret def readCont(self, name): @@ -759,7 +826,7 @@ class BitStream(): for i in range(0, size): ret.pushBool(self.readSerial(1,name = '', decode=False)) v2 = self._read - self._groupRead.append((v1, v2, name + ':data', 'readCont', '')) + self._groupRead.append((v1, v2, name + ':data', 'readCont', '', None)) return size, ret def getNotRead(self): @@ -851,8 +918,18 @@ class BitStream(): ret2 = "" last = 0 - for x, y, name, typeName, value in self._groupRead: - ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') : ' + ret[x:y] + ' => ' + str(value) + "]" + for x, y, name, typeName, value, commentValue in self._groupRead: + if typeName == None: + typeName = '-' + if commentValue == None: + strcommentValue = "" + else: + strcommentValue = " " + commentValue + if value: + strvalue = ' => ' + str(value) + else: + strvalue = '' + ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') : ' + ret[x:y] + strvalue + strcommentValue + "]" last = y if last < self._pos: ret2 += "{" + ret[last:] + "}" @@ -890,6 +967,8 @@ class BitStream(): last = 0 for x, y, name, typeName, value in self._groupWrite: + if typeName == None: + typeName = '-' ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') : ' + ret[x:y] + ' => ' + str(value) + "]" last = y if last < self._pos: @@ -958,13 +1037,18 @@ class BitStream(): ret2 = [] last = 0 - for x, y, name, typeName, value in self._groupRead: + for x, y, name, typeName, value, commentValue in self._groupRead: + if commentValue == None: + commentValue = "" + plus = "" + else: + plus = " " if not typeName: nbbit = y - x typeName = "%d bit" % nbbit if nbbit > 1: typeName += "s" - ret2.append("<" + str(x) + ':' + str(y-1) + "> " + '(' + typeName + ') ' + str(name) + ' => ' + str(value) + " : " + ret[x:y]) + ret2.append("<" + str(x) + ':' + str(y-1) + "> " + '(' + typeName + ') ' + str(name) + ' => ' + str(value) + " : " + ret[x:y] + plus + commentValue) last = y if last < self._pos: ret2.append("<" + str(last) + ':' + str(self._pos - 1) + "> " + ret[last:]) diff --git a/tools/CBitSet.py b/tools/CBitSet.py index a05f3a0..e80d62f 100644 --- a/tools/CBitSet.py +++ b/tools/CBitSet.py @@ -57,6 +57,9 @@ class CBitSet: mask= bitNumber&(self.NL_BITLEN-1); mask= 1<> 5] & mask != 0 + + def setUint(self, srcValue, i): + self.data[i] = srcValue def setBit(self, bitNumber): self.set(bitNumber, True) @@ -66,6 +69,10 @@ class CBitSet: def __str__(self): return '.'.join([hex(x) for x in self.data]) + + def showBitString(self): + return ''.join(["{0:032b}".format(x) for x in reversed(self.data)]) + def writeSerial(self, msgout): # v = 0 # currentVersion # if v >= 0xff: @@ -94,6 +101,23 @@ class CBitSet: y = msgin.readUint32( name+':Data' ) self.data[i] = y + def readSerialExtra(self, msgin, nbBit, name): + needread = nbBit + print("----", nbBit, nbBit // 32 + 1) + self.resize(nbBit) + i = 0 + while needread>32: + print("---<", nbBit, nbBit // 32 + 1, i, needread) + y = msgin.readUint32( name+' Data' + str(i)) + self.data[i] = y + needread -= 32 + i += 1 + print(self.data) + if needread > 0: + print("--->", nbBit, nbBit // 32 + 1, i, needread) + y = msgin.readSerial( needread, name+' Data' + str(i), typeName="I" + str(needread) ) + self.data[i] = y + def TestCBitSet(): cBitSet = CBitSet() cBitSet.resize(1024) diff --git a/tools/DecodeDatabase.py b/tools/DecodeDatabase.py index 6152371..76d0607 100644 --- a/tools/DecodeDatabase.py +++ b/tools/DecodeDatabase.py @@ -20,17 +20,21 @@ import logging from tools import getPowerOf2 +from tools import BitStream LOGGER='DecodeDatabase' def show_dico(dico, level=1): - for ele in dico: - if isinstance(dico[ele], dict): - print("." * level, ele , ":") + try: + for ele in dico: if isinstance(dico[ele], dict): - show_dico(dico[ele], level+1) - else: - print("." * level, ele, ':', dico[ele]) + print("." * level, ele , ":") + if isinstance(dico[ele], dict): + show_dico(dico[ele], level+1) + else: + print("." * level, ele, ':', dico[ele]) + except: + print("empty") def child(ele): ret = {} @@ -77,63 +81,452 @@ def child(ele): return ret def count_elements(head): + print("%" * 80) + #print(head) + if 'child' in head.keys(): + list_ele = [x for x in list(head['child'].keys()) if isinstance(x, int)] + else: + list_ele = [x for x in list(head.keys()) if isinstance(x, int)] + print(list_ele) + last_key = max(list_ele) + print(last_key ) + print("%" * 80) try: - return head.items()[-1]['max'] + 1 + last_key = max(list_ele) + if 'child' in head.keys(): + return head['child'][last_key]['max'] + 1 + else: + return head[last_key]['max'] + 1 except TypeError: - return len(head) + return 0 def get_element(head, id): print("id:", id) - for ele in head: - if id <= head[ele]['max'] and id >= head[ele]['min']: - return head[ele] + for ele in head['child']: + print("ele:", ele) + print("head:", head) + print("max:", head['child'][ele]['max']) + print("min:", head['child'][ele]['min']) + if id <= head['child'][ele]['max'] and id >= head['child'][ele]['min']: + return head['child'][ele] return None + + +class LeafDatabase(): + def __init__(self): + self.name = "" + self.type = "" + self.count = None + + def loadXml(self, xmldata): + self.name = xmldata.get('name') + self.type = xmldata.get('type') + if xmldata.get('count'): + self.count = int(xmldata.get('count')) + + def countLeaves(self): + if self.count: + return self.count + else: + return 1 + + def show(self, level=1): + print(" " * level, level, " Leaf ", self.name, ":", self.count, ":", self.type) + + def execute(self, msgin, name=""): + if name: + tmp = "/" + name + else: + tmp = "/" + self.name + if self.type[0] == 'I': + logging.getLogger(LOGGER).debug("Read:" + str (self.type)) + value = int(self.type[1:]) + _ = msgin.readSerial64(value, name='DatabaseXML' + tmp, typeName=self.type) + else: + logging.getLogger(LOGGER).debug("Type inconnu:" + str (self.type)) + raise "type not managed" + + def execute_atom(self, level, pos, msgin, name=""): + if name: + extraName = "/" + name + "/" + self.name + else: + extraName = "/" + self.name + if self.count: + step = self.count + else: + step = 1 + for step in range(0, step): + if self.count: + idname = extraName + str(step) + else: + idname = extraName + logging.getLogger(LOGGER).debug('step:' + str(step) + ' level:'+ str(level) + ' pos:' + str(pos) + ' idname:' + idname) + if level < pos: + level += 1 + continue + if self.type[0] == 'I': + value = int(self.type[1:]) + _ = msgin.readSerial(value, name='DatabaseXML' + idname, typeName=self.type) + return level+1 + else: + logging.getLogger(LOGGER).debug("Type inconnu:", self.type) + raise "type not managed" + return level + + +class BranchDatabase(): + def __init__(self): + self.name = None + self.branch = [] + self.leaf = [] + self.min = None + self.max = None + self.atom = False + self.count = None + + def loadXml(self, xmldata, filter=None): +# print("xmldata:", xmldata) +# print("keys:", xmldata.keys()) +# print("filter:", filter) + #print("bank:", xmldata['bank']) + if filter: + if 'bank' in xmldata: + if filter != xmldata['bank']: + return + else: + return + if xmldata.get('atom'): + self.atom = True + if xmldata.get('count'): + self.count = int(xmldata.get('count')) + self.name = xmldata.get('name') +# print(self.name) + for ele in xmldata: + if ele.tag == 'branch': + newbranch = BranchDatabase() + newbranch.loadXml(ele) + self.branch.append(newbranch) + elif ele.tag == 'leaf': + newleaf = LeafDatabase() + newleaf.loadXml(ele) + self.leaf.append(newleaf) + + def loadRootXml(self, xmldata, filter=None): + for ele in xmldata: + if ele.tag == 'branch': + if filter: + if ele.get('bank') == filter: +# print(ele.get('bank'), filter) + newbranch = BranchDatabase() + newbranch.loadXml(ele) + self.branch.append(newbranch) + + def getIdBits(self): + count = 0 + for ele in self.branch: + if ele.count: + count += ele.count + else: + count += 1 + for ele in self.leaf: + if ele.count: + count += ele.count + else: + count += 1 + return count + + def countLeaves(self): + count = 0 + for ele in self.branch: + count += ele.countLeaves() + for ele in self.leaf: + count += ele.countLeaves() + if self.count: + count *= self.count + return count + + def execute_atom_found(self, level, pos, msgin, name=""): + if self.count: + step = self.count + else: + step=1 + if name: + extraName = name + "/" + self.name + else: + extraName = self.name + for step in range(0, step): + logging.getLogger(LOGGER).debug('step:' + str(step)+ ' level:' + str(level) + ' pos:' + str(pos) + ' name:' + name) + if self.count: + idname = extraName + str(step) + else: + idname = extraName + for ele in self.branch: + level = ele.execute_atom_found(level, pos, msgin, idname) + logging.getLogger(LOGGER).debug('step:' + str(step)+ ' level:' + str(level) + ' pos:' + str(pos) + ' name:' + name + ' idname:' + str(idname)) + if level > pos: + return level + for ele in self.leaf: + level = ele.execute_atom(level, pos, msgin, idname) + logging.getLogger(LOGGER).debug('step:' + str(step)+ ' level:' + str(level) + ' pos:' + str(pos) + ' name:' + name + ' idname:' + str(idname)) + if level > pos: + return level + return level + + def show(self, level=0, pos=0, filterlevel=None): + print(" " * level, level, "pos:", pos, " Branch ", self.name, ":", self.count, ":", self.atom, self.getIdBits()) + if filterlevel is not None: + if filterlevel <= level: + return + i = 0 + for ele in self.branch: + ele.show(level + 1, i, filterlevel) + i += 1 + for ele in self.leaf: + ele.show(level + 1) + + def execute_atom(self, msgin): + nbchild = self.countLeaves() + #nbBit = getPowerOf2.getPowerOf2_Bis(nbchild) + + logging.getLogger(LOGGER).debug("needRead:" + str(msgin.needRead()) + " nbchild:" + str(nbchild)) + logging.getLogger(LOGGER).debug(msgin.showAllData()) + cBitSet = msgin.readCBitSet(nbchild, self.name + ":Param", typeName = 'I' + str(nbchild)) + #cBitSet = CBitSet.CBitSet() + #cBitSet.readSerialExtra(msgin, nbchild, self.name + "/Param") + logging.getLogger(LOGGER).debug(msgin.showAllData()) + todelete_count_true = 0 + for i in range(0, nbchild): + #ii = nbchild - i + logging.getLogger(LOGGER).debug(str(i) + " - " + str(cBitSet.get(i))) + if cBitSet.get(i): + todelete_count_true += 1 + _ = self.execute_atom_found(0, i, msgin) + if todelete_count_true > 1: + logging.getLogger(LOGGER).debug(msgin.showAllData()) + #raise "A controler" + logging.getLogger(LOGGER).debug(msgin.showAllDataRaw()) + logging.getLogger(LOGGER).debug(msgin.showAllData()) + #raise "A faire" + + def execute_normal(self, msgin): + nbchild = self.getIdBits() + #nbBit = getPowerOf2.getPowerOf2_Bis(nbchild) + nbBit = getPowerOf2.getPowerOf2_ter(nbchild) + if nbBit > msgin.needRead() : + return + logging.getLogger(LOGGER).debug("needRead:" + str(msgin.needRead()) + " nbBit:" + str(nbBit)) + id = msgin.readSerial(nbBit, name='DatabaseXML', typeName='Number:'+str(nbBit), emulate=True) + i = 0 + ii = 0 + for ele in self.branch: + logging.getLogger(LOGGER).debug(str(i) + " id:" + str(id) + " name:" + str(ele.name)) + if ele.count: + i += ele.count + else: + i += 1 + if i > id: + comment = "" + if ele.count: + pos = id - ii + comment = str(pos) + logging.getLogger(LOGGER).debug(str(i) + " id:" + str(id) + " name:" + str(ele.name)) + if self.name: + idname = '/' + self.name + '/' + ele.name + else: + idname = '/' + ele.name + _= msgin.readSerial(nbBit, name='DatabaseXML' + idname, typeName='Number:'+str(nbBit), emulate=False, commentValue=ele.name+comment) + logging.getLogger(LOGGER).debug("name:" + ele.name + ", count:" + str(ele.count) + ", atom:" + str(ele.atom)) + ele.execute(msgin) + return + ii = i + for ele in self.leaf: + logging.getLogger(LOGGER).debug(str(i) + " id:" + str(id) + " name:" + str(ele.name)) + if ele.count: + i += ele.count + else: + i += 1 + if i > id: + comment = "" + if ele.count: + pos = id - ii + comment = str(pos) + if self.name: + idname = '/' + self.name + '/' + ele.name + comment + else: + idname = '/' + ele.name + comment + logging.getLogger(LOGGER).debug(str(i) + " id:" + str(id) + " name:" + str(ele.name)) + _ = msgin.readSerial(nbBit, name='DatabaseXML' + idname, typeName='Number:'+str(nbBit), emulate=False, commentValue=ele.name+comment) + logging.getLogger(LOGGER).debug("name:" + ele.name + ", count:" + str(ele.count)) + ele.execute(msgin, name=idname) + return + ii = i + def execute(self, msgin): + if self.atom: + self.execute_atom(msgin) + else: + self.execute_normal(msgin) + + def execute_root(self, msgin): + if self.atom: + nbchild = self.countLeaves() + #nbBit = getPowerOf2.getPowerOf2_Bis(nbchild) + nbBit = getPowerOf2.getPowerOf2(nbchild) + raise "A faire" + else: + nbchild = self.getIdBits() + #nbBit = getPowerOf2.getPowerOf2_Bis(nbchild) + nbBit = getPowerOf2.getPowerOf2(nbchild) + while msgin.needRead() > nbBit: + logging.getLogger(LOGGER).debug("needRead:" + str(msgin.needRead()) + ", nbBit:" + str(nbBit)) + self.execute(msgin) + + class DecodeDatabase(): def __init__(self): self.databaseXml = None self.databasePlr = None def loadDatabase(self, databaseXml): + self.databasePlr = BranchDatabase() + self.databasePlr.loadRootXml(databaseXml, 'PLR') + + def execute(self, msgin, world): + self.databasePlr.execute(msgin) + + def loadDatabase2(self, databaseXml): logging.getLogger(LOGGER).debug("loadDatabase") + print("-"*80) + base = BranchDatabase() + print("-"*80) + #base.loadXml(databaseXml, 'PLR') + base.loadRootXml(databaseXml, 'PLR') + print("-"*80) + base.show(filterlevel=2) + base.show() + tmp = BitStream.BitStream() + tmp.internalSerial(23, 5) + tmp.internalSerial(0,1) + tmp.internalSerial(13237038,32) + base.execute_root(tmp) + print(tmp.showAllData()) + print("-"*80) + tmp = BitStream.BitStream() + tmp.internalSerial(21, 5) + tmp.internalSerial(8,5) + tmp.internalSerial(2,3) + tmp.internalSerial(0,3) + tmp.internalSerial(0,5) + tmp.internalSerial(3,9) + tmp.internalSerial(69,9) + tmp.internalSerial(10,5) + tmp.internalSerial(10,5) + tmp.internalSerial(0,5) + tmp.internalSerial(0,9) + tmp.internalSerial(200,9) + tmp.internalSerial(21,5) + tmp.internalSerial(10,5) + tmp.internalSerial(8,5) + tmp.internalSerial(0,1) + tmp.internalSerial(821933,32) + tmp.internalSerial(0,5) + tmp.internalSerial(0,9) + tmp.internalSerial(100,9) + tmp.internalSerial(14,5) + tmp.internalSerial(16,5) + tmp.internalSerial(4,5) + tmp.internalSerial(0,2) + tmp.internalSerial(15,8) + tmp.internalSerial(64,8) + tmp.internalSerial(0,8) + tmp.internalSerial(1,2) + base.execute_root(tmp) + print(tmp.showAllData()) + + raise "Stop" self.databaseXml = databaseXml id = 0 - self.databasePlr = {} + self.databasePlr = {'name': 'root', 'bank': 'PLR', 'child': {}, 'min':0, 'max':0 , 'atom': False} for ele in self.databaseXml: if ele.tag == 'branch': if ele.get('bank') == "PLR": - self.databasePlr[id] = child(ele) - self.databasePlr[id]['min'] = id - self.databasePlr[id]['max'] = id + if 'atom' in ele: + if int(ele.get('atom')) > 0: + #self.databasePlr + pass + self.databasePlr['child'][id] = child(ele) + self.databasePlr['child'][id]['min'] = id + self.databasePlr['child'][id]['max'] = id id += 1 print(dir(ele)) + nb = len(self.databasePlr) - 1 + self.databasePlr['min'] = 0 + self.databasePlr['max'] = nb print("-" * 80) show_dico(self.databasePlr) print("-" * 80) + print("max", self.databasePlr['max'] ) + print("-" * 80) #raise "Decode" - def execute(self, msgin, world): + def execute2(self, msgin, world): logging.getLogger(LOGGER).debug("execute") head = self.databasePlr listpath = [] + + print("="*80) + print(head) + print("="*80) while True: + print("---") logging.getLogger(LOGGER).debug("count_elements:" + str(count_elements(head))) - nbBit = getPowerOf2.getPowerOf2(count_elements(head)) + nbchild = count_elements(head) + print("count_elements(head):", nbchild) + if nbchild == 0: + print("Ahhhh", "+"*80) + return True + print("nbchild:", nbchild) + nbBit = getPowerOf2.getPowerOf2_Bis(nbchild) + print("nbBit:", nbBit) +# res=1; +# ret=0; +# print("ret:", ret, "res:", res) +# while res %s" % (nbBit, ':'.join(listpath)) ) - ele = get_element(head, id) + + print("Ahhhh a", "-"*80) + show_dico(head) + ele = get_element(head, int(id)) print(ele) show_dico(ele) + print(msgin.showAllData()) name = ele['name'] + id = msgin.readSerial(nbBit, name='DatabaseXML', typeName='Number:'+str(nbBit), commentValue=name) listpath.append(name) fullname = ':'.join(listpath) + print("fullname:", fullname) logging.getLogger(LOGGER).debug(fullname) + if 'count' in ele: + nbBit = getPowerOf2.getPowerOf2_Bis(int(ele['count'])) + count = msgin.readSerial(nbBit, name='DatabaseXML', typeName='count:'+str(ele['count']+':'+str(nbBit))) + listpath.append(str(count)) if 'type' in ele: - print("+"*80) + print("Ahhhh 2", "+"*80) + print(ele['type']) + if ele['type'] == 'I32': + _ = msgin.readSerial(32, name='DatabaseXML', typeName=ele['type']) + else: + pass + print(msgin.showAllData()) return True head = ele - print("-"*80) + print("Ahhhh 3", "-"*80) return False diff --git a/tools/Enum.py b/tools/Enum.py index cc0cf86..f73436b 100644 --- a/tools/Enum.py +++ b/tools/Enum.py @@ -21,6 +21,18 @@ from enum import IntEnum +def GetNameIntEnum(typeEnum, value): + for key in typeEnum.__dict__: + try: + print("-"*80) + print(key, dir(typeEnum.__dict__[key])) + print(key, typeEnum.__dict__[key].value) + if typeEnum.__dict__[key].value == value: + return key + except: + pass + return None + class TConnectionState(IntEnum): NotInitialised = 0 # nothing happened yet NotConnected = 1 # init() called @@ -610,7 +622,8 @@ class TCDBBank(IntEnum): CDBOutpost = 2, # CDBGlobal, NB_CDB_BANKS = 3, - INVALID_CDB_BANK = 4 + INVALID_CDB_BANK = 4, + NB_BITS_FOR_CDBBANK = 2 # normally calculate with NB_CDB_BANKS // ------ for ( nbits=1; (1<& npcKeys ) ''' @@ -381,7 +395,7 @@ class ImpulsePhraseDownload(ImpulseBase): # tmp.setdefault('MemorizedPhrase_%d' % i, data) # self.param.setdefault("MemorizedPhrase", tmp) - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): """ khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:13586 void CCharacter::sendPhrasesToClient() """ @@ -400,7 +414,7 @@ class ImpulsePosition(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/server/src/gpm_service/client_messages.cpp void cbClientPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') @@ -415,7 +429,7 @@ class ImpulseSringDynString(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') self.readUint32(msgin, 'phraseId') @@ -425,7 +439,7 @@ class ImpulseSringManagerReloadCache(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') self.readUint32(msgin, 'timestamp') @@ -435,7 +449,7 @@ class ImpulseSringManagerPhraseSend(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') id = 'SringManagerPhrase' @@ -452,7 +466,7 @@ class ImpulseSringManagerStringResp(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') self.readUint32(msgin, 'stringId') @@ -463,7 +477,7 @@ class ImpulseSringManagerStringRq(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') self.readUint32(msgin, 'stringId') @@ -473,7 +487,7 @@ class impulseGuildUpdatePlayerTitle(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') self.readBool(msgin, 'bUnblock') @@ -486,7 +500,7 @@ class impulseDeathRespawnPoint(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): id = "CRespawnPointsMsg" logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') @@ -521,7 +535,7 @@ class impulseEncyclopediaInit(ImpulseBase): self.readUint8(msgin, '%s_Album_State' % (id)) self.read_thema(id, msgin) - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): id = "EncyclopediaInit" logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') @@ -543,7 +557,7 @@ class impulseInitInventory(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void updateInventoryFromStream (NLMISC::CBitMemStream &impulse, const CInventoryCategoryTemplate *templ, bool notifyItemSheetChanges) # khanat-opennel-code/code/ryzom/server/src/entities_game_service/inventory_updater.cpp void CInventoryUpdaterForCharacter::sendAllUpdates( const NLMISC::CEntityId& destEntityId ) id = "InitInventory" @@ -596,7 +610,7 @@ class ImpulseConnectionUserChars(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseUserChars(NLMISC::CBitMemStream &impulse) # khanat-opennel-code/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp void sendCharactersSummary( CPlayer *player, bool AllAutorized, uint32 bitfieldOwnerOfActiveAnimSession, uint32 bitfieldOwnerOfEditSession ) id = "ConnectionUserChars" @@ -638,7 +652,7 @@ class impulseDatabaseInitPlayer(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse) # khanat-opennel-code/code/ryzom/server/src/simulation_service/simulated_editor.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse) id = "DatabaseInitPlayer" @@ -654,7 +668,7 @@ class ImpulseConnectionDeleteChar(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse) # khanat-opennel-code/code/ryzom/server/src/simulation_service/simulated_editor.cpp void impulseDatabaseInitPlayer(NLMISC::CBitMemStream &impulse) id = "ConnectionDeleteChar" @@ -667,7 +681,7 @@ class impulseTeamContactInit(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): id = "TeamContactInit" logging.getLogger(LOGGER).debug("read") self.name = name.replace(':', '_') @@ -686,7 +700,7 @@ class impulseNpcIconGetDesc(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/server/src/frontend_service/id_impulsions.cpp void cbImpulsionGetNpcIconDesc( CEntityId& sender, CBitMemStream &bms, TGameCycle gamecycle, uint16 serviceId ) id = "ClientNpcIcon" logging.getLogger(LOGGER).debug("read %s" % id) @@ -700,7 +714,7 @@ class impulseUserBars(ImpulseBase): def __init__(self): super().__init__() - def read(self, name, msgin, world): + def read(self, name, msgin, world, databaseXml): # khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp void CCharacter::barUpdate() id = "UserBars" logging.getLogger(LOGGER).debug("read %s" % id) @@ -712,6 +726,42 @@ class impulseUserBars(ImpulseBase): _ = self.readSint32(msgin, '%s_oldchascore4barsenttoplayer' % id) +class impulseDbGroupInitBank(ImpulseBase): + def __init__(self): + super().__init__() + + def read(self, name, msgin, world, databaseXml): + # khanat/khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseInitBank(NLMISC::CBitMemStream &impulse) + id = "DbGroupInitBank" + logging.getLogger(LOGGER).debug("read %s" % id) + self.name = name.replace(':', '_') + _ = self.readUint32(msgin, '%s_serverTick' % id) + bank = self.readSerialEnum(msgin, Enum.TCDBBank.NB_BITS_FOR_CDBBANK, '%s_bank' % id, Enum.TCDBBank) + propertyCount = self.readUint16(msgin, '%s_propertyCount' % id) + for i in range(0, propertyCount): + raise "TODO" + + +class impulseDatabaseUpdatePlayer(ImpulseBase): + def __init__(self): + super().__init__() + + def read(self, name, msgin, world, databaseXml): + # khanat/khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseDatabaseUpdatePlayer(NLMISC::CBitMemStream &impulse) + id = "DbUpdPlr" + logging.getLogger(LOGGER).debug("read %s" % id) + self.name = name.replace(':', '_') + _ = self.readUint32(msgin, '%s_serverTick' % id) + propertyCount = self.readUint16(msgin, '%s_propertyCount' % id) + for i in range(0, propertyCount): + databaseXml.execute(msgin, world) + #raise "TODO" + if msgin.needRead() > 5: + print(msgin.showAllData()) + #raise "TODO" + #raise "TODO" + + class DecodeImpulseSimple: def __init__(self): ''' @@ -752,6 +802,8 @@ class DecodeImpulseSimple: self.GenericMsgHeaderMngr.setdefault( "TEAM:CONTACT_INIT", impulseTeamContactInit) self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:GET_DESC", impulseNpcIconGetDesc) self.GenericMsgHeaderMngr.setdefault( "USER:BARS", impulseUserBars) + self.GenericMsgHeaderMngr.setdefault( "DB_GROUP:INIT_BANK", impulseDbGroupInitBank) + self.GenericMsgHeaderMngr.setdefault( "DB_UPD_PLR", impulseDatabaseUpdatePlayer) def execute(self, msgin, world, references = [], name=""): ''' @@ -792,7 +844,7 @@ class DecodeImpulseSimple: if fullname in self.GenericMsgHeaderMngr: logging.getLogger(LOGGER).debug("Found : %s" % fullname) impulse = self.GenericMsgHeaderMngr[fullname]() - impulse.read(fullname, msgin, world) + impulse.read(fullname, msgin, world, self.databaseXml) logging.getLogger(LOGGER).debug("MessageXML decoded: %s" % msgin.showAllData() ) impulse.add_value("command", fullname) for reference in references: diff --git a/tools/getPowerOf2.py b/tools/getPowerOf2.py index 700596a..14c2b07 100644 --- a/tools/getPowerOf2.py +++ b/tools/getPowerOf2.py @@ -34,3 +34,14 @@ def getPowerOf2_Bis(v): ret += 1 res *= 2 return ret + + +def getPowerOf2_ter(v): + res=1; + ret=0; + while res