mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-11-21 22:56:13 +00:00
update
This commit is contained in:
parent
065b290753
commit
1df1ee152e
8 changed files with 363 additions and 52 deletions
211
spykhanat.py
211
spykhanat.py
|
@ -39,12 +39,14 @@ from tools import Enum
|
|||
from tools import CActionFactory
|
||||
from tools import CBitSet
|
||||
from tools import DecodeImpulse
|
||||
from tools import DecodeDatabase
|
||||
from tools import World
|
||||
from tools import CGenericMultiPartTemp
|
||||
from tools import CImpulseDecoder
|
||||
#from tools import CStringManager
|
||||
from tools import CAction
|
||||
from tools import Impulse
|
||||
from tools import CPropertyDecoder
|
||||
import xml.etree.ElementTree as ET
|
||||
from datetime import datetime
|
||||
|
||||
|
@ -69,7 +71,7 @@ def write_yaml_str_or_array(outyaml, nbspace, value):
|
|||
outyaml.write(" " * nbspace + str(type(value)) + "\n")
|
||||
|
||||
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:
|
||||
self.khanat_host_service = re.compile(khanat_host_service)
|
||||
else:
|
||||
|
@ -84,14 +86,25 @@ class SpyPcap():
|
|||
self.show_message_decoded = show_message_decoded
|
||||
self.actionFactory = CActionFactory.CActionFactory(None)
|
||||
self.client_state = {}
|
||||
# msg.xml
|
||||
self.decodeImpulse = DecodeImpulse.DecodeImpulse()
|
||||
self.decodeImpulseSimple = Impulse.DecodeImpulseSimple()
|
||||
|
||||
fp = open(msg_xml , 'rt')
|
||||
msgRawXml = fp.read()
|
||||
fp.close()
|
||||
self.msgXml = ET.fromstring(msgRawXml)
|
||||
self.decodeImpulse.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
|
||||
|
||||
def readRaw(self):
|
||||
|
@ -124,7 +137,6 @@ class SpyPcap():
|
|||
ip_packet.src.decode(), udp_packet.src_port,
|
||||
ip_packet.dst.decode(), udp_packet.dst_port,
|
||||
data.decode()))
|
||||
|
||||
elif ip_packet.p == 6:
|
||||
# TCP
|
||||
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):
|
||||
self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, [])
|
||||
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):
|
||||
"""
|
||||
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 = []
|
||||
for level in range(0, 3):
|
||||
if level == 0:
|
||||
|
@ -224,6 +291,8 @@ class SpyPcap():
|
|||
elif action:
|
||||
logging.getLogger(LOGGER).debug("append Code:%s" % str(action.Code))
|
||||
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
|
||||
|
||||
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
|
||||
actions = []
|
||||
impulses = []
|
||||
databases = []
|
||||
if not SystemMode:
|
||||
'''
|
||||
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage()
|
||||
|
@ -353,12 +423,13 @@ class SpyPcap():
|
|||
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).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):
|
||||
target = "%s_%s" % (Source, Parent[7:])
|
||||
actions = []
|
||||
impulses = []
|
||||
databases = []
|
||||
CurrentSendNumber = msgin.readSint32('CurrentSendNumber')
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst))
|
||||
SystemMode = msgin.readBool('SystemMode')
|
||||
|
@ -377,12 +448,14 @@ class SpyPcap():
|
|||
# Decode the actions received in the impulsions
|
||||
logging.getLogger(LOGGER).debug('=' * 80)
|
||||
actionsbis = []
|
||||
logging.getLogger(LOGGER).info("size[actions] %d" % len(actions))
|
||||
for action in actions:
|
||||
referenceBis = "%s_%d" % (target, id)
|
||||
action.add_reference(Parent)
|
||||
action.set_name(referenceBis)
|
||||
logging.getLogger(LOGGER).debug('-' * 80)
|
||||
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:
|
||||
#action.add_reference(Parent)
|
||||
logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE")
|
||||
|
@ -400,6 +473,11 @@ class SpyPcap():
|
|||
) #, Reference = Parent, Name = "%s_%d" % (target, 0))
|
||||
logging.getLogger(LOGGER).info("impulse:%s" % str(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)
|
||||
except Impulse.ImpulseNoElement:
|
||||
pass
|
||||
|
@ -407,6 +485,7 @@ class SpyPcap():
|
|||
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))
|
||||
try:
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s OKKKKKKKK " % action)
|
||||
impulse = action.decodeImpulseSimple(
|
||||
self.decodeImpulseSimple,
|
||||
self.client_state[dst]['world'],
|
||||
|
@ -416,6 +495,7 @@ class SpyPcap():
|
|||
) #, Reference = Parent, Name = "%s_%d" % (target, 0))
|
||||
logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
|
||||
if impulse:
|
||||
print("spykhanat.py:429", type(impulse))
|
||||
impulses.append(impulse)
|
||||
except Impulse.ImpulseNoElement:
|
||||
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}" % (
|
||||
CurrentSendNumber, src, dst, _LastReceivedAck, id,
|
||||
self.client_state[dst]['GenericMultiPartTempServer'].data[id].read().showAllData()))
|
||||
temp = CAction.CActionFake('ACTION_GENERIC_MULTI_PART_CODE',
|
||||
self.client_state[dst]['GenericMultiPartTempServer'].data[id].read(),
|
||||
## temp = CAction.CActionFake('ACTION_GENERIC_MULTI_PART_CODE',
|
||||
## 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)},
|
||||
# Reference = self.client_state[dst]['GenericMultiPartTemp'].data[id].Reference,
|
||||
Name = "inpulse_%s_%s" % (Parent[7:], 0)
|
||||
Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference,
|
||||
Name = "impulse_%s_%s" % (Parent[7:], 0)
|
||||
)
|
||||
temp.Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference
|
||||
actionsbis.append(temp)
|
||||
try:
|
||||
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:
|
||||
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))
|
||||
|
@ -454,6 +584,7 @@ class SpyPcap():
|
|||
# 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]))
|
||||
# self._Actions.pop(0)
|
||||
logging.getLogger(LOGGER).info("size[actions] %d" % len(actions))
|
||||
for action in actionsbis:
|
||||
actions.append(action)
|
||||
|
||||
|
@ -493,7 +624,7 @@ class SpyPcap():
|
|||
#cActionFactory.unpack(msgin)
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData())
|
||||
#logging.getLogger(LOGGER).info("impulses:%s" % str(impulses))
|
||||
return actions, impulses
|
||||
return actions, impulses, databases
|
||||
|
||||
def read(self):
|
||||
file = open( self.pcap_file , 'rb')
|
||||
|
@ -526,8 +657,8 @@ class SpyPcap():
|
|||
logging.getLogger(LOGGER).debug("-" * 80)
|
||||
actions_clients = []
|
||||
actions_servers = []
|
||||
inpulses_servers = []
|
||||
inpulses_clients = []
|
||||
impulses_servers = []
|
||||
impulses_clients = []
|
||||
if self.show_raw_packet:
|
||||
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"),
|
||||
|
@ -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):
|
||||
_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()))
|
||||
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:
|
||||
_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()))
|
||||
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:
|
||||
moredata = "message partially decoded"
|
||||
else:
|
||||
|
@ -623,16 +754,38 @@ class SpyPcap():
|
|||
#self.outyaml.write(" %s: %s\n" % (key, params[key]))
|
||||
id += 1
|
||||
|
||||
if inpulses_servers:
|
||||
self.outyaml.write("\ninpulseserver_%s_%d:\n" %(list_host[src], sequenceid))
|
||||
# if databases_servers:
|
||||
# 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
|
||||
#print("-"*30)
|
||||
#print(inpulses_servers)
|
||||
for inpulse in inpulses_servers:
|
||||
#print(impulses_servers)
|
||||
for impulse_data in impulses_servers:
|
||||
#print("-"*80)
|
||||
#print(inpulse)
|
||||
params = inpulse.get_parameter()
|
||||
self.outyaml.write(" %s:\n" % (inpulse.get_name()))
|
||||
#print(Impulse)
|
||||
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))
|
||||
|
@ -649,6 +802,7 @@ class SpyPcap():
|
|||
id += 1
|
||||
#print("-"*30)
|
||||
|
||||
|
||||
if actions_clients:
|
||||
self.outyaml.write("\nblock_%s_%d:\n" %(list_host[src], sequenceid))
|
||||
id = 0
|
||||
|
@ -673,12 +827,12 @@ class SpyPcap():
|
|||
#self.outyaml.write(" %s: %s\n" % (key, params[key]))
|
||||
id += 1
|
||||
|
||||
# if inpulses_clients:
|
||||
# self.outyaml.write("\ninpulseclient_%s_%d:\n" %(list_host[src], sequenceid))
|
||||
# if impulses_clients:
|
||||
# self.outyaml.write("\nImpulseclient_%s_%d:\n" %(list_host[src], sequenceid))
|
||||
# id = 0
|
||||
# for inpulse in inpulses_clients:
|
||||
# params = inpulse.get_parameter()
|
||||
# self.outyaml.write(" %s:\n" % (inpulse.get_name()))
|
||||
# for Impulse in impulses_clients:
|
||||
# params = Impulse.get_parameter()
|
||||
# self.outyaml.write(" %s:\n" % (Impulse.get_name()))
|
||||
# id += 1
|
||||
sequenceid += 1
|
||||
sequencenum += 1
|
||||
|
@ -699,6 +853,7 @@ def main():
|
|||
# logger.append(logging.getLogger(CAction.LOGGER))
|
||||
# logger.append(logging.getLogger(CActionFactory.LOGGER))
|
||||
# logger.append(logging.getLogger(BitStream.LOGGER))
|
||||
logger.append(logging.getLogger(DecodeDatabase.LOGGER))
|
||||
logger.append(logging.getLogger(Impulse.LOGGER))
|
||||
CImpulseDecoder
|
||||
# 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("-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("-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("--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')
|
||||
|
@ -732,6 +888,7 @@ def main():
|
|||
spy = SpyPcap(khanat_host_service=args.khanat_host_service,
|
||||
pcap_file=args.pcap_file,
|
||||
msg_xml=args.msg_xml,
|
||||
database_xml=args.database_xml,
|
||||
filter_host_service=args.filter_host_service,
|
||||
show_raw_packet=args.show_raw_packet,
|
||||
show_message_decoded=args.show_message_decoded,
|
||||
|
|
|
@ -42,6 +42,10 @@ class BitStream():
|
|||
def __len__(self):
|
||||
return (self._pos + 7) // 8
|
||||
|
||||
def reset_read(self):
|
||||
self._read = 0
|
||||
self._groupRead = []
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
ret = BitStream()
|
||||
ret._pos = self._pos
|
||||
|
@ -583,27 +587,53 @@ class BitStream():
|
|||
return c_int8(v).value
|
||||
|
||||
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
|
||||
if sys.byteorder == "little":
|
||||
v1 = self.readSerial(32, decode=False)
|
||||
v2 = self.readSerial(32, decode=False)
|
||||
v4 = self.readSerial(8, 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:
|
||||
v2 = self.readSerial(32, decode=False)
|
||||
v1 = self.readSerial(32, decode=False)
|
||||
v3 = (v1 << 32) | v2
|
||||
self._groupRead.append((p1, p1+64, name, 'Uint64', v3))
|
||||
v1 = self.readSerial(8, decode=False)
|
||||
v2 = self.readSerial(8, decode=False)
|
||||
v3 = self.readSerial(8, decode=False)
|
||||
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
|
||||
|
||||
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
|
||||
if sys.byteorder == "little":
|
||||
v1 = self.readSerial(32, decode=False)
|
||||
v2 = self.readSerial(32, decode=False)
|
||||
v4 = self.readSerial(8, 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:
|
||||
v2 = self.readSerial(32, decode=False)
|
||||
v1 = self.readSerial(32, decode=False)
|
||||
v3 = (v1 << 32) | v2
|
||||
self._groupRead.append((p1, p1+64, name, 'Sint64', c_int64(v3).value))
|
||||
v1 = self.readSerial(8, decode=False)
|
||||
v2 = self.readSerial(8, decode=False)
|
||||
v3 = self.readSerial(8, decode=False)
|
||||
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
|
||||
|
||||
def readFloat(self, name):
|
||||
|
|
|
@ -115,6 +115,10 @@ class CAction:
|
|||
return "[%d,%d]" % (self.Code , self.Slot)
|
||||
|
||||
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):
|
||||
super().__init__(slot, code, world)
|
||||
self.Position = [0, 0, 0]
|
||||
|
@ -503,3 +507,8 @@ class CActionFake():
|
|||
ret["Reference"] = self.Reference
|
||||
ret["Message"] = self._Message.extractAllData()
|
||||
return ret
|
||||
|
||||
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
|
||||
ret = decodeImpulseSimple.execute(self._Message, world, Reference, Name)
|
||||
self.decoded = True
|
||||
return ret
|
||||
|
|
|
@ -24,13 +24,14 @@ from tools import BitStream
|
|||
LOGGER='CGenericMultiPartTemp'
|
||||
|
||||
class CGenericMultiPartTemp():
|
||||
def __init__(self):
|
||||
def __init__(self, autoDecompile=True):
|
||||
self.NbBlock = 0xFFFFFFFF
|
||||
self.MsgDecoded = None
|
||||
self.FirstRead = False
|
||||
self.Reference = []
|
||||
self.block = {}
|
||||
self.Name = None
|
||||
self.AutoDecompile = autoDecompile
|
||||
|
||||
def getNbCurrentBlock(self):
|
||||
return len(self.block)
|
||||
|
@ -60,6 +61,7 @@ class CGenericMultiPartTemp():
|
|||
for data in self.block:
|
||||
logging.getLogger(LOGGER).error("CGenericMultiPartTemp : Number:%d id:%d len:%d/%d" % (Number, data, len(self.block), self.NbBlock))
|
||||
bms.pushBitStream(self.block[data])
|
||||
if self.AutoDecompile:
|
||||
try:
|
||||
ret = decodeImpulse.execute(bms, world)
|
||||
except:
|
||||
|
|
|
@ -24,6 +24,7 @@ from tools import getPowerOf2
|
|||
from tools import CShardName
|
||||
from tools import CCharacterSummary
|
||||
from tools import CMainlandSummary
|
||||
from tools import DecodeDatabase
|
||||
|
||||
|
||||
LOGGER='DecodeImpulse'
|
||||
|
@ -34,9 +35,10 @@ class DecodeImpulse():
|
|||
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork()
|
||||
'''
|
||||
self.msgXml = None
|
||||
self.databaseXml = None
|
||||
# self.databaseXml = None
|
||||
self.GenericMsgHeaderMngr = {}
|
||||
self.initializeNetwork()
|
||||
self.decodeDatabase = DecodeDatabase.DecodeDatabase()
|
||||
|
||||
def updatePatcherPriorityBasedOnCharacters(self, world):
|
||||
logging.getLogger(LOGGER).debug('Load character')
|
||||
|
@ -581,4 +583,4 @@ class DecodeImpulse():
|
|||
self.msgXml = msgXml
|
||||
|
||||
def loadDatabase(self, databaseXml):
|
||||
self.databaseXml = databaseXml
|
||||
self.decodeDatabase.loadDatabase(self.databaseXml)
|
||||
|
|
|
@ -612,3 +612,37 @@ class TCDBBank(IntEnum):
|
|||
# CDBGlobal,
|
||||
NB_CDB_BANKS = 3,
|
||||
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
|
||||
|
||||
|
|
|
@ -164,6 +164,8 @@ class ImpulseBase:
|
|||
value = msgin.readUint32(id + '_extended')
|
||||
self.param.setdefault(id, value)
|
||||
return value
|
||||
def readDatabases(self, world, decodeDatabase):
|
||||
return None
|
||||
|
||||
class ImpulseBotchatSetFilters(ImpulseBase):
|
||||
def __init__(self):
|
||||
|
@ -315,9 +317,10 @@ class ImpulseGuildFemaleTitles(ImpulseBase):
|
|||
self.readSerial(msgin, 1, 'UseFemaleTitles')
|
||||
|
||||
|
||||
class ImpulseNpsIconSetDesc(ImpulseBase):
|
||||
class ImpulseNpcIconSetDesc(ImpulseBase):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.data = BitStream.BitStream()
|
||||
|
||||
def read(self, name, msgin, world):
|
||||
'''
|
||||
|
@ -326,9 +329,15 @@ class ImpulseNpsIconSetDesc(ImpulseBase):
|
|||
logging.getLogger(LOGGER).debug("read")
|
||||
self.name = name.replace(':', '_')
|
||||
nb8 = self.readUint8(msgin, 'nb8')
|
||||
self.data.pushUint8(nb8)
|
||||
for i in range(0, nb8):
|
||||
self.readUint32(msgin, 'NpcIconSetDesc_%d_npcAlias' % nb8)
|
||||
self.readUint32(msgin, 'NpcIconSetDesc_%d_state' % nb8)
|
||||
npcAlias = self.readUint32(msgin, 'NpcIconSetDesc_%d_npcAlias' % 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):
|
||||
|
@ -392,8 +401,10 @@ class ImpulsePosition(ImpulseBase):
|
|||
super().__init__()
|
||||
|
||||
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")
|
||||
self.name = name.replace(':', '_')
|
||||
self.readBool(msgin, '')
|
||||
self.readSint32(msgin, 'X')
|
||||
self.readSint32(msgin, 'Y')
|
||||
self.readSint32(msgin, 'Z')
|
||||
|
@ -636,7 +647,7 @@ class impulseDatabaseInitPlayer(ImpulseBase):
|
|||
self.readUint32(msgin, '%s_serverTick' % id)
|
||||
propertyCount = self.readUint16(msgin, '%s_propertyCount' % id)
|
||||
for i in range(0, propertyCount):
|
||||
propertyCount = self.readUint32(msgin, '%s_propertyCount' % id)
|
||||
_ = self.readUint32(msgin, '%s_property' % id)
|
||||
|
||||
|
||||
class ImpulseConnectionDeleteChar(ImpulseBase):
|
||||
|
@ -651,6 +662,56 @@ class ImpulseConnectionDeleteChar(ImpulseBase):
|
|||
self.name = name.replace(':', '_')
|
||||
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:
|
||||
def __init__(self):
|
||||
'''
|
||||
|
@ -677,7 +738,7 @@ class DecodeImpulseSimple:
|
|||
self.GenericMsgHeaderMngr.setdefault( "DEATH:RESPAWN_POINT", impulseDeathRespawnPoint)
|
||||
self.GenericMsgHeaderMngr.setdefault( "GUILD:UPDATE_PLAYER_TITLE", impulseGuildUpdatePlayerTitle)
|
||||
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( "POSITION", ImpulsePosition )
|
||||
self.GenericMsgHeaderMngr.setdefault( "STRING:DYN_STRING", ImpulseSringDynString )
|
||||
|
@ -688,6 +749,9 @@ class DecodeImpulseSimple:
|
|||
self.GenericMsgHeaderMngr.setdefault( "ENCYCLOPEDIA:INIT", impulseEncyclopediaInit )
|
||||
self.GenericMsgHeaderMngr.setdefault( "DB_INIT:INV", impulseInitInventory)
|
||||
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=""):
|
||||
'''
|
||||
|
@ -743,6 +807,11 @@ class DecodeImpulseSimple:
|
|||
if a == 0:
|
||||
return impulse
|
||||
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))
|
||||
return None
|
||||
else:
|
||||
|
|
|
@ -26,3 +26,11 @@ def getPowerOf2(v):
|
|||
ret += 1
|
||||
res *= 2
|
||||
return ret
|
||||
|
||||
def getPowerOf2_Bis(v):
|
||||
res=1;
|
||||
ret=0;
|
||||
while res<=v:
|
||||
ret += 1
|
||||
res *= 2
|
||||
return ret
|
||||
|
|
Loading…
Reference in a new issue