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 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,

View file

@ -41,6 +41,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()
@ -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):

View file

@ -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

View file

@ -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,11 +61,12 @@ 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])
try:
ret = decodeImpulse.execute(bms, world)
except:
logging.getLogger(LOGGER).error("CGenericMultiPartTemp : Error to decode - Number:%d len:%d/%d msg:%s" % (Number, len(self.block), self.NbBlock, bms.showAllData()))
return ret
if self.AutoDecompile:
try:
ret = decodeImpulse.execute(bms, world)
except:
logging.getLogger(LOGGER).error("CGenericMultiPartTemp : Error to decode - Number:%d len:%d/%d msg:%s" % (Number, len(self.block), self.NbBlock, bms.showAllData()))
return ret
logging.getLogger(LOGGER).error("CGenericMultiPartTemp : data : %s" % bms.showAllData())
self.MsgDecoded = bms
else:

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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