From 390c448bde828a71b01647645217b72af26e93ba Mon Sep 17 00:00:00 2001 From: AleaJactaEst Date: Wed, 6 Nov 2019 22:33:35 +0100 Subject: [PATCH] update yaml output --- spykhanat.py | 56 ++++++++++++++++++++++++++++++------------- tools/CAction.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 17 deletions(-) diff --git a/spykhanat.py b/spykhanat.py index 7e243a1..01530ff 100755 --- a/spykhanat.py +++ b/spykhanat.py @@ -216,7 +216,7 @@ class SpyPcap(): # logging.getLogger(LOGGER).info("[Client -> Server] actions:%s" % str(actions)) # # decodeVisualProperties( msgin ); - def decode_client_send_normal_message(self, msgin, clientid, dst): + def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name): ''' khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage() khanat-opennel-code/code/ryzom/common/src/game_share/action_block.cpp:36 void CActionBlock::serial(CBitMemStream &msg) @@ -242,8 +242,17 @@ class SpyPcap(): logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) # decodeVisualProperties( msgin ); + if self.outyaml and actions: + self.outyaml.write("\nblock_%s_udp_%d:\n" %(name, sequenceid)) + id = 0 + for action in actions: + self.outyaml.write(" action_%s_udp_%d_%d:\n" %(name, sequenceid, id)) + params = action.get_parameter() + for key in params: + self.outyaml.write(" %s: %s\n" % (key, params[key])) + id += 1 - def decode_client_message(self, msgin, clientid, dst, sequenceid): + def decode_client_message(self, msgin, clientid, dst, sequenceid, name): CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') SystemMode = msgin.readBool('SystemMode') logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) @@ -259,7 +268,7 @@ class SpyPcap(): self.client_state[clientid]['AckBitMask'] = AckBitMask logging.getLogger(LOGGER).info("[Client -> Server] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) #self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1) - self.decode_client_send_normal_message(msgin, clientid, dst) + self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, name) else: message = msgin.readUint8('message') try: @@ -305,7 +314,7 @@ class SpyPcap(): 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()) - def decode_khanat_message(self, msgin, src, dst, sequenceid): + def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname): CurrentSendNumber = msgin.readSint32('CurrentSendNumber') logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) SystemMode = msgin.readBool('SystemMode') @@ -402,35 +411,48 @@ class SpyPcap(): dst = "%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port) 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' - who = "Server" if src not in list_host: - clientname = "Server %d" % serverid - list_host.setdefault(src, clientname) + name = "Server%d" % serverid + list_host.setdefault(src, name) serverid += 1 + else: + if src not in list_host: + name = "Client%d" % clientid + list_host.setdefault(src, name) + clientid += 1 + + if (self.khanat_host_service and self.khanat_host_service.match(dst)) or ( not self.khanat_host_service and khanat_host == dst): + if dst not in list_host: + name = "Server%d" % serverid + list_host.setdefault(dst, name) + serverid += 1 + else: + if dst not in list_host: + name = "Client%d" % clientid + list_host.setdefault(dst, name) + clientid += 1 + + 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' logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) - self.decode_khanat_message(msgin, src, dst, sequenceid) + self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst]) else: _provenance = 'Client -> Server' - if src not in list_host: - clientname = "Client %d" % clientid - list_host.setdefault(src, clientname) - clientid += 1 - who = "Client" logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) - self.decode_client_message(msgin, src, dst, sequenceid) + self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst]) moredata='message decoded' if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: moredata = "message partially decoded" if self.show_message_decoded: logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData())) if self.outyaml: - self.outyaml.write("\nmessage_%d:\n sequence: %d\n time: %s\n name: %s\n function: %s\n source: %s\n destination: %s\n state: %s\n message:\n" % ( + self.outyaml.write("\nudp_%d:\n sequence: %d\n time: %s\n source: %s\n destination: %s\n function: %s\n adress_source: %s\n adress_destination: %s\n state: %s\n message:\n" % ( sequenceid, sequenceid, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), list_host[src], - who, + list_host[dst], + _provenance, src, dst, moredata diff --git a/tools/CAction.py b/tools/CAction.py index b98557c..ac98a07 100644 --- a/tools/CAction.py +++ b/tools/CAction.py @@ -36,6 +36,9 @@ class CAction: self.GameCycle = 0 self.world = world + def get_parameter(self): + return {"Type": "CAction", "Code": self.Code, "Slot": self.Slot, "PropertyCode": self.PropertyCode, "GameCycle": self.GameCycle} + def unpack(self, message): raise RuntimeError @@ -107,6 +110,15 @@ class CActionPosition(CAction): def __str__(self): return "CActionPosition" + super().__str__() + " x:" + str(self.Position16[0]) + " y:" + str(self.Position16[1]) + " z:" + str(self.Position16[2]) + " IsRelative:" + str(self.IsRelative) + " Interior:" + str(self.Interior) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionPosition" + ret.setdefault("Position", ', '.join([str(x) for x in self.Position])) + ret.setdefault("Position16", ', '.join([str(x) for x in self.Position16])) + ret.setdefault("IsRelative", str(self.IsRelative)) + ret.setdefault("IsRelative", str(self.IsRelative)) + return ret + def unpack(self, message): self.Position16[0] = message.readUint16('px') self.Position16[1] = message.readUint16('py') @@ -127,6 +139,11 @@ class CActionSync(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionSync" + return ret + def __str__(self): return "CActionSync" + super().__str__() @@ -134,6 +151,11 @@ class CActionDisconnection(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionDisconnection" + return ret + def __str__(self): return "CActionDisconnection" + super().__str__() @@ -141,6 +163,11 @@ class CActionAssociation(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionAssociation" + return ret + def __str__(self): return "CActionAssociation" + super().__str__() @@ -148,6 +175,11 @@ class CActionDummy(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionDummy" + return ret + def __str__(self): return "CActionDummy" + super().__str__() @@ -155,6 +187,11 @@ class CActionLogin(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionLogin" + return ret + def __str__(self): return "CActionLogin" + super().__str__() @@ -162,6 +199,11 @@ class CActionTargetSlot(CAction): def __init__(self, slot, code, world): super().__init__(slot, code, world) + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionTargetSlot" + return ret + def __str__(self): return "CActionTargetSlot" + super().__str__() @@ -171,6 +213,12 @@ class CActionGeneric(CAction): self._Message = None self.decoded = False + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionGeneric" + ret["Message"] = self._Message.showAllData() + return ret + def set(self, message): self._Message = message @@ -215,6 +263,15 @@ class CActionGenericMultiPart(CAction): self.Part = 0 self.NbBlock = 0 + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionGenericMultiPart" + ret["Number"] = "%d" % self.Number + ret["Part"] = "%d" % self.Part + ret["NbBlock"] = "%d" % self.NbBlock + ret["PartCont"] = self.PartCont.showAllData() + return ret + def set(self, number, part, buffer, bytelen, size, nbBlock): ''' khanat-opennel-code/code/ryzom/common/src/game_share/action_generic_multi_part.h # void set (uint8 number, uint16 part, const uint8 *buffer, uint32 bytelen, uint32 size, uint16 nbBlock) @@ -314,6 +371,11 @@ class CActionSint64(CAction): TPropIndex.TPropIndex.PROPERTY_OWNER_PEOPLE: 3 , # 4 races and unknow TPropIndex.TPropIndex.PROPERTY_OUTPOST_INFOS: 16 } # 15+1 + def get_parameter(self): + ret = super().get_parameter() + ret["Type"] = "CActionSint64" + return ret + def __str__(self): return "CActionSint64" + super().__str__()