This commit is contained in:
AleaJactaEst 2020-07-20 21:56:58 +02:00
parent 065b290753
commit 1df1ee152e
8 changed files with 363 additions and 52 deletions

View file

@ -39,12 +39,14 @@ from tools import Enum
from tools import CActionFactory from tools import CActionFactory
from tools import CBitSet from tools import CBitSet
from tools import DecodeImpulse from tools import DecodeImpulse
from tools import DecodeDatabase
from tools import World from tools import World
from tools import CGenericMultiPartTemp from tools import CGenericMultiPartTemp
from tools import CImpulseDecoder from tools import CImpulseDecoder
#from tools import CStringManager #from tools import CStringManager
from tools import CAction from tools import CAction
from tools import Impulse from tools import Impulse
from tools import CPropertyDecoder
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime from datetime import datetime
@ -69,7 +71,7 @@ def write_yaml_str_or_array(outyaml, nbspace, value):
outyaml.write(" " * nbspace + str(type(value)) + "\n") outyaml.write(" " * nbspace + str(type(value)) + "\n")
class SpyPcap(): class SpyPcap():
def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None): def __init__(self, khanat_host_service, pcap_file, msg_xml, database_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None):
if khanat_host_service: if khanat_host_service:
self.khanat_host_service = re.compile(khanat_host_service) self.khanat_host_service = re.compile(khanat_host_service)
else: else:
@ -84,14 +86,25 @@ class SpyPcap():
self.show_message_decoded = show_message_decoded self.show_message_decoded = show_message_decoded
self.actionFactory = CActionFactory.CActionFactory(None) self.actionFactory = CActionFactory.CActionFactory(None)
self.client_state = {} self.client_state = {}
# msg.xml
self.decodeImpulse = DecodeImpulse.DecodeImpulse() self.decodeImpulse = DecodeImpulse.DecodeImpulse()
self.decodeImpulseSimple = Impulse.DecodeImpulseSimple() self.decodeImpulseSimple = Impulse.DecodeImpulseSimple()
fp = open(msg_xml , 'rt') fp = open(msg_xml , 'rt')
msgRawXml = fp.read() msgRawXml = fp.read()
fp.close()
self.msgXml = ET.fromstring(msgRawXml) self.msgXml = ET.fromstring(msgRawXml)
self.decodeImpulse.loadMsg(self.msgXml) self.decodeImpulse.loadMsg(self.msgXml)
self.decodeImpulseSimple.loadMsg(self.msgXml) self.decodeImpulseSimple.loadMsg(self.msgXml)
# database.xml
#self.decodeDatabase = DecodeDatabase.DecodeDatabase()
fp = open(database_xml, 'rt')
databaseRawXml = fp.read()
fp.close()
self.databaseXml = ET.fromstring(databaseRawXml)
self.decodeImpulseSimple.loadDatabase(self.databaseXml)
self.decodeDatabase = DecodeDatabase.DecodeDatabase()
self.decodeDatabase.loadDatabase(self.databaseXml)
# outyaml
self.outyaml = outyaml self.outyaml = outyaml
def readRaw(self): def readRaw(self):
@ -124,7 +137,6 @@ class SpyPcap():
ip_packet.src.decode(), udp_packet.src_port, ip_packet.src.decode(), udp_packet.src_port,
ip_packet.dst.decode(), udp_packet.dst_port, ip_packet.dst.decode(), udp_packet.dst_port,
data.decode())) data.decode()))
elif ip_packet.p == 6: elif ip_packet.p == 6:
# TCP # TCP
logging.getLogger(LOGGER).debug("ip packet: protocol TCP (%s)" % ip_packet.p) logging.getLogger(LOGGER).debug("ip packet: protocol TCP (%s)" % ip_packet.p)
@ -183,8 +195,63 @@ class SpyPcap():
def add_registered_action(self, clientid, action): def add_registered_action(self, clientid, action):
self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, []) self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, [])
self.client_state[clientid]['RegisteredAction'][action.Code].append(action) self.client_state[clientid]['RegisteredAction'][action.Code].append(action)
self.client_state[clientid]['PropertyDecoder'] = CPropertyDecoder()
def decodeVisualProperties(self, clientid, msgin):
"""
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:1512 void CNetworkConnection::decodeVisualProperties( CBitMemStream& msgin )
"""
actions = []
try:
while True:
# if ( msgin.getPosInBit() + (sizeof(TCLEntityId)*8) > msgin.length()*8 ) return
if msgin.sizeRead() + (8*8 ) > msgin.sizeData() * 8:
return
slot = msgin.readUint8("Slot")
associationBits = msgin.readSerial(2, "associationBits")
if self.client_state[clientid]['PropertyDecoder'] .associationBitsHaveChanged( slot, associationBits ) and (slot==0):
if self.client_state[clientid]['PropertyDecoder'] .isUsed( slot ):
sheet = self.client_state[clientid]['PropertyDecoder'] .getSheet(slot)
timestampIsThere = msgin.readBool("timestampIsThere")
if timestampIsThere:
timestampDelta = msgin.readSerial(4, "timestampDelta")
timestamp = self.client_state[clientid]['CurrentReceivedNumber'] - timestampDelta
else:
timestamp = self.client_state[clientid]['CurrentReceivedNumber']
# Tree
# currentNode->a()
BranchHasPayload = msgin.readBool("BranchHasPayload")
if BranchHasPayload:
# _PropertyDecoder.receive( _CurrentReceivedNumber, ap );
# Create a new action
cActionPosition = CAction.CActionPosition(slot, Enum.TActionCode.ACTION_POSITION_CODE, self.client_state[clientid]['world'])
self.client_state[clientid]['PropertyDecoder'] .receive(cActionPosition)
cActionPosition.unpack(msgin)
actions.append(cActionPosition)
# currentNode->b()
BranchHasPayload = msgin.readBool("BranchHasPayload")
if BranchHasPayload:
# currentNode->b()->a()
BranchHasPayload = msgin.readBool("BranchHasPayload")
# Create a new action -> PROPERTY_ORIENTATION
cActionOrientation= CAction.CActionSint64(slot, self.client_state[clientid]['world'])
cActionOrientation.PropertyCode = Enum.TPropIndex.PROPERTY_ORIENTATION
cActionOrientation.unpack(msgin)
#self.client_state[clientid]['PropertyDecoder'] .receive(cActionPosition)
actions.append(cActionOrientation)
# Discreet properties
except:
# Detect end of stream (little hard to close)
pass
def decode_server(self, clientid, msgin, receivedPacket, receivedAck, nextSentPacket=0): def decode_server(self, clientid, msgin, receivedPacket, receivedAck, nextSentPacket=0):
"""
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:1312 void CNetworkConnection::receiveNormalMessage(CBitMemStream &msgin)
khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp:38 void CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector<CLFECOMMON::CAction *> &actions)
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:1512 void CNetworkConnection::decodeVisualProperties( CBitMemStream& msgin )
"""
actions = [] actions = []
for level in range(0, 3): for level in range(0, 3):
if level == 0: if level == 0:
@ -224,6 +291,8 @@ class SpyPcap():
elif action: elif action:
logging.getLogger(LOGGER).debug("append Code:%s" % str(action.Code)) logging.getLogger(LOGGER).debug("append Code:%s" % str(action.Code))
self.add_registered_action(clientid, action) self.add_registered_action(clientid, action)
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:1512 void CNetworkConnection::decodeVisualProperties( CBitMemStream& msgin )
self.decodeVisualProperties(clientid, msgin)
return actions return actions
def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name, Reference): def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name, Reference):
@ -288,6 +357,7 @@ class SpyPcap():
self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber
actions = [] actions = []
impulses = [] impulses = []
databases = []
if not SystemMode: if not SystemMode:
''' '''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage() khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage()
@ -353,12 +423,13 @@ class SpyPcap():
else: else:
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst)) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst))
logging.getLogger(LOGGER).debug("[Client -> Server] msg:%s" % msgin.showAllData()) logging.getLogger(LOGGER).debug("[Client -> Server] msg:%s" % msgin.showAllData())
return actions, impulses return actions, impulses, databases
def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname, Parent, Source): def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname, Parent, Source):
target = "%s_%s" % (Source, Parent[7:]) target = "%s_%s" % (Source, Parent[7:])
actions = [] actions = []
impulses = [] impulses = []
databases = []
CurrentSendNumber = msgin.readSint32('CurrentSendNumber') CurrentSendNumber = msgin.readSint32('CurrentSendNumber')
logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst))
SystemMode = msgin.readBool('SystemMode') SystemMode = msgin.readBool('SystemMode')
@ -377,12 +448,14 @@ class SpyPcap():
# Decode the actions received in the impulsions # Decode the actions received in the impulsions
logging.getLogger(LOGGER).debug('=' * 80) logging.getLogger(LOGGER).debug('=' * 80)
actionsbis = [] actionsbis = []
logging.getLogger(LOGGER).info("size[actions] %d" % len(actions))
for action in actions: for action in actions:
referenceBis = "%s_%d" % (target, id) referenceBis = "%s_%d" % (target, id)
action.add_reference(Parent) action.add_reference(Parent)
action.set_name(referenceBis) action.set_name(referenceBis)
logging.getLogger(LOGGER).debug('-' * 80) logging.getLogger(LOGGER).debug('-' * 80)
logging.getLogger(LOGGER).debug('Analyse actions:%s', action) logging.getLogger(LOGGER).debug('Analyse actions:%s', action)
logging.getLogger(LOGGER).info("size[actions] %d" % len(actions))
if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE: if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE:
#action.add_reference(Parent) #action.add_reference(Parent)
logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE") logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE")
@ -400,6 +473,11 @@ class SpyPcap():
) #, Reference = Parent, Name = "%s_%d" % (target, 0)) ) #, Reference = Parent, Name = "%s_%d" % (target, 0))
logging.getLogger(LOGGER).info("impulse:%s" % str(impulse)) logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
if impulse: if impulse:
print("spykhanat.py:412", type(impulse))
database = None
#database = impulse.readDatabases(self.client_state[dst]['world'], self.decodeDatabase)
if database:
databases.append(database)
impulses.append(impulse) impulses.append(impulse)
except Impulse.ImpulseNoElement: except Impulse.ImpulseNoElement:
pass pass
@ -407,6 +485,7 @@ class SpyPcap():
elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE: elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE:
#action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTempServer'], Reference = referenceBis) #, Reference = Parent, Name = "%s_%d" % (target, 0)) #action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTempServer'], Reference = referenceBis) #, Reference = Parent, Name = "%s_%d" % (target, 0))
try: try:
logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s OKKKKKKKK " % action)
impulse = action.decodeImpulseSimple( impulse = action.decodeImpulseSimple(
self.decodeImpulseSimple, self.decodeImpulseSimple,
self.client_state[dst]['world'], self.client_state[dst]['world'],
@ -416,6 +495,7 @@ class SpyPcap():
) #, Reference = Parent, Name = "%s_%d" % (target, 0)) ) #, Reference = Parent, Name = "%s_%d" % (target, 0))
logging.getLogger(LOGGER).info("impulse:%s" % str(impulse)) logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
if impulse: if impulse:
print("spykhanat.py:429", type(impulse))
impulses.append(impulse) impulses.append(impulse)
except Impulse.ImpulseNoElement: except Impulse.ImpulseNoElement:
pass pass
@ -433,14 +513,64 @@ class SpyPcap():
logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % ( logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (
CurrentSendNumber, src, dst, _LastReceivedAck, id, CurrentSendNumber, src, dst, _LastReceivedAck, id,
self.client_state[dst]['GenericMultiPartTempServer'].data[id].read().showAllData())) self.client_state[dst]['GenericMultiPartTempServer'].data[id].read().showAllData()))
temp = CAction.CActionFake('ACTION_GENERIC_MULTI_PART_CODE', ## temp = CAction.CActionFake('ACTION_GENERIC_MULTI_PART_CODE',
self.client_state[dst]['GenericMultiPartTempServer'].data[id].read(), ## self.client_state[dst]['GenericMultiPartTempServer'].data[id].read(),
## # {'coucou': ', '.join(self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference)},
## # Reference = self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference,
## Name = "impulse_%s_%s" % (Parent[7:], 0)
## )
## temp.Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference
## #actionsbis.append(temp)
msg = self.client_state[dst]['GenericMultiPartTempServer'].data[id].MsgDecoded
msg.reset_read()
# #print("------->", msg.needRead(), "/", msg.sizeData())
# #print("------>", type(self.client_state[dst]['GenericMultiPartTempServer'].data[id]))
action = CAction.CActionFake('ACTION_GENERIC_MULTI_PART_CODE',
msg,
# {'coucou': ', '.join(self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference)}, # {'coucou': ', '.join(self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference)},
# Reference = self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference, Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference,
Name = "inpulse_%s_%s" % (Parent[7:], 0) Name = "impulse_%s_%s" % (Parent[7:], 0)
) )
temp.Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference try:
actionsbis.append(temp) impulse = action.decodeImpulseSimple(
self.decodeImpulseSimple,
self.client_state[dst]['world'],
self.client_state[dst]['GenericMultiPartTempServer'],
Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference,
Name = "%s_%d" % (target, 0)
) #, Reference = Parent, Name = "%s_%d" % (target, 0))
if impulse:
print("spykhanat.py:429", type(impulse))
impulses.append(impulse)
except Impulse.ImpulseNoElement:
pass
actionsbis.append(action)
# try:
# impulse = {"Type": "CActionFake.ACTION_GENERIC_MULTI_PART_CODE"}
# impulse["state"] = "message partially decoded"
# tmp = self.decodeImpulseSimple.execute(msg, self.client_state[dst]['world'])
# print("-"*80)
# print(tmp)
# print("-"*80)
# impulse['Message'] = msg.extractAllData()
# impulse['Reference'] = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference
# impulse['Name'] = "Impulse_%s_%d" % (target, 0)
## impulse = action.decodeImpulseSimple(
## self.decodeImpulseSimple,
## self.client_state[dst]['world'],
## self.client_state[dst]['GenericMultiPartTempServer'],
## Reference = Parent,
## Name = "%s_%d" % (target, 0)
## ) #, Reference = Parent, Name = "%s_%d" % (target, 0))
# print("-"*80)
# logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
# if impulse:
# print("spykhanat.py:473", type(impulse))
# impulses.append(impulse)
# except Impulse.ImpulseNoElement:
# pass
# print(impulses)
#raise "quoi"
else: else:
logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d}" % ( logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d}" % (
CurrentSendNumber, src, dst, _LastReceivedAck, id)) CurrentSendNumber, src, dst, _LastReceivedAck, id))
@ -454,6 +584,7 @@ class SpyPcap():
# while self._Actions and self._Actions[0].FirstPacket != 0 and self._Actions[0].FirstPacket < self._LastReceivedAck: # while self._Actions and self._Actions[0].FirstPacket != 0 and self._Actions[0].FirstPacket < self._LastReceivedAck:
# logging.getLogger(LOGGER).debug("remove old action [%d/%d] : %s" % (self._Actions[0].FirstPacket, self._LastReceivedAck, self._Actions[0])) # logging.getLogger(LOGGER).debug("remove old action [%d/%d] : %s" % (self._Actions[0].FirstPacket, self._LastReceivedAck, self._Actions[0]))
# self._Actions.pop(0) # self._Actions.pop(0)
logging.getLogger(LOGGER).info("size[actions] %d" % len(actions))
for action in actionsbis: for action in actionsbis:
actions.append(action) actions.append(action)
@ -493,7 +624,7 @@ class SpyPcap():
#cActionFactory.unpack(msgin) #cActionFactory.unpack(msgin)
logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData()) logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData())
#logging.getLogger(LOGGER).info("impulses:%s" % str(impulses)) #logging.getLogger(LOGGER).info("impulses:%s" % str(impulses))
return actions, impulses return actions, impulses, databases
def read(self): def read(self):
file = open( self.pcap_file , 'rb') file = open( self.pcap_file , 'rb')
@ -526,8 +657,8 @@ class SpyPcap():
logging.getLogger(LOGGER).debug("-" * 80) logging.getLogger(LOGGER).debug("-" * 80)
actions_clients = [] actions_clients = []
actions_servers = [] actions_servers = []
inpulses_servers = [] impulses_servers = []
inpulses_clients = [] impulses_clients = []
if self.show_raw_packet: if self.show_raw_packet:
logging.getLogger(LOGGER).debug("[raw packet] timestamp:%s [%s] src:%s:%d dst:%s:%d data:%s" % (pkt.timestamp, logging.getLogger(LOGGER).debug("[raw packet] timestamp:%s [%s] src:%s:%d dst:%s:%d data:%s" % (pkt.timestamp,
datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"),
@ -564,11 +695,11 @@ class SpyPcap():
if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src): if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src):
_provenance = 'Server -> Client' _provenance = 'Server -> Client'
logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData()))
actions_servers, inpulses_servers = self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst], Reference, list_host[src]) actions_servers, impulses_servers, databases_servers = self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst], Reference, list_host[src])
else: else:
_provenance = 'Client -> Server' _provenance = 'Client -> Server'
logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData()))
actions_clients, inpulses_clients = self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst], Reference, list_host[src]) actions_clients, impulses_clients, databases_clients = self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst], Reference, list_host[src])
if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7:
moredata = "message partially decoded" moredata = "message partially decoded"
else: else:
@ -623,16 +754,38 @@ class SpyPcap():
#self.outyaml.write(" %s: %s\n" % (key, params[key])) #self.outyaml.write(" %s: %s\n" % (key, params[key]))
id += 1 id += 1
if inpulses_servers: # if databases_servers:
self.outyaml.write("\ninpulseserver_%s_%d:\n" %(list_host[src], sequenceid)) # self.outyaml.write("\ndatabaseserver_%s_%d:\n" %(list_host[src], sequenceid))
# id = 0
# for databases in databases_servers:
# params = impulse_data.get_parameter()
# self.outyaml.write(" %s:\n" % (impulse_data.get_name()))
# for key in params:
# if key == 'Message':
# self.outyaml.write(" %s:\n" % (key))
# for key2 in params[key]:
# self.outyaml.write(" - %s\n" % key2)
# elif key == "Reference":
# self.outyaml.write(" parents:\n")
# for key in params['Reference']:
# self.outyaml.write(" - %s\n" % (key))
# #elif key != 'parent':
# else:
# self.outyaml.write(" %s: %s\n" % (key, params[key]))
# #self.outyaml.write(" %s: %s\n" % (key, params[key]))
# id += 1
# #print("-"*30)
if impulses_servers:
self.outyaml.write("\nimpulseserver_%s_%d:\n" %(list_host[src], sequenceid))
id = 0 id = 0
#print("-"*30) #print("-"*30)
#print(inpulses_servers) #print(impulses_servers)
for inpulse in inpulses_servers: for impulse_data in impulses_servers:
#print("-"*80) #print("-"*80)
#print(inpulse) #print(Impulse)
params = inpulse.get_parameter() params = impulse_data.get_parameter()
self.outyaml.write(" %s:\n" % (inpulse.get_name())) self.outyaml.write(" %s:\n" % (impulse_data.get_name()))
for key in params: for key in params:
if key == 'Message': if key == 'Message':
self.outyaml.write(" %s:\n" % (key)) self.outyaml.write(" %s:\n" % (key))
@ -649,6 +802,7 @@ class SpyPcap():
id += 1 id += 1
#print("-"*30) #print("-"*30)
if actions_clients: if actions_clients:
self.outyaml.write("\nblock_%s_%d:\n" %(list_host[src], sequenceid)) self.outyaml.write("\nblock_%s_%d:\n" %(list_host[src], sequenceid))
id = 0 id = 0
@ -673,12 +827,12 @@ class SpyPcap():
#self.outyaml.write(" %s: %s\n" % (key, params[key])) #self.outyaml.write(" %s: %s\n" % (key, params[key]))
id += 1 id += 1
# if inpulses_clients: # if impulses_clients:
# self.outyaml.write("\ninpulseclient_%s_%d:\n" %(list_host[src], sequenceid)) # self.outyaml.write("\nImpulseclient_%s_%d:\n" %(list_host[src], sequenceid))
# id = 0 # id = 0
# for inpulse in inpulses_clients: # for Impulse in impulses_clients:
# params = inpulse.get_parameter() # params = Impulse.get_parameter()
# self.outyaml.write(" %s:\n" % (inpulse.get_name())) # self.outyaml.write(" %s:\n" % (Impulse.get_name()))
# id += 1 # id += 1
sequenceid += 1 sequenceid += 1
sequencenum += 1 sequencenum += 1
@ -699,6 +853,7 @@ def main():
# logger.append(logging.getLogger(CAction.LOGGER)) # logger.append(logging.getLogger(CAction.LOGGER))
# logger.append(logging.getLogger(CActionFactory.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(Impulse.LOGGER))
CImpulseDecoder CImpulseDecoder
# logger.append(logging.getLogger('CGenericMultiPartTemp')) # logger.append(logging.getLogger('CGenericMultiPartTemp'))
@ -710,6 +865,7 @@ def main():
parser.add_argument("-v", "--verbose", help="show verbose message", action='store_true') parser.add_argument("-v", "--verbose", help="show verbose message", action='store_true')
parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True) parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True)
parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True) parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True)
parser.add_argument("-w", "--database-xml", help="file database.xml (from server khanat)", required=True)
parser.add_argument("-r", "--raw", help="show message raw", action='store_true') parser.add_argument("-r", "--raw", help="show message raw", action='store_true')
parser.add_argument("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None) parser.add_argument("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None)
parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true') parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true')
@ -732,6 +888,7 @@ def main():
spy = SpyPcap(khanat_host_service=args.khanat_host_service, spy = SpyPcap(khanat_host_service=args.khanat_host_service,
pcap_file=args.pcap_file, pcap_file=args.pcap_file,
msg_xml=args.msg_xml, msg_xml=args.msg_xml,
database_xml=args.database_xml,
filter_host_service=args.filter_host_service, filter_host_service=args.filter_host_service,
show_raw_packet=args.show_raw_packet, show_raw_packet=args.show_raw_packet,
show_message_decoded=args.show_message_decoded, show_message_decoded=args.show_message_decoded,

View file

@ -42,6 +42,10 @@ class BitStream():
def __len__(self): def __len__(self):
return (self._pos + 7) // 8 return (self._pos + 7) // 8
def reset_read(self):
self._read = 0
self._groupRead = []
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
ret = BitStream() ret = BitStream()
ret._pos = self._pos ret._pos = self._pos
@ -583,27 +587,53 @@ class BitStream():
return c_int8(v).value return c_int8(v).value
def readUint64(self, name): def readUint64(self, name):
# khanat-opennel-code/code/nel/include/nel/misc/stream.h #define NLMISC_BSWAP64(src) (src) = (((src)>>56)&0xFF) | ((((src)>>48)&0xFF)<<8) | ((((src)>>40)&0xFF)<<16) | ((((src)>>32)&0xFF)<<24) | ((((src)>>24)&0xFF)<<32) | ((((src)>>16)&0xFF)<<40) | ((((src)>>8)&0xFF)<<48) | (((src)&0xFF)<<56)
p1 = self._read p1 = self._read
if sys.byteorder == "little": if sys.byteorder == "little":
v1 = self.readSerial(32, decode=False) v4 = self.readSerial(8, decode=False)
v2 = self.readSerial(32, decode=False) v3 = self.readSerial(8, decode=False)
v2 = self.readSerial(8, decode=False)
v1 = self.readSerial(8, decode=False)
v8 = self.readSerial(8, decode=False)
v7 = self.readSerial(8, decode=False)
v6 = self.readSerial(8, decode=False)
v5 = self.readSerial(8, decode=False)
else: else:
v2 = self.readSerial(32, decode=False) v1 = self.readSerial(8, decode=False)
v1 = self.readSerial(32, decode=False) v2 = self.readSerial(8, decode=False)
v3 = (v1 << 32) | v2 v3 = self.readSerial(8, decode=False)
self._groupRead.append((p1, p1+64, name, 'Uint64', v3)) v4 = self.readSerial(8, decode=False)
v5 = self.readSerial(8, decode=False)
v6 = self.readSerial(8, decode=False)
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))
return v3 return v3
def readSint64(self, name): def readSint64(self, name):
# khanat-opennel-code/code/nel/include/nel/misc/stream.h #define NLMISC_BSWAP64(src) (src) = (((src)>>56)&0xFF) | ((((src)>>48)&0xFF)<<8) | ((((src)>>40)&0xFF)<<16) | ((((src)>>32)&0xFF)<<24) | ((((src)>>24)&0xFF)<<32) | ((((src)>>16)&0xFF)<<40) | ((((src)>>8)&0xFF)<<48) | (((src)&0xFF)<<56)
p1 = self._read p1 = self._read
if sys.byteorder == "little": if sys.byteorder == "little":
v1 = self.readSerial(32, decode=False) v4 = self.readSerial(8, decode=False)
v2 = self.readSerial(32, decode=False) v3 = self.readSerial(8, decode=False)
v2 = self.readSerial(8, decode=False)
v1 = self.readSerial(8, decode=False)
v8 = self.readSerial(8, decode=False)
v7 = self.readSerial(8, decode=False)
v6 = self.readSerial(8, decode=False)
v5 = self.readSerial(8, decode=False)
else: else:
v2 = self.readSerial(32, decode=False) v1 = self.readSerial(8, decode=False)
v1 = self.readSerial(32, decode=False) v2 = self.readSerial(8, decode=False)
v3 = (v1 << 32) | v2 v3 = self.readSerial(8, decode=False)
self._groupRead.append((p1, p1+64, name, 'Sint64', c_int64(v3).value)) v4 = self.readSerial(8, decode=False)
v5 = self.readSerial(8, decode=False)
v6 = self.readSerial(8, decode=False)
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))
return c_int64(v3).value return c_int64(v3).value
def readFloat(self, name): def readFloat(self, name):

View file

@ -115,6 +115,10 @@ class CAction:
return "[%d,%d]" % (self.Code , self.Slot) return "[%d,%d]" % (self.Code , self.Slot)
class CActionPosition(CAction): class CActionPosition(CAction):
"""
Method use to decode position
khanat/khanat-opennel-code/code/ryzom/client/src/property_decoder.cpp:39 - void CPropertyDecoder::receive(TPacketNumber /* packetNumber */, CAction *action)
"""
def __init__(self, slot, code, world): def __init__(self, slot, code, world):
super().__init__(slot, code, world) super().__init__(slot, code, world)
self.Position = [0, 0, 0] self.Position = [0, 0, 0]
@ -503,3 +507,8 @@ class CActionFake():
ret["Reference"] = self.Reference ret["Reference"] = self.Reference
ret["Message"] = self._Message.extractAllData() ret["Message"] = self._Message.extractAllData()
return ret return ret
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
ret = decodeImpulseSimple.execute(self._Message, world, Reference, Name)
self.decoded = True
return ret

View file

@ -24,13 +24,14 @@ from tools import BitStream
LOGGER='CGenericMultiPartTemp' LOGGER='CGenericMultiPartTemp'
class CGenericMultiPartTemp(): class CGenericMultiPartTemp():
def __init__(self): def __init__(self, autoDecompile=True):
self.NbBlock = 0xFFFFFFFF self.NbBlock = 0xFFFFFFFF
self.MsgDecoded = None self.MsgDecoded = None
self.FirstRead = False self.FirstRead = False
self.Reference = [] self.Reference = []
self.block = {} self.block = {}
self.Name = None self.Name = None
self.AutoDecompile = autoDecompile
def getNbCurrentBlock(self): def getNbCurrentBlock(self):
return len(self.block) return len(self.block)
@ -60,6 +61,7 @@ class CGenericMultiPartTemp():
for data in self.block: for data in self.block:
logging.getLogger(LOGGER).error("CGenericMultiPartTemp : Number:%d id:%d len:%d/%d" % (Number, data, len(self.block), self.NbBlock)) logging.getLogger(LOGGER).error("CGenericMultiPartTemp : Number:%d id:%d len:%d/%d" % (Number, data, len(self.block), self.NbBlock))
bms.pushBitStream(self.block[data]) bms.pushBitStream(self.block[data])
if self.AutoDecompile:
try: try:
ret = decodeImpulse.execute(bms, world) ret = decodeImpulse.execute(bms, world)
except: except:

View file

@ -24,6 +24,7 @@ from tools import getPowerOf2
from tools import CShardName from tools import CShardName
from tools import CCharacterSummary from tools import CCharacterSummary
from tools import CMainlandSummary from tools import CMainlandSummary
from tools import DecodeDatabase
LOGGER='DecodeImpulse' LOGGER='DecodeImpulse'
@ -34,9 +35,10 @@ class DecodeImpulse():
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork() khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork()
''' '''
self.msgXml = None self.msgXml = None
self.databaseXml = None # self.databaseXml = None
self.GenericMsgHeaderMngr = {} self.GenericMsgHeaderMngr = {}
self.initializeNetwork() self.initializeNetwork()
self.decodeDatabase = DecodeDatabase.DecodeDatabase()
def updatePatcherPriorityBasedOnCharacters(self, world): def updatePatcherPriorityBasedOnCharacters(self, world):
logging.getLogger(LOGGER).debug('Load character') logging.getLogger(LOGGER).debug('Load character')
@ -581,4 +583,4 @@ class DecodeImpulse():
self.msgXml = msgXml self.msgXml = msgXml
def loadDatabase(self, databaseXml): def loadDatabase(self, databaseXml):
self.databaseXml = databaseXml self.decodeDatabase.loadDatabase(self.databaseXml)

View file

@ -612,3 +612,37 @@ class TCDBBank(IntEnum):
# CDBGlobal, # CDBGlobal,
NB_CDB_BANKS = 3, NB_CDB_BANKS = 3,
INVALID_CDB_BANK = 4 INVALID_CDB_BANK = 4
class TPropIndex(IntEnum):
PROPERTY_POSITION = 0,
PROPERTY_POSX = 0,
PROPERTY_POSY = 1,
PROPERTY_POSZ = 2,
PROPERTY_ORIENTATION = 3,
PROPERTY_SHEET = 4
PROPERTY_BEHAVIOUR = 5,
PROPERTY_NAME_STRING_ID = 6,
PROPERTY_TARGET_ID = 7,
PROPERTY_MODE = 8,
PROPERTY_VPA = 9,
PROPERTY_VPB = 10,
PROPERTY_VPC = 11,
PROPERTY_ENTITY_MOUNTED_ID = 12,
PROPERTY_RIDER_ENTITY_ID = 13,
PROPERTY_CONTEXTUAL = 14,
PROPERTY_BARS = 15
PROPERTY_TARGET_LIST = 16,
PROPERTY_TARGET_LIST_0 = 16,
PROPERTY_TARGET_LIST_1 = 17,
PROPERTY_TARGET_LIST_2 = 18,
PROPERTY_TARGET_LIST_3 = 19,
PROPERTY_GUILD_SYMBOL = 20,
PROPERTY_GUILD_NAME_ID = 21,
PROPERTY_VISUAL_FX = 22,
PROPERTY_EVENT_FACTION_ID = 23,
PROPERTY_PVP_MODE = 24,
PROPERTY_PVP_CLAN = 25,
PROPERTY_OWNER_PEOPLE = 26,
PROPERTY_OUTPOST_INFOS = 27,
NB_VISUAL_PROPERTIES = 28

View file

@ -164,6 +164,8 @@ class ImpulseBase:
value = msgin.readUint32(id + '_extended') value = msgin.readUint32(id + '_extended')
self.param.setdefault(id, value) self.param.setdefault(id, value)
return value return value
def readDatabases(self, world, decodeDatabase):
return None
class ImpulseBotchatSetFilters(ImpulseBase): class ImpulseBotchatSetFilters(ImpulseBase):
def __init__(self): def __init__(self):
@ -315,9 +317,10 @@ class ImpulseGuildFemaleTitles(ImpulseBase):
self.readSerial(msgin, 1, 'UseFemaleTitles') self.readSerial(msgin, 1, 'UseFemaleTitles')
class ImpulseNpsIconSetDesc(ImpulseBase): class ImpulseNpcIconSetDesc(ImpulseBase):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.data = BitStream.BitStream()
def read(self, name, msgin, world): def read(self, name, msgin, world):
''' '''
@ -326,9 +329,15 @@ class ImpulseNpsIconSetDesc(ImpulseBase):
logging.getLogger(LOGGER).debug("read") logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_') self.name = name.replace(':', '_')
nb8 = self.readUint8(msgin, 'nb8') nb8 = self.readUint8(msgin, 'nb8')
self.data.pushUint8(nb8)
for i in range(0, nb8): for i in range(0, nb8):
self.readUint32(msgin, 'NpcIconSetDesc_%d_npcAlias' % nb8) npcAlias = self.readUint32(msgin, 'NpcIconSetDesc_%d_npcAlias' % nb8)
self.readUint32(msgin, 'NpcIconSetDesc_%d_state' % nb8) self.data.pushUint32(npcAlias)
state = self.readUint32(msgin, 'NpcIconSetDesc_%d_state' % nb8)
self.data.pushUint32(state)
def readDatabases(self, world, decodeDatabase):
return decodeDatabase.execute(self.data, world)
class ImpulsePhraseDownload(ImpulseBase): class ImpulsePhraseDownload(ImpulseBase):
@ -392,8 +401,10 @@ class ImpulsePosition(ImpulseBase):
super().__init__() super().__init__()
def read(self, name, msgin, world): def read(self, name, msgin, world):
# 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") logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_') self.name = name.replace(':', '_')
self.readBool(msgin, '')
self.readSint32(msgin, 'X') self.readSint32(msgin, 'X')
self.readSint32(msgin, 'Y') self.readSint32(msgin, 'Y')
self.readSint32(msgin, 'Z') self.readSint32(msgin, 'Z')
@ -636,7 +647,7 @@ class impulseDatabaseInitPlayer(ImpulseBase):
self.readUint32(msgin, '%s_serverTick' % id) self.readUint32(msgin, '%s_serverTick' % id)
propertyCount = self.readUint16(msgin, '%s_propertyCount' % id) propertyCount = self.readUint16(msgin, '%s_propertyCount' % id)
for i in range(0, propertyCount): for i in range(0, propertyCount):
propertyCount = self.readUint32(msgin, '%s_propertyCount' % id) _ = self.readUint32(msgin, '%s_property' % id)
class ImpulseConnectionDeleteChar(ImpulseBase): class ImpulseConnectionDeleteChar(ImpulseBase):
@ -651,6 +662,56 @@ class ImpulseConnectionDeleteChar(ImpulseBase):
self.name = name.replace(':', '_') self.name = name.replace(':', '_')
self.readUint8(msgin, '%s_slot' % id) self.readUint8(msgin, '%s_slot' % id)
class impulseTeamContactInit(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
id = "TeamContactInit"
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
friend_string_ids_len = self.readUint32(msgin, '%s_friend_string_ids_len' % id)
for i in range(0, friend_string_ids_len):
_ = self.readUint32(msgin, '%s_friend_string_ids_%d' % (id, i))
nb_state = self.readUint32(msgin, '%s_nb_state' % id)
for i in range(0, nb_state):
_ = self.readUint32(msgin, '%s_friend_online_status_%d' % (id, i))
ignore_list_len = self.readUint32(msgin, '%s_ignore_list_len' % id)
for i in range(0, ignore_list_len):
_ = self.readUString(msgin, '%s_ignore_list_%d' % (id, i))
class impulseNpcIconGetDesc(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
# 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)
self.name = name.replace(':', '_')
nb8 = self.readUint8(msgin, '%s_nb8' % id)
for i in range(0, nb8):
_ = self.readUint32(msgin, '%s_NPCIconCacheKey_%d' % (id, i))
class impulseUserBars(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
# 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)
self.name = name.replace(':', '_')
_ = self.readUint8(msgin, '%s_barsenttoplayermsgnumber' % id)
_ = self.readSint32(msgin, '%s_oldchascore1barsenttoplayer' % id)
_ = self.readSint32(msgin, '%s_oldchascore2barsenttoplayer' % id)
_ = self.readSint32(msgin, '%s_oldchascore3barsenttoplayer' % id)
_ = self.readSint32(msgin, '%s_oldchascore4barsenttoplayer' % id)
class DecodeImpulseSimple: class DecodeImpulseSimple:
def __init__(self): def __init__(self):
''' '''
@ -677,7 +738,7 @@ class DecodeImpulseSimple:
self.GenericMsgHeaderMngr.setdefault( "DEATH:RESPAWN_POINT", impulseDeathRespawnPoint) self.GenericMsgHeaderMngr.setdefault( "DEATH:RESPAWN_POINT", impulseDeathRespawnPoint)
self.GenericMsgHeaderMngr.setdefault( "GUILD:UPDATE_PLAYER_TITLE", impulseGuildUpdatePlayerTitle) self.GenericMsgHeaderMngr.setdefault( "GUILD:UPDATE_PLAYER_TITLE", impulseGuildUpdatePlayerTitle)
self.GenericMsgHeaderMngr.setdefault( "GUILD:USE_FEMALE_TITLES", ImpulseGuildFemaleTitles ) self.GenericMsgHeaderMngr.setdefault( "GUILD:USE_FEMALE_TITLES", ImpulseGuildFemaleTitles )
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_DESC", ImpulseNpsIconSetDesc ) self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_DESC", ImpulseNpcIconSetDesc )
self.GenericMsgHeaderMngr.setdefault( "PHRASE:DOWNLOAD", ImpulsePhraseDownload ) self.GenericMsgHeaderMngr.setdefault( "PHRASE:DOWNLOAD", ImpulsePhraseDownload )
self.GenericMsgHeaderMngr.setdefault( "POSITION", ImpulsePosition ) self.GenericMsgHeaderMngr.setdefault( "POSITION", ImpulsePosition )
self.GenericMsgHeaderMngr.setdefault( "STRING:DYN_STRING", ImpulseSringDynString ) self.GenericMsgHeaderMngr.setdefault( "STRING:DYN_STRING", ImpulseSringDynString )
@ -688,6 +749,9 @@ class DecodeImpulseSimple:
self.GenericMsgHeaderMngr.setdefault( "ENCYCLOPEDIA:INIT", impulseEncyclopediaInit ) self.GenericMsgHeaderMngr.setdefault( "ENCYCLOPEDIA:INIT", impulseEncyclopediaInit )
self.GenericMsgHeaderMngr.setdefault( "DB_INIT:INV", impulseInitInventory) self.GenericMsgHeaderMngr.setdefault( "DB_INIT:INV", impulseInitInventory)
self.GenericMsgHeaderMngr.setdefault( "DB_INIT:PLR", impulseDatabaseInitPlayer) self.GenericMsgHeaderMngr.setdefault( "DB_INIT:PLR", impulseDatabaseInitPlayer)
self.GenericMsgHeaderMngr.setdefault( "TEAM:CONTACT_INIT", impulseTeamContactInit)
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:GET_DESC", impulseNpcIconGetDesc)
self.GenericMsgHeaderMngr.setdefault( "USER:BARS", impulseUserBars)
def execute(self, msgin, world, references = [], name=""): def execute(self, msgin, world, references = [], name=""):
''' '''
@ -743,6 +807,11 @@ class DecodeImpulseSimple:
if a == 0: if a == 0:
return impulse return impulse
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d, not read:%d]" % (fullname, msgin.showAllData(), nbBitNotRead, a)) logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d, not read:%d]" % (fullname, msgin.showAllData(), nbBitNotRead, a))
elif nbBitNotRead < 32:
a = msgin.readSerial(nbBitNotRead, decode=False)
if a == 0:
return impulse
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d, not read:%d]" % (fullname, msgin.showAllData(), nbBitNotRead, a))
logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d]" % (fullname, msgin.showAllData(), nbBitNotRead)) logging.getLogger(LOGGER).error("MessageXML not decoded: [%s] %s [size:%d]" % (fullname, msgin.showAllData(), nbBitNotRead))
return None return None
else: else:

View file

@ -26,3 +26,11 @@ def getPowerOf2(v):
ret += 1 ret += 1
res *= 2 res *= 2
return ret return ret
def getPowerOf2_Bis(v):
res=1;
ret=0;
while res<=v:
ret += 1
res *= 2
return ret