update spykhanat.py (it can generate yaml file with detail message decoded)

This commit is contained in:
AleaJactaEst 2020-04-11 23:52:41 +02:00
parent 390c448bde
commit 5c506cfa32
11 changed files with 807 additions and 52 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*.pcap
*.yaml
*.yml
*.log
*.err

View file

@ -117,7 +117,7 @@ class ClientKhanat:
'Referer': 'http://' + self.khanat_host+':'+ str(self.khanat_port_login) + '/ams/index.php?page=register', 'Referer': 'http://' + self.khanat_host+':'+ str(self.khanat_port_login) + '/ams/index.php?page=register',
'Upgrade-Insecure-Requests': '1', 'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20100101 Firefox/6.0', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20100101 Firefox/6.0',
'Content-Type': 'application/x-www-form-urlencoded'} '': 'application/x-www-form-urlencoded'}
headers = {'Content-Type': 'application/x-www-form-urlencoded'} headers = {'Content-Type': 'application/x-www-form-urlencoded'}
params = urllib.parse.urlencode({'Username': self.login, 'Password': self.password, 'ConfirmPass': self.password, 'Email': self.login+'@khaganat.net', 'TaC': 'on', 'function': 'add_user'}) params = urllib.parse.urlencode({'Username': self.login, 'Password': self.password, 'ConfirmPass': self.password, 'Email': self.login+'@khaganat.net', 'TaC': 'on', 'function': 'add_user'})

View file

@ -22,6 +22,9 @@
# sudo tcpdump -i docker0 -w capture2.pcap # sudo tcpdump -i docker0 -w capture2.pcap
# ./spykhanat.py --pcap-file=../capture2.pcap --msg-xml=../khanat-opennel-code/code/ryzom/common/data_common/msg.xml # ./spykhanat.py --pcap-file=../capture2.pcap --msg-xml=../khanat-opennel-code/code/ryzom/common/data_common/msg.xml
# install pcapfile
# pip install pypcapfile
import argparse import argparse
import logging import logging
from pcapfile import savefile from pcapfile import savefile
@ -39,8 +42,9 @@ from tools import DecodeImpulse
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
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime from datetime import datetime
@ -56,6 +60,14 @@ LOGGER = 'SpyKhanat'
#ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload)) #ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload))
#print(ip_packet) #print(ip_packet)
def write_yaml_str_or_array(outyaml, nbspace, value):
if type(value) == str:
outyaml.write(" " * nbspace + "- %s\n" % (value))
else:
for key in value:
outyaml.write(" " * nbspace + "- %s\n" % (key))
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, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None):
if khanat_host_service: if khanat_host_service:
@ -73,11 +85,13 @@ class SpyPcap():
self.actionFactory = CActionFactory.CActionFactory(None) self.actionFactory = CActionFactory.CActionFactory(None)
self.client_state = {} self.client_state = {}
self.decodeImpulse = DecodeImpulse.DecodeImpulse() self.decodeImpulse = DecodeImpulse.DecodeImpulse()
self.decodeImpulseSimple = Impulse.DecodeImpulseSimple()
fp = open(msg_xml , 'rt') fp = open(msg_xml , 'rt')
msgRawXml = fp.read() msgRawXml = fp.read()
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.outyaml = outyaml self.outyaml = outyaml
def readRaw(self): def readRaw(self):
@ -156,7 +170,8 @@ class SpyPcap():
'AckBitMask': 0, 'AckBitMask': 0,
'RegisteredAction': {}, 'RegisteredAction': {},
'world': World.World(), 'world': World.World(),
'GenericMultiPartTemp': CGenericMultiPartTemp.GenericMultiPartTemp(), 'GenericMultiPartTempServer': CGenericMultiPartTemp.GenericMultiPartTemp(),
'GenericMultiPartTempClient': CGenericMultiPartTemp.GenericMultiPartTemp(),
'CImpulseDecoder': None, 'CImpulseDecoder': None,
'CActionFactory': None, 'CActionFactory': None,
'LastAck0': [-1], 'LastAck0': [-1],
@ -211,18 +226,14 @@ class SpyPcap():
self.add_registered_action(clientid, action) self.add_registered_action(clientid, action)
return actions return actions
# def decode_client_receive_normal_message(self, msgin, clientid, dst): def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name, Reference):
# actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] )
# logging.getLogger(LOGGER).info("[Client -> Server] actions:%s" % str(actions))
# # decodeVisualProperties( msgin );
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/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) khanat-opennel-code/code/ryzom/common/src/game_share/action_block.cpp:36 void CActionBlock::serial(CBitMemStream &msg)
''' '''
#actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] ) #actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] )
actions = [] actions = []
impulses = []
noerror = True noerror = True
msgin.disable_LogErrorOnStreamOverflow() msgin.disable_LogErrorOnStreamOverflow()
while noerror: while noerror:
@ -231,7 +242,7 @@ class SpyPcap():
num = msgin.readUint8("num") num = msgin.readUint8("num")
logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, num)) logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, num))
for i in range(0, num): for i in range(0, num):
actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin)) actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin, Reference, name))
pass pass
except BitStream.OverflowError: except BitStream.OverflowError:
noerror = False noerror = False
@ -240,24 +251,33 @@ class SpyPcap():
raise e raise e
msgin.enable_LogErrorOnStreamOverflow() msgin.enable_LogErrorOnStreamOverflow()
ids = 0
for action in actions:
try:
impulse = action.decodeImpulseSimple(
self.decodeImpulseSimple,
self.client_state[clientid]['world'],
self.client_state[clientid]['GenericMultiPartTempClient'],
Reference = name
) #, Reference = Parent, Name = "%s_%d" % (target, 0))
if impulse:
impulses.append(impulse)
except Impulse.ImpulseNoElement:
pass
ids += 1
logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions])))
# decodeVisualProperties( msgin ); # decodeVisualProperties( msgin );
if self.outyaml and actions: return actions, impulses
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, name): def decode_client_message(self, msgin, clientid, dst, sequenceid, name, Parent, Source):
target = "%s_%s" % (Source, Parent[7:])
CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber')
SystemMode = msgin.readBool('SystemMode') SystemMode = msgin.readBool('SystemMode')
logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst))
self.initialize_client(clientid) self.initialize_client(clientid)
self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber
actions = []
impulses = []
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()
@ -268,7 +288,7 @@ class SpyPcap():
self.client_state[clientid]['AckBitMask'] = AckBitMask 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)) 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_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1)
self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, name) actions, _ = self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, "%s_%d" % (target, 0), Parent)
else: else:
message = msgin.readUint8('message') message = msgin.readUint8('message')
try: try:
@ -282,10 +302,14 @@ class SpyPcap():
LanguageCode = msgin.readString('LanguageCode') LanguageCode = msgin.readString('LanguageCode')
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" % logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" %
(typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode)) (typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode))
action = CAction.CActionFake('SYSTEM_LOGIN_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE:
LatestProbe = msgin.readSint32('LatestProbe') LatestProbe = msgin.readSint32('LatestProbe')
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage,
LatestProbe, CurrentReceivedNumber, clientid, dst)) LatestProbe, CurrentReceivedNumber, clientid, dst))
action = CAction.CActionFake('SYSTEM_PROBE_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE:
Synchronize = msgin.readUint32('Synchronize') Synchronize = msgin.readUint32('Synchronize')
stime = msgin.readSint64('stime') stime = msgin.readSint64('stime')
@ -296,6 +320,8 @@ class SpyPcap():
md5Database = bytes(DatabaseData) md5Database = bytes(DatabaseData)
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % ( logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (
typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode())) typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode()))
action = CAction.CActionFake('SYSTEM_SYNC_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE: elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE:
LastReceivedNumber = msgin.readSint32('LastReceivedNumber') LastReceivedNumber = msgin.readSint32('LastReceivedNumber')
LastAckInLongAck = msgin.readSint32('LastAckInLongAck') LastAckInLongAck = msgin.readSint32('LastAckInLongAck')
@ -304,22 +330,31 @@ class SpyPcap():
LatestSync = msgin.readSint32('LatestSync') LatestSync = msgin.readSint32('LatestSync')
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % ( logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % (
typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField)) typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField))
action = CAction.CActionFake('SYSTEM_ACK_SYNC_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE:
SizeLatestProbes = msgin.readSint32('SizeLatestProbes') SizeLatestProbes = msgin.readSint32('SizeLatestProbes')
LatestProbes = [] LatestProbes = []
for data in range(0, SizeLatestProbes): for data in range(0, SizeLatestProbes):
LatestProbes.append(msgin.readSint32('LatestProbes')) LatestProbes.append(msgin.readSint32('LatestProbes'))
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes))) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes)))
action = CAction.CActionFake('SYSTEM_ACK_PROBE_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
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
def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname): def decode_khanat_message(self, msgin, src, dst, sequenceid, clientname, Parent, Source):
target = "%s_%s" % (Source, Parent[7:])
actions = []
impulses = []
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')
self.initialize_client(dst) self.initialize_client(dst)
self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber
id = 0
if not SystemMode: if not SystemMode:
_LastReceivedAck = msgin.readSint32('LastReceivedAck'); _LastReceivedAck = msgin.readSint32('LastReceivedAck');
logging.getLogger(LOGGER).debug("[Server -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck)) logging.getLogger(LOGGER).debug("[Server -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck))
@ -331,29 +366,80 @@ 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 = []
for action in 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('-' * 80)
logging.getLogger(LOGGER).debug('Analyse actions:%s', action) logging.getLogger(LOGGER).debug('Analyse actions:%s', action)
if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE: if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE:
#action.add_reference(Parent)
logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE") logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE")
actionsbis.append(CAction.CActionFake('ACTION_DISCONNECTION_CODE', self.client_state[dst]['GenericMultiPartTempServer'].data[id].read())) # , Reference = Parent, Name = "%s_%d" % (target, 0)
elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE: elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE:
action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) #action.add_reference(Parent)
#action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTempServer']) #, Reference = Parent, Name = "%s_%d" % (target, 0))
try:
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))
logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
if impulse:
impulses.append(impulse)
except Impulse.ImpulseNoElement:
pass
logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action)) logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action))
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]['GenericMultiPartTemp']) #action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTempServer'], Reference = referenceBis) #, Reference = Parent, Name = "%s_%d" % (target, 0))
try:
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))
logging.getLogger(LOGGER).info("impulse:%s" % str(impulse))
if impulse:
impulses.append(impulse)
except Impulse.ImpulseNoElement:
pass
logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action) logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action)
for id in self.client_state[dst]['GenericMultiPartTemp'].data: for id in self.client_state[dst]['GenericMultiPartTempServer'].data:
if self.client_state[dst]['GenericMultiPartTemp'].data[id].isAvailable(): if self.client_state[dst]['GenericMultiPartTempServer'].data[id].isAvailable():
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]['GenericMultiPartTemp'].data[id].read().showAllData())) 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(),
# {'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)
)
temp.Reference = self.client_state[dst]['GenericMultiPartTempServer'].data[id].Reference
actionsbis.append(temp)
elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE: elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE:
#action.add_reference(Parent)
logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE") logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE")
actionsbis.append(CAction.CActionFake('ACTION_DUMMY_CODE', self.client_state[dst]['GenericMultiPartTempServer'].data[id].read(), Reference=Parent, Name = "%s_%d" % (target, 0)))
self.add_registered_action(dst, action) self.add_registered_action(dst, action)
id += 1
# # remove all old actions that are acked # # remove all old actions that are acked
# 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)
for action in actionsbis:
actions.append(action)
logging.getLogger(LOGGER).info("impulses:%s" % str(impulses))
else: else:
message = msgin.readUint8('message') message = msgin.readUint8('message')
#referenceBis = "%s_%d" % (Parent, id)
logging.getLogger(LOGGER).debug("[Server -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).debug("[Server -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message))
if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE:
logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize") logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize")
@ -363,20 +449,30 @@ class SpyPcap():
MsgData = msgin.readArrayUint8(16, 'MsgData') MsgData = msgin.readArrayUint8(16, 'MsgData')
DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') DatabaseData = msgin.readArrayUint8(16, 'DatabaseData')
logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData))) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData)))
action = CAction.CActionFake('SYSTEM_SYNC_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE: elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE:
logging.getLogger(LOGGER).debug("[Server -> Client] Stalled") logging.getLogger(LOGGER).debug("[Server -> Client] Stalled")
logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message))
action = CAction.CActionFake('SYSTEM_STALLED_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE:
logging.getLogger(LOGGER).debug("[Server -> Client] Probe") logging.getLogger(LOGGER).debug("[Server -> Client] Probe")
LatestProbe = msgin.readSint32('LatestProbe') LatestProbe = msgin.readSint32('LatestProbe')
logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe))
action = CAction.CActionFake('SYSTEM_PROBE_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE: elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
logging.getLogger(LOGGER).info("[Server -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message))
action = CAction.CActionFake('SYSTEM_SERVER_DOWN_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
actions.append(action)
else: else:
logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message) logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message)
#cActionFactory = CAction.CActionFactory(None) #cActionFactory = CAction.CActionFactory(None)
#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))
return actions, impulses
def read(self): def read(self):
file = open( self.pcap_file , 'rb') file = open( self.pcap_file , 'rb')
@ -386,6 +482,9 @@ class SpyPcap():
serverid = 1 serverid = 1
list_host = {} list_host = {}
sequenceid = 1 sequenceid = 1
sequencenum = 1
if self.outyaml:
self.outyaml.write("# Generated : %s\n\n" % (datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
for pkt in pcapfile.packets: for pkt in pcapfile.packets:
eth_frame = ethernet.Ethernet(pkt.raw()) eth_frame = ethernet.Ethernet(pkt.raw())
@ -397,8 +496,17 @@ class SpyPcap():
data = udp_packet.payload data = udp_packet.payload
if udp_packet.src_port == 53 or udp_packet.dst_port == 53: if udp_packet.src_port == 53 or udp_packet.dst_port == 53:
continue continue
if udp_packet.src_port == 5353 and ip_packet.src.decode() == "224.0.0.251":
continue
if udp_packet.dst_port == 5353 and ip_packet.dst.decode() == "224.0.0.251":
continue
if not self.filter_host_service or self.filter_host_service.match("%s:%d" % (ip_packet.src.decode(), udp_packet.src_port)) or self.filter_host_service.match("%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port)): if not self.filter_host_service or self.filter_host_service.match("%s:%d" % (ip_packet.src.decode(), udp_packet.src_port)) or self.filter_host_service.match("%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port)):
Reference = "packet_%d" % sequenceid
logging.getLogger(LOGGER).debug("-" * 80) logging.getLogger(LOGGER).debug("-" * 80)
actions_clients = []
actions_servers = []
inpulses_servers = []
inpulses_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"),
@ -435,20 +543,21 @@ 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()))
self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst]) actions_servers, inpulses_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()))
self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst]) actions_clients, inpulses_clients = self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst], Reference, list_host[src])
moredata='message decoded'
if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7:
moredata = "message partially decoded" moredata = "message partially decoded"
else:
moredata = 'message decoded'
if self.show_message_decoded: if self.show_message_decoded:
logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData())) logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData()))
if self.outyaml: if self.outyaml:
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" % ( self.outyaml.write("\n%s:\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, Reference,
sequenceid, sequencenum,
datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"),
list_host[src], list_host[src],
list_host[dst], list_host[dst],
@ -459,7 +568,99 @@ class SpyPcap():
)) ))
for key in msgin.extractAllData(): for key in msgin.extractAllData():
self.outyaml.write(" - %s\n" % key) self.outyaml.write(" - %s\n" % key)
if actions_servers:
self.outyaml.write("\nblock_%s_%d:\n" %(list_host[src], sequenceid))
id = 0
for action in actions_servers:
params = action.get_parameter()
self.outyaml.write(" %s:\n" % (action.get_name()))
# if "parent" in params:
# self.outyaml.write(" parent: %s\n" % (params['parent']))
# elif "Reference" in params:
# #self.outyaml.write(" parents: %s\n" % (', '.join(params['Reference'])))
# self.outyaml.write(" parents:\n")
# for key in params['Reference']:
# self.outyaml.write(" - %s\n" % (key))
# else:
# self.outyaml.write(" parent: udp_%s\n" % (sequenceid))
self.outyaml.write(" receivedby: client\n")
self.outyaml.write(" sequence: %s\n" % (sequencenum))
self.outyaml.write(" source: %s\n" % (list_host[src]))
self.outyaml.write(" destination: %s\n" % (list_host[dst]))
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
if inpulses_servers:
self.outyaml.write("\ninpulseserver_%s_%d:\n" %(list_host[src], sequenceid))
id = 0
#print("-"*30)
#print(inpulses_servers)
for inpulse in inpulses_servers:
#print("-"*80)
#print(inpulse)
params = inpulse.get_parameter()
self.outyaml.write(" %s:\n" % (inpulse.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 actions_clients:
self.outyaml.write("\nblock_%s_%d:\n" %(list_host[src], sequenceid))
id = 0
for action in actions_clients:
self.outyaml.write(" %s:\n" % (action.get_name()))
self.outyaml.write(" receivedby: server\n")
self.outyaml.write(" sequence: %s\n" % (sequencenum))
self.outyaml.write(" source: %s\n" % (list_host[src]))
self.outyaml.write(" destination: %s\n" % (list_host[dst]))
params = action.get_parameter()
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))
else:
self.outyaml.write(" %s: %s\n" % (key, params[key]))
#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))
# id = 0
# for inpulse in inpulses_clients:
# params = inpulse.get_parameter()
# self.outyaml.write(" %s:\n" % (inpulse.get_name()))
# id += 1
sequenceid += 1 sequenceid += 1
sequencenum += 1
for client in self.client_state: for client in self.client_state:
logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber'])) logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber']))
@ -470,13 +671,14 @@ def main():
logger = [] logger = []
logger.append(logging.getLogger(LOGGER)) logger.append(logging.getLogger(LOGGER))
logger.append(logging.getLogger(CImpulseDecoder.LOGGER)) # logger.append(logging.getLogger(CImpulseDecoder.LOGGER))
#logger.append(logging.getLogger(DecodeImpuls.LOGGER)) # #logger.append(logging.getLogger(DecodeImpuls.LOGGER))
# #logger.append(logging.getLogger(BitStream.LOGGER))
# logger.append(logging.getLogger(CStringManager.LOGGER))
# logger.append(logging.getLogger(CAction.LOGGER))
# logger.append(logging.getLogger(CActionFactory.LOGGER))
# logger.append(logging.getLogger(BitStream.LOGGER)) # logger.append(logging.getLogger(BitStream.LOGGER))
logger.append(logging.getLogger(CStringManager.LOGGER)) logger.append(logging.getLogger(Impulse.LOGGER))
logger.append(logging.getLogger(CAction.LOGGER))
logger.append(logging.getLogger(CActionFactory.LOGGER))
logger.append(logging.getLogger(BitStream.LOGGER))
CImpulseDecoder CImpulseDecoder
# logger.append(logging.getLogger('CGenericMultiPartTemp')) # logger.append(logging.getLogger('CGenericMultiPartTemp'))

View file

@ -23,6 +23,7 @@ from ctypes import *
import sys import sys
import inspect import inspect
import copy import copy
import struct
LOGGER='BitStream' LOGGER='BitStream'

View file

@ -22,6 +22,7 @@
import logging import logging
from tools import TPropIndex from tools import TPropIndex
from tools import TPVPMode from tools import TPVPMode
from tools import Enum
LOGGER='CActionFactory' LOGGER='CActionFactory'
INVALID_SLOT = 0xff INVALID_SLOT = 0xff
@ -35,9 +36,23 @@ class CAction:
self.Timeout = 0 self.Timeout = 0
self.GameCycle = 0 self.GameCycle = 0
self.world = world self.world = world
self.Reference = []
self.Name = ""
def set_name(self, name):
self.Name = name
def get_name(self):
return self.Name
def add_reference(self, ref):
self.Reference.append(ref)
def get_reference(self):
return self.Reference
def get_parameter(self): def get_parameter(self):
return {"Type": "CAction", "Code": self.Code, "Slot": self.Slot, "PropertyCode": self.PropertyCode, "GameCycle": self.GameCycle} return {"Type": "CAction", "Code": self.Code, "Slot": self.Slot, "PropertyCode": self.PropertyCode, "GameCycle": self.GameCycle, "Reference": self.Reference}
def unpack(self, message): def unpack(self, message):
raise RuntimeError raise RuntimeError
@ -216,7 +231,11 @@ class CActionGeneric(CAction):
def get_parameter(self): def get_parameter(self):
ret = super().get_parameter() ret = super().get_parameter()
ret["Type"] = "CActionGeneric" ret["Type"] = "CActionGeneric"
ret["Message"] = self._Message.showAllData() if not self._Message.checkOnlyZeroAtEnd():
ret["state"] = "message partially decoded"
else:
ret["state"] = 'message decoded'
ret["Message"] = self._Message.extractAllData()
return ret return ret
def set(self, message): def set(self, message):
@ -239,6 +258,11 @@ class CActionGeneric(CAction):
decodeImpulse.execute(self._Message, world) decodeImpulse.execute(self._Message, world)
self.decoded = True self.decoded = True
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
ret = decodeImpulseSimple.execute(self._Message, world, Reference, Name)
self.decoded = True
return ret
def __str__(self): def __str__(self):
if self.decoded: if self.decoded:
return "CActionGeneric" + super().__str__() + ' => ' + self._Message.showAllData() return "CActionGeneric" + super().__str__() + ' => ' + self._Message.showAllData()
@ -265,6 +289,7 @@ class CActionGenericMultiPart(CAction):
def get_parameter(self): def get_parameter(self):
ret = super().get_parameter() ret = super().get_parameter()
ret["Name"] = self.Name
ret["Type"] = "CActionGenericMultiPart" ret["Type"] = "CActionGenericMultiPart"
ret["Number"] = "%d" % self.Number ret["Number"] = "%d" % self.Number
ret["Part"] = "%d" % self.Part ret["Part"] = "%d" % self.Part
@ -315,13 +340,21 @@ class CActionGenericMultiPart(CAction):
self.Part = 0 self.Part = 0
self.NbBlock = 0 self.NbBlock = 0
def genericAction(self, decodeImpulse, world, cGenericMultiPartTemp): def genericAction(self, decodeImpulse, world, cGenericMultiPartTemp, Reference, Name):
''' '''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::genericAction (CActionGenericMultiPart *agmp) khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::genericAction (CActionGenericMultiPart *agmp)
''' '''
logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock)) logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
cGenericMultiPartTemp.addGenericMultiPartTemp(self.Number) cGenericMultiPartTemp.addGenericMultiPartTemp(self.Number)
cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulse, world) cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulse, world, Reference, Name)
def decodeImpulseSimple(self, decodeImpulseSimple, world, cGenericMultiPartTemp, Reference = None, Name = ""):
logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
cGenericMultiPartTemp.addGenericMultiPartTemp(self.Number)
ret = cGenericMultiPartTemp.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont, decodeImpulseSimple, world, Reference, Name)
#ret = decodeImpulseSimple.execute(self._Message, world)
self.decoded = True
return ret
def __str__(self): def __str__(self):
return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',read:' + self.PartCont.showAllData() + ',write:' + self.PartCont.showAllDataWrite() + ']' return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',read:' + self.PartCont.showAllData() + ',write:' + self.PartCont.showAllDataWrite() + ']'
@ -445,3 +478,27 @@ class CActionBlock:
def __str__(self): def __str__(self):
return "CActionBlock [Cycle:" + str(self.Cycle) + ', FirstPacket:' + str(self.FirstPacket) + ', Data:' + ', '.join([ str(x) for x in self.Actions]) + "]" return "CActionBlock [Cycle:" + str(self.Cycle) + ', FirstPacket:' + str(self.FirstPacket) + ', Data:' + ', '.join([ str(x) for x in self.Actions]) + "]"
class CActionFake():
def __init__(self, Type, msgin, addon = None, Reference=None, Name=""):
self.Type = Type
self.Code = Enum.TActionCode.ACTION_NONE
self._Message = msgin
self.addon = addon
self.Reference = [ Reference ]
self.Name = Name
def get_name(self):
return self.Name
def get_parameter(self):
ret = {"Type": "CActionFake.%s" % self.Type}
if not self._Message.checkOnlyZeroAtEnd():
ret["state"] = "message partially decoded"
else:
ret["state"] = 'message decoded'
if self.addon:
for key in self.addon:
ret[key] = str(self.addon[key])
ret["Reference"] = self.Reference
ret["Message"] = self._Message.extractAllData()
return ret

View file

@ -91,7 +91,7 @@ class CActionFactory:
action.Slot = slot action.Slot = slot
return action return action
def unpack(self, msgin): def unpack(self, msgin, Reference = None, Name = None):
''' '''
khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ ) khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ )
''' '''
@ -113,6 +113,10 @@ class CActionFactory:
else: else:
log = logging.getLogger('myLogger') log = logging.getLogger('myLogger')
log.warning('Unpacking an action with unknown code, skip it (%u)' % code) log.warning('Unpacking an action with unknown code, skip it (%u)' % code)
if Reference:
action.add_reference(Reference)
if Name:
action.set_name(Name)
return action return action

View file

@ -32,12 +32,19 @@ class CGenericMultiPartTemp():
self.BlockReceived = [] self.BlockReceived = []
self.MsgDecoded = None self.MsgDecoded = None
self.FirstRead = False self.FirstRead = False
self.Reference = []
self.Name = None
def set(self, Number, Part, NbBlock, PartCont, decodeImpulse, world): def set(self, Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference = None, Name = None):
''' '''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::CGenericMultiPartTemp::set (CActionGenericMultiPart *agmp, CNetworkConnection *parent) khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::CGenericMultiPartTemp::set (CActionGenericMultiPart *agmp, CNetworkConnection *parent)
''' '''
logging.getLogger(LOGGER).debug("set Number:%d Part:%d NbBlock:%d" % (Number, Part, NbBlock)) logging.getLogger(LOGGER).debug("set Number:%d Part:%d NbBlock:%d" % (Number, Part, NbBlock))
ret = None
if not self.Name:
self.Name = Name
if Reference:
self.Reference.append(Reference)
if self.NbBlock == 0xFFFFFFFF: if self.NbBlock == 0xFFFFFFFF:
# Initialize # Initialize
self.NbBlock = NbBlock self.NbBlock = NbBlock
@ -49,7 +56,7 @@ class CGenericMultiPartTemp():
while len(self.BlockReceived) < NbBlock: while len(self.BlockReceived) < NbBlock:
self.BlockReceived.append(False) self.BlockReceived.append(False)
if self.BlockReceived[Part]: if self.BlockReceived[Part]:
logging.getLogger(LOGGER).warning('This part is already received, discard it %d' % Part) logging.getLogger(LOGGER).debug('This part is already received, discard it %d' % Part)
return return
self.Temp[Part] = PartCont self.Temp[Part] = PartCont
self.BlockReceived[Part] = True self.BlockReceived[Part] = True
@ -64,11 +71,12 @@ class CGenericMultiPartTemp():
self.NbBlock == 0xFFFFFFFF self.NbBlock == 0xFFFFFFFF
for data in self.Temp: for data in self.Temp:
bms.pushBitStream(data) bms.pushBitStream(data)
decodeImpulse.execute(bms, world) ret = decodeImpulse.execute(bms, world)
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : data : %s" % bms.showAllData()) logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : data : %s" % bms.showAllData())
self.MsgDecoded = bms self.MsgDecoded = bms
else: else:
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : Wait other block") logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : Wait other block")
return ret
def isAvailable(self): def isAvailable(self):
if self.MsgDecoded and not self.FirstRead: if self.MsgDecoded and not self.FirstRead:
@ -87,5 +95,5 @@ class GenericMultiPartTemp():
def addGenericMultiPartTemp(self, Number): def addGenericMultiPartTemp(self, Number):
self.data.setdefault(Number, CGenericMultiPartTemp()) self.data.setdefault(Number, CGenericMultiPartTemp())
def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont, decodeImpulse, world): def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference = None, Name = None):
self.data[Number].set(Number, Part, NbBlock, PartCont, decodeImpulse, world) self.data[Number].set(Number, Part, NbBlock, PartCont, decodeImpulse, world, Reference, Name)

View file

@ -38,7 +38,7 @@ class CImpulseDecoder:
def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket): def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket):
''' '''
khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp:38 oid CImpulseDecoder::decode(CBitMemStream &inbox, TPacketNumber receivedPacket, TPacketNumber receivedAck, TPacketNumber nextSentPacket, vector<CLFECOMMON::CAction *> &actions) 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)
''' '''
logging.getLogger(LOGGER).debug("*" * 80) logging.getLogger(LOGGER).debug("*" * 80)
logging.getLogger(LOGGER).debug("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket)) logging.getLogger(LOGGER).debug("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket))

View file

@ -351,6 +351,11 @@ class DecodeImpulse():
def impulseDatabaseInitPlayer(self, msgin, world): def impulseDatabaseInitPlayer(self, msgin, world):
logging.getLogger(LOGGER).debug("TODO") logging.getLogger(LOGGER).debug("TODO")
def impulseSetConnectionAskName(self, msgin, world):
# _ = msgin.readUtf8String('Name')
_ = msgin.readUString('Name')
_ = msgin.readUint32('HomeSessionId')
def initializeNetwork(self): def initializeNetwork(self):
self.GenericMsgHeaderMngr.setdefault('DB_UPD_PLR', self.impulseDatabaseUpdatePlayer) self.GenericMsgHeaderMngr.setdefault('DB_UPD_PLR', self.impulseDatabaseUpdatePlayer)
self.GenericMsgHeaderMngr.setdefault('DB_INIT:PLR', self.impulseDatabaseInitPlayer) self.GenericMsgHeaderMngr.setdefault('DB_INIT:PLR', self.impulseDatabaseInitPlayer)
@ -493,6 +498,9 @@ class DecodeImpulse():
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SVR_EVENT_MIS_AVL", self.impulseServerEventForMissionAvailability ) self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SVR_EVENT_MIS_AVL", self.impulseServerEventForMissionAvailability )
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_TIMER", self.impulseSetNpcIconTimer ) self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_TIMER", self.impulseSetNpcIconTimer )
# Send by client
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:ASK_NAME", self.impulseSetConnectionAskName )
def sizeElement(self, keys = None): def sizeElement(self, keys = None):
head = self.msgXml head = self.msgXml
if not keys: if not keys:
@ -540,6 +548,7 @@ class DecodeImpulse():
nbBit = getPowerOf2.getPowerOf2(len(head)) nbBit = getPowerOf2.getPowerOf2(len(head))
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True) id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
logging.getLogger(LOGGER).debug("XML DECODE : %3d -> %s" % (nbBit, ':'.join(listpath)) )
ele = head[id] ele = head[id]
name = ele.attrib['name'] name = ele.attrib['name']
listpath.append(name) listpath.append(name)

View file

@ -539,6 +539,8 @@ class TActionCode(IntEnum):
ACTION_LOGIN_CODE = 13 ACTION_LOGIN_CODE = 13
ACTION_TARGET_SLOT_CODE = 40 ACTION_TARGET_SLOT_CODE = 40
ACTION_DUMMY_CODE = 99 ACTION_DUMMY_CODE = 99
ACTION_NONE = 999
class Card(IntEnum): class Card(IntEnum):
BEGIN_TOKEN = 0 BEGIN_TOKEN = 0
@ -550,6 +552,7 @@ class Card(IntEnum):
FLAG_TOKEN = 6 FLAG_TOKEN = 6
EXTEND_TOKEN = 7 EXTEND_TOKEN = 7
class TType(IntEnum): class TType(IntEnum):
STRUCT_BEGIN = 0 STRUCT_BEGIN = 0
STRUCT_END = 1 STRUCT_END = 1
@ -563,3 +566,14 @@ class TType(IntEnum):
FLOAT64 = 9 FLOAT64 = 9
EXTEND_TYPE = 10 EXTEND_TYPE = 10
NB_TYPE = 11 NB_TYPE = 11
class NPC_ICON(IntEnum): # TNPCMissionGiverState
AwaitingFirstData = 0
NotAMissionGiver = 1
ListHasOutOfReachMissions = 2
ListHasAlreadyTakenMissions = 3
ListHasAvailableMission = 4
AutoHasUnavailableMissions = 5
AutoHasAvailableMission = 6
NbMissionGiverStates = 7

455
tools/Impulse.py Normal file
View file

@ -0,0 +1,455 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# module Impulse
#
# Copyright (C) 2019 AleaJactaEst
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from tools import getPowerOf2
from tools import BitStream
# from tools import Enum
LOGGER='Impulse'
class ImpulseNoElement(Exception):
pass
class ImpulseBase:
def __init__(self):
self.name = ""
self.id = ""
self.param = {}
#self.Reference = []
def set_name(self, name):
self.name = name.replace(':', '_')
def get_name(self):
return self.name
def add_reference(self, ref):
#self.Reference.append(ref)
self.param.setdefault('Reference', [])
self.param['Reference'].append(ref)
def get_reference(self):
return self.param['Reference']
def get_parameter(self):
return self.param
def add_parameter(self, key, value):
self.param.setdefault(key, [])
self.param[key].append(value)
def add_value(self, key, value):
self.param.setdefault(key, "")
self.param[key] = value
def read(self, name, msgin, world):
logging.getLogger(LOGGER).error("Not define")
class ImpulseBotchatSetFilters(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('qualityMin', msgin.readUint32('qualityMin'))
self.param.setdefault('qualityMax', msgin.readUint32('qualityMax'))
self.param.setdefault('priceMin', msgin.readUint32('priceMin'))
self.param.setdefault('priceMax', msgin.readUint32('priceMax'))
self.param.setdefault('classMin', msgin.readUint8('classMin'))
self.param.setdefault('classMax', msgin.readUint8('classMax'))
self.param.setdefault('itemPart', msgin.readUint8('itemPart'))
self.param.setdefault('itemType', msgin.readUint8('itemType'))
class ImpulseConnectionAskName(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('Name', msgin.readUString('Name'))
self.param.setdefault('HomeSessionId', msgin.readUint32('HomeSessionId'))
class ImpulseConnectionCreateChar(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('Slot', msgin.readUint8('Slot'))
self.param.setdefault('SheetId', msgin.readUint32('SheetId'))
self.param.setdefault('CSessionId', msgin.readUint32('CSessionId'))
self.param.setdefault('name', msgin.readUString('name'))
self.param.setdefault('People', msgin.readUint8('People'))
self.param.setdefault('Sex', msgin.readUint8('Sex'))
self.param.setdefault('NbPointFighter', msgin.readUint8('NbPointFighter'))
self.param.setdefault('NbPointCaster', msgin.readUint8('NbPointCaster'))
self.param.setdefault('NbPointCrafter', msgin.readUint8('NbPointCrafter'))
self.param.setdefault('NbPointHarvester', msgin.readUint8('NbPointHarvester'))
self.param.setdefault('StartPoint', msgin.readSint32('StartPoint'))
self.param.setdefault('HairType', msgin.readSint8('HairType'))
self.param.setdefault('HairColor', msgin.readSint8('HairColor'))
self.param.setdefault('GabaritHeight', msgin.readSint8('GabaritHeight'))
self.param.setdefault('GabaritTorsoWidth', msgin.readSint8('GabaritTorsoWidth'))
self.param.setdefault('GabaritArmsWidth', msgin.readSint8('GabaritArmsWidth'))
self.param.setdefault('GabaritLegsWidth', msgin.readSint8('GabaritLegsWidth'))
self.param.setdefault('GabaritBreastSize', msgin.readSint8('GabaritBreastSize'))
self.param.setdefault('MorphTarget1', msgin.readSint8('MorphTarget1'))
self.param.setdefault('MorphTarget2', msgin.readSint8('MorphTarget2'))
self.param.setdefault('MorphTarget3', msgin.readSint8('MorphTarget3'))
self.param.setdefault('MorphTarget4', msgin.readSint8('MorphTarget4'))
self.param.setdefault('MorphTarget5', msgin.readSint8('MorphTarget5'))
self.param.setdefault('MorphTarget6', msgin.readSint8('MorphTarget6'))
self.param.setdefault('MorphTarget7', msgin.readSint8('MorphTarget7'))
self.param.setdefault('MorphTarget8', msgin.readSint8('MorphTarget8'))
self.param.setdefault('EyesColor', msgin.readSint8('EyesColor'))
self.param.setdefault('Tattoo', msgin.readSint8('Tattoo'))
self.param.setdefault('JacketColor', msgin.readSint8('JacketColor'))
self.param.setdefault('TrousersColor', msgin.readSint8('TrousersColor'))
self.param.setdefault('HatColor', msgin.readSint8('HatColor'))
self.param.setdefault('ArmsColor', msgin.readSint8('ArmsColor'))
self.param.setdefault('HandsColor', msgin.readSint8('HandsColor'))
self.param.setdefault('FeetColor', msgin.readSint8('FeetColor'))
class ImpulseConnectionReady(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('LanguageCode', msgin.readString('LanguageCode'))
class ImpulseConnectionSelectChar(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('SelectCharMsg', msgin.readUint8('SelectCharMsg'))
class ImpulseConnectionUserChar(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('X', msgin.readSint32('X'))
self.param.setdefault('Y', msgin.readSint32('Y'))
self.param.setdefault('Z', msgin.readSint32('Z'))
self.param.setdefault('Heading', msgin.readFloat('Heading'))
self.param.setdefault('season', msgin.readSerial(3, 'season'))
self.param.setdefault('userRole', msgin.readSerial(3, 'userRole'))
self.param.setdefault('highestMainlandSessionId', msgin.readUint32('highestMainlandSessionId'))
self.param.setdefault('firstConnectedTime', msgin.readUint32('firstConnectedTime'))
self.param.setdefault('playedTime', msgin.readUint32('playedTime'))
class ImpulseConnectionShardId(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('shardId', msgin.readUint32('shardId'))
self.param.setdefault('webHost', msgin.readString('webHost'))
class ImpulseConnectionValidName(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('valide', msgin.readUint8('valide'))
class ImpulseDebugPing(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('localTime', msgin.readUint32('localTime'))
class ImpulseGuildFemaleTitles(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('UseFemaleTitles', msgin.readSerial(1, 'UseFemaleTitles'))
class ImpulseNpsIconSetDesc(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:20976 void CCharacter::sendNpcMissionGiverIconDesc( const std::vector<uint32>& npcKeys )
'''
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('nb8', msgin.readUint8('nb8'))
nb8 = self.param['nb8']
for i in range(0, nb8):
self.param.setdefault('%d:npcAlias' % nb8, msgin.readUint32('npcAlias'))
self.param.setdefault('%d:state' % nb8, msgin.readUint32('state'))
class ImpulsePhraseDownload(ImpulseBase):
def __init__(self):
super().__init__()
def readSerialPhrase(self, msgin, id):
self.param.setdefault(id, msgin.readUtf8String(id))
size = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
for i in range(0, size):
self.param.setdefault('%s:compBricks:%d' % (id, i), msgin.readUint16('%s:compBricks:%d' % (id, i)))
def readSerialPhrases(self, msgin, id):
"""
khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:13586 void CCharacter::sendPhrasesToClient()
khanat-opennel-code/code/nel/include/nel/misc/stream.h:1089 void serialVector(T &cont)
khanat-opennel-code/code/ryzom/common/src/game_share/sphrase_com.cpp:57 void CSPhraseCom::serial(NLMISC::IStream &impulse)
"""
size = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
for i in range(0, size):
#self.param.setdefault('%d:Phrase' % i, msgin.readUtf8String('%d:Phrase:Name' % i))
#self.param.setdefault('%d:Phrase' % i, msgin.readString('%d:Phrase' % i))
self.readSerialPhrase(msgin, '%d:Phrase' % i)
self.param.setdefault('%d:KnownSlot' % i, msgin.readUint16('%d:KnownSlot' % i))
self.param.setdefault('%d:PhraseSheetId:id' % i, msgin.readUint32('%d:PhraseSheetId:id' % i))
self.param.setdefault('%d:PhraseSheetId:Type' % i, msgin.readUint32('%d:PhraseSheetId:IdInfos:Type' % i))
self.param.setdefault('%d:PhraseSheetId:Type' % i, msgin.readUint32('%d:PhraseSheetId:IdInfos:Id' % i))
def readSerialMemorizedPhrases(self, msgin, id):
size = msgin.readSint32(id + ':len')
self.param.setdefault(id + ':len', size)
for i in range(0, size):
self.param.setdefault('%d:MemoryLineId' % i, msgin.readUint8('MemoryLineId'))
self.param.setdefault('%d:MemorySlotId' % i, msgin.readUint8('MemorySlotId'))
self.param.setdefault('%d:PhraseId' % i, msgin.readUint16('PhraseId'))
def read(self, name, msgin, world):
"""
khanat-opennel-code/code/ryzom/server/src/entities_game_service/player_manager/character.cpp:13586 void CCharacter::sendPhrasesToClient()
"""
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
return
#self.param.setdefault(id + 'phrases', msgin.readString('phrases'))
#self.param.setdefault(id + 'memorizedPhrases', msgin.readString('memorizedPhrases'))
self.readSerialPhrases(msgin, 'knownPhrases')
self.readSerialMemorizedPhrases(msgin, 'memorizedPhrases')
logging.getLogger(LOGGER).error("[Client -> Server] msg:%s" % msgin.showAllData())
raise ValueError
class ImpulsePosition(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('X', msgin.readSint32('X'))
self.param.setdefault('Y', msgin.readSint32('Y'))
self.param.setdefault('Z', msgin.readSint32('Z'))
self.param.setdefault('Heading', msgin.readFloat('Heading'))
class ImpulseSringDynString(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('phraseId', msgin.readUint32('phraseId'))
class ImpulseSringManagerReloadCache(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('timestamp', msgin.readUint32('timestamp'))
class ImpulseSringManagerPhraseSend(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('dynId', msgin.readUint32('dynId'))
self.param.setdefault('StringId', msgin.readUint32('StringId'))
try:
id = 0
while True:
self.param.setdefault('StringId:%d' % id, msgin.readUint32('StringId'))
id += 1
except:
pass
class ImpulseSringManagerStringResp(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('stringId', msgin.readUint32('stringId'))
self.param.setdefault('strUtf8', msgin.readUtf8String('strUtf8'))
class ImpulseSringManagerStringRq(ImpulseBase):
def __init__(self):
super().__init__()
def read(self, name, msgin, world):
logging.getLogger(LOGGER).debug("read")
self.name = name.replace(':', '_')
self.param.setdefault('stringId', msgin.readUint32('stringId'))
class DecodeImpulseSimple:
def __init__(self):
'''
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork()
'''
self.msgXml = None
self.databaseXml = None
self.GenericMsgHeaderMngr = {}
self.initializeNetwork()
def initializeNetwork(self):
# Send by client
self.GenericMsgHeaderMngr.setdefault( "BOTCHAT:SET_FILTERS", ImpulseBotchatSetFilters )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:ASK_NAME", ImpulseConnectionAskName )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:CREATE_CHAR", ImpulseConnectionCreateChar )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:READY", ImpulseConnectionReady )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:SELECT_CHAR", ImpulseConnectionSelectChar )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:SHARD_ID", ImpulseConnectionShardId )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:USER_CHAR", ImpulseConnectionUserChar )
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:VALID_NAME", ImpulseConnectionValidName )
self.GenericMsgHeaderMngr.setdefault( "DEBUG:PING", ImpulseDebugPing )
self.GenericMsgHeaderMngr.setdefault( "GUILD:USE_FEMALE_TITLES", ImpulseGuildFemaleTitles )
self.GenericMsgHeaderMngr.setdefault( "NPC_ICON:SET_DESC", ImpulseNpsIconSetDesc )
self.GenericMsgHeaderMngr.setdefault( "PHRASE:DOWNLOAD", ImpulsePhraseDownload )
self.GenericMsgHeaderMngr.setdefault( "POSITION", ImpulsePosition )
self.GenericMsgHeaderMngr.setdefault( "STRING:DYN_STRING", ImpulseSringDynString )
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:RELOAD_CACHE", ImpulseSringManagerReloadCache )
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:PHRASE_SEND", ImpulseSringManagerPhraseSend )
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:STRING_RESP", ImpulseSringManagerStringResp )
self.GenericMsgHeaderMngr.setdefault( "STRING_MANAGER:STRING_RQ", ImpulseSringManagerStringRq )
def execute(self, msgin, world, references = [], name=""):
'''
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp:3746 void impulseCallBack(NLMISC::CBitMemStream &impulse, sint32 packet, void *arg)
khanat-opennel-code/code/ryzom/common/src/game_share/generic_xml_msg_mngr.cpp:121 void CGenericXmlMsgHeaderManager::execute(CBitMemStream &strm)
khanat-opennel-code/code/ryzom/common/src/game_share/generic_xml_msg_mngr.h:431 CNode *select(NLMISC::CBitMemStream &strm)
uint32 index = 0;
q uint NbBits;
strm.serialAndLog2(index, node->NbBits);
'''
logging.getLogger(LOGGER).debug("execute")
head = self.msgXml
listpath = []
while True:
nbBit = getPowerOf2.getPowerOf2(len(head))
#logging.getLogger(LOGGER).error("nbBit : %d " % nbBit)
#for child in head:
# print(child.tag, child.attrib)
try:
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
except BitStream.OverflowError:
raise ImpulseNoElement
if id is None:
raise ImpulseNoElement
try:
ele = head[id]
except IndexError as e:
logging.getLogger(LOGGER).error("Error to decode message: %s" % msgin.showAllData() )
raise e
command = ele.attrib['name']
listpath.append(command)
fullname = ':'.join(listpath)
id = msgin.readSerial(nbBit, name='MsgXML', typeName='XML <' + command + '>')
if fullname in self.GenericMsgHeaderMngr:
logging.getLogger(LOGGER).debug("Found : %s" % fullname)
impulse = self.GenericMsgHeaderMngr[fullname]()
impulse.read(fullname, msgin, world)
logging.getLogger(LOGGER).debug("MessageXML decoded: %s" % msgin.showAllData() )
impulse.add_value("command", fullname)
for reference in references:
impulse.add_reference(reference)
impulse.add_value("Message", msgin.extractAllData())
return impulse
else:
#logging.getLogger(LOGGER).debug("Non trouve")
for ele in head:
if ele.attrib['name'] == command:
head = ele
break
if head != ele:
logging.getLogger(LOGGER).error("Impossible to found %s" % fullname )
logging.getLogger(LOGGER).debug("MessageXML decoded: %s" % msgin.showAllData() )
return None
# End While
logging.getLogger(LOGGER).debug("MessageXML decoded: %s" % msgin.showAllData() )
return None
def loadMsg(self, msgXml):
logging.getLogger(LOGGER).debug("msgXml")
self.msgXml = msgXml
def loadDatabase(self, databaseXml):
self.databaseXml = databaseXml