mirror of
https://port.numenaute.org/aleajactaest/clientbot.git
synced 2024-09-08 00:47:17 +00:00
update spykhanat.py (it can generate yaml file with detail message decoded)
This commit is contained in:
parent
390c448bde
commit
5c506cfa32
11 changed files with 807 additions and 52 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
*.pcap
|
||||
*.yaml
|
||||
*.yml
|
||||
*.log
|
||||
*.err
|
|
@ -117,7 +117,7 @@ class ClientKhanat:
|
|||
'Referer': 'http://' + self.khanat_host+':'+ str(self.khanat_port_login) + '/ams/index.php?page=register',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
'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'}
|
||||
params = urllib.parse.urlencode({'Username': self.login, 'Password': self.password, 'ConfirmPass': self.password, 'Email': self.login+'@khaganat.net', 'TaC': 'on', 'function': 'add_user'})
|
||||
|
|
282
spykhanat.py
282
spykhanat.py
|
@ -22,6 +22,9 @@
|
|||
# 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
|
||||
|
||||
# install pcapfile
|
||||
# pip install pypcapfile
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
from pcapfile import savefile
|
||||
|
@ -39,8 +42,9 @@ from tools import DecodeImpulse
|
|||
from tools import World
|
||||
from tools import CGenericMultiPartTemp
|
||||
from tools import CImpulseDecoder
|
||||
from tools import CStringManager
|
||||
#from tools import CStringManager
|
||||
from tools import CAction
|
||||
from tools import Impulse
|
||||
import xml.etree.ElementTree as ET
|
||||
from datetime import datetime
|
||||
|
||||
|
@ -56,6 +60,14 @@ LOGGER = 'SpyKhanat'
|
|||
#ip_packet = ip.IP(binascii.unhexlify(eth_frame.payload))
|
||||
#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():
|
||||
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:
|
||||
|
@ -73,11 +85,13 @@ class SpyPcap():
|
|||
self.actionFactory = CActionFactory.CActionFactory(None)
|
||||
self.client_state = {}
|
||||
self.decodeImpulse = DecodeImpulse.DecodeImpulse()
|
||||
self.decodeImpulseSimple = Impulse.DecodeImpulseSimple()
|
||||
|
||||
fp = open(msg_xml , 'rt')
|
||||
msgRawXml = fp.read()
|
||||
self.msgXml = ET.fromstring(msgRawXml)
|
||||
self.decodeImpulse.loadMsg(self.msgXml)
|
||||
self.decodeImpulseSimple.loadMsg(self.msgXml)
|
||||
self.outyaml = outyaml
|
||||
|
||||
def readRaw(self):
|
||||
|
@ -156,7 +170,8 @@ class SpyPcap():
|
|||
'AckBitMask': 0,
|
||||
'RegisteredAction': {},
|
||||
'world': World.World(),
|
||||
'GenericMultiPartTemp': CGenericMultiPartTemp.GenericMultiPartTemp(),
|
||||
'GenericMultiPartTempServer': CGenericMultiPartTemp.GenericMultiPartTemp(),
|
||||
'GenericMultiPartTempClient': CGenericMultiPartTemp.GenericMultiPartTemp(),
|
||||
'CImpulseDecoder': None,
|
||||
'CActionFactory': None,
|
||||
'LastAck0': [-1],
|
||||
|
@ -211,18 +226,14 @@ class SpyPcap():
|
|||
self.add_registered_action(clientid, action)
|
||||
return actions
|
||||
|
||||
# def decode_client_receive_normal_message(self, msgin, clientid, dst):
|
||||
# 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):
|
||||
def decode_client_send_normal_message(self, msgin, clientid, dst, sequenceid, name, Reference):
|
||||
'''
|
||||
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)
|
||||
'''
|
||||
#actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] )
|
||||
actions = []
|
||||
impulses = []
|
||||
noerror = True
|
||||
msgin.disable_LogErrorOnStreamOverflow()
|
||||
while noerror:
|
||||
|
@ -231,7 +242,7 @@ class SpyPcap():
|
|||
num = msgin.readUint8("num")
|
||||
logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, 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
|
||||
except BitStream.OverflowError:
|
||||
noerror = False
|
||||
|
@ -240,24 +251,33 @@ class SpyPcap():
|
|||
raise e
|
||||
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])))
|
||||
# decodeVisualProperties( msgin );
|
||||
if self.outyaml and actions:
|
||||
self.outyaml.write("\nblock_%s_udp_%d:\n" %(name, sequenceid))
|
||||
id = 0
|
||||
for action in actions:
|
||||
self.outyaml.write(" action_%s_udp_%d_%d:\n" %(name, sequenceid, id))
|
||||
params = action.get_parameter()
|
||||
for key in params:
|
||||
self.outyaml.write(" %s: %s\n" % (key, params[key]))
|
||||
id += 1
|
||||
return actions, impulses
|
||||
|
||||
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')
|
||||
SystemMode = msgin.readBool('SystemMode')
|
||||
logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst))
|
||||
self.initialize_client(clientid)
|
||||
self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber
|
||||
actions = []
|
||||
impulses = []
|
||||
if not SystemMode:
|
||||
'''
|
||||
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp:2029 void CNetworkConnection::sendNormalMessage()
|
||||
|
@ -267,8 +287,8 @@ class SpyPcap():
|
|||
AckBitMask = msgin.readUint32('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))
|
||||
#self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1)
|
||||
self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, name)
|
||||
# self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1)
|
||||
actions, _ = self.decode_client_send_normal_message(msgin, clientid, dst, sequenceid, "%s_%d" % (target, 0), Parent)
|
||||
else:
|
||||
message = msgin.readUint8('message')
|
||||
try:
|
||||
|
@ -282,10 +302,14 @@ class SpyPcap():
|
|||
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}" %
|
||||
(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:
|
||||
LatestProbe = msgin.readSint32('LatestProbe')
|
||||
logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage,
|
||||
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:
|
||||
Synchronize = msgin.readUint32('Synchronize')
|
||||
stime = msgin.readSint64('stime')
|
||||
|
@ -296,6 +320,8 @@ class SpyPcap():
|
|||
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}" % (
|
||||
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:
|
||||
LastReceivedNumber = msgin.readSint32('LastReceivedNumber')
|
||||
LastAckInLongAck = msgin.readSint32('LastAckInLongAck')
|
||||
|
@ -304,22 +330,31 @@ class SpyPcap():
|
|||
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}" % (
|
||||
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:
|
||||
SizeLatestProbes = msgin.readSint32('SizeLatestProbes')
|
||||
LatestProbes = []
|
||||
for data in range(0, SizeLatestProbes):
|
||||
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)))
|
||||
action = CAction.CActionFake('SYSTEM_ACK_PROBE_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
|
||||
actions.append(action)
|
||||
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
|
||||
|
||||
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')
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst))
|
||||
SystemMode = msgin.readBool('SystemMode')
|
||||
self.initialize_client(dst)
|
||||
self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber
|
||||
id = 0
|
||||
if not SystemMode:
|
||||
_LastReceivedAck = msgin.readSint32('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
|
||||
logging.getLogger(LOGGER).debug('=' * 80)
|
||||
actionsbis = []
|
||||
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)
|
||||
if action.Code == Enum.TActionCode.ACTION_DISCONNECTION_CODE:
|
||||
#action.add_reference(Parent)
|
||||
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:
|
||||
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))
|
||||
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)
|
||||
for id in self.client_state[dst]['GenericMultiPartTemp'].data:
|
||||
if self.client_state[dst]['GenericMultiPartTemp'].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()))
|
||||
for id in self.client_state[dst]['GenericMultiPartTempServer'].data:
|
||||
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]['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:
|
||||
#action.add_reference(Parent)
|
||||
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)
|
||||
id += 1
|
||||
# # remove all old actions that are acked
|
||||
# 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)
|
||||
for action in actionsbis:
|
||||
actions.append(action)
|
||||
|
||||
logging.getLogger(LOGGER).info("impulses:%s" % str(impulses))
|
||||
else:
|
||||
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))
|
||||
if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE:
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize")
|
||||
|
@ -363,20 +449,30 @@ class SpyPcap():
|
|||
MsgData = msgin.readArrayUint8(16, 'MsgData')
|
||||
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)))
|
||||
action = CAction.CActionFake('SYSTEM_SYNC_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
|
||||
actions.append(action)
|
||||
elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE:
|
||||
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))
|
||||
action = CAction.CActionFake('SYSTEM_STALLED_CODE', msgin, Reference=Parent, Name = "%s_%d" % (target, 0))
|
||||
actions.append(action)
|
||||
elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE:
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] Probe")
|
||||
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))
|
||||
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:
|
||||
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:
|
||||
logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message)
|
||||
#cActionFactory = CAction.CActionFactory(None)
|
||||
#cActionFactory.unpack(msgin)
|
||||
logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData())
|
||||
#logging.getLogger(LOGGER).info("impulses:%s" % str(impulses))
|
||||
return actions, impulses
|
||||
|
||||
def read(self):
|
||||
file = open( self.pcap_file , 'rb')
|
||||
|
@ -386,6 +482,9 @@ class SpyPcap():
|
|||
serverid = 1
|
||||
list_host = {}
|
||||
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:
|
||||
eth_frame = ethernet.Ethernet(pkt.raw())
|
||||
|
@ -397,8 +496,17 @@ class SpyPcap():
|
|||
data = udp_packet.payload
|
||||
if udp_packet.src_port == 53 or udp_packet.dst_port == 53:
|
||||
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)):
|
||||
Reference = "packet_%d" % sequenceid
|
||||
logging.getLogger(LOGGER).debug("-" * 80)
|
||||
actions_clients = []
|
||||
actions_servers = []
|
||||
inpulses_servers = []
|
||||
inpulses_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"),
|
||||
|
@ -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):
|
||||
_provenance = 'Server -> Client'
|
||||
logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData()))
|
||||
self.decode_khanat_message(msgin, src, dst, sequenceid, list_host[dst])
|
||||
actions_servers, inpulses_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()))
|
||||
self.decode_client_message(msgin, src, dst, sequenceid, list_host[dst])
|
||||
moredata='message decoded'
|
||||
actions_clients, inpulses_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:
|
||||
moredata = 'message decoded'
|
||||
if self.show_message_decoded:
|
||||
logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData()))
|
||||
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" % (
|
||||
sequenceid,
|
||||
sequenceid,
|
||||
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" % (
|
||||
Reference,
|
||||
sequencenum,
|
||||
datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"),
|
||||
list_host[src],
|
||||
list_host[dst],
|
||||
|
@ -459,7 +568,99 @@ class SpyPcap():
|
|||
))
|
||||
for key in msgin.extractAllData():
|
||||
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
|
||||
sequencenum += 1
|
||||
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']))
|
||||
|
||||
|
@ -470,13 +671,14 @@ def main():
|
|||
|
||||
logger = []
|
||||
logger.append(logging.getLogger(LOGGER))
|
||||
logger.append(logging.getLogger(CImpulseDecoder.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(CImpulseDecoder.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(Impulse.LOGGER))
|
||||
CImpulseDecoder
|
||||
# logger.append(logging.getLogger('CGenericMultiPartTemp'))
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from ctypes import *
|
|||
import sys
|
||||
import inspect
|
||||
import copy
|
||||
import struct
|
||||
|
||||
LOGGER='BitStream'
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
import logging
|
||||
from tools import TPropIndex
|
||||
from tools import TPVPMode
|
||||
from tools import Enum
|
||||
|
||||
LOGGER='CActionFactory'
|
||||
INVALID_SLOT = 0xff
|
||||
|
@ -35,9 +36,23 @@ class CAction:
|
|||
self.Timeout = 0
|
||||
self.GameCycle = 0
|
||||
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):
|
||||
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):
|
||||
raise RuntimeError
|
||||
|
@ -216,7 +231,11 @@ class CActionGeneric(CAction):
|
|||
def get_parameter(self):
|
||||
ret = super().get_parameter()
|
||||
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
|
||||
|
||||
def set(self, message):
|
||||
|
@ -239,6 +258,11 @@ class CActionGeneric(CAction):
|
|||
decodeImpulse.execute(self._Message, world)
|
||||
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):
|
||||
if self.decoded:
|
||||
return "CActionGeneric" + super().__str__() + ' => ' + self._Message.showAllData()
|
||||
|
@ -265,6 +289,7 @@ class CActionGenericMultiPart(CAction):
|
|||
|
||||
def get_parameter(self):
|
||||
ret = super().get_parameter()
|
||||
ret["Name"] = self.Name
|
||||
ret["Type"] = "CActionGenericMultiPart"
|
||||
ret["Number"] = "%d" % self.Number
|
||||
ret["Part"] = "%d" % self.Part
|
||||
|
@ -315,13 +340,21 @@ class CActionGenericMultiPart(CAction):
|
|||
self.Part = 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)
|
||||
'''
|
||||
logging.getLogger(LOGGER).debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
|
||||
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):
|
||||
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):
|
||||
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
|
||||
|
|
|
@ -91,7 +91,7 @@ class CActionFactory:
|
|||
action.Slot = slot
|
||||
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 */ )
|
||||
'''
|
||||
|
@ -113,6 +113,10 @@ class CActionFactory:
|
|||
else:
|
||||
log = logging.getLogger('myLogger')
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -32,12 +32,19 @@ class CGenericMultiPartTemp():
|
|||
self.BlockReceived = []
|
||||
self.MsgDecoded = None
|
||||
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)
|
||||
'''
|
||||
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:
|
||||
# Initialize
|
||||
self.NbBlock = NbBlock
|
||||
|
@ -49,7 +56,7 @@ class CGenericMultiPartTemp():
|
|||
while len(self.BlockReceived) < NbBlock:
|
||||
self.BlockReceived.append(False)
|
||||
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
|
||||
self.Temp[Part] = PartCont
|
||||
self.BlockReceived[Part] = True
|
||||
|
@ -64,11 +71,12 @@ class CGenericMultiPartTemp():
|
|||
self.NbBlock == 0xFFFFFFFF
|
||||
for data in self.Temp:
|
||||
bms.pushBitStream(data)
|
||||
decodeImpulse.execute(bms, world)
|
||||
ret = decodeImpulse.execute(bms, world)
|
||||
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : data : %s" % bms.showAllData())
|
||||
self.MsgDecoded = bms
|
||||
else:
|
||||
logging.getLogger(LOGGER).debug("CGenericMultiPartTemp : Wait other block")
|
||||
return ret
|
||||
|
||||
def isAvailable(self):
|
||||
if self.MsgDecoded and not self.FirstRead:
|
||||
|
@ -87,5 +95,5 @@ class GenericMultiPartTemp():
|
|||
def addGenericMultiPartTemp(self, Number):
|
||||
self.data.setdefault(Number, CGenericMultiPartTemp())
|
||||
|
||||
def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont, decodeImpulse, world):
|
||||
self.data[Number].set(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, Reference, Name)
|
||||
|
|
|
@ -38,7 +38,7 @@ class CImpulseDecoder:
|
|||
|
||||
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("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket))
|
||||
|
|
|
@ -351,6 +351,11 @@ class DecodeImpulse():
|
|||
def impulseDatabaseInitPlayer(self, msgin, world):
|
||||
logging.getLogger(LOGGER).debug("TODO")
|
||||
|
||||
def impulseSetConnectionAskName(self, msgin, world):
|
||||
# _ = msgin.readUtf8String('Name')
|
||||
_ = msgin.readUString('Name')
|
||||
_ = msgin.readUint32('HomeSessionId')
|
||||
|
||||
def initializeNetwork(self):
|
||||
self.GenericMsgHeaderMngr.setdefault('DB_UPD_PLR', self.impulseDatabaseUpdatePlayer)
|
||||
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:SET_TIMER", self.impulseSetNpcIconTimer )
|
||||
|
||||
# Send by client
|
||||
self.GenericMsgHeaderMngr.setdefault( "CONNECTION:ASK_NAME", self.impulseSetConnectionAskName )
|
||||
|
||||
def sizeElement(self, keys = None):
|
||||
head = self.msgXml
|
||||
if not keys:
|
||||
|
@ -540,6 +548,7 @@ class DecodeImpulse():
|
|||
nbBit = getPowerOf2.getPowerOf2(len(head))
|
||||
id = msgin.readSerial(nbBit, name='MsgXML', typeName='Number', emulate=True)
|
||||
|
||||
logging.getLogger(LOGGER).debug("XML DECODE : %3d -> %s" % (nbBit, ':'.join(listpath)) )
|
||||
ele = head[id]
|
||||
name = ele.attrib['name']
|
||||
listpath.append(name)
|
||||
|
|
|
@ -539,6 +539,8 @@ class TActionCode(IntEnum):
|
|||
ACTION_LOGIN_CODE = 13
|
||||
ACTION_TARGET_SLOT_CODE = 40
|
||||
ACTION_DUMMY_CODE = 99
|
||||
ACTION_NONE = 999
|
||||
|
||||
|
||||
class Card(IntEnum):
|
||||
BEGIN_TOKEN = 0
|
||||
|
@ -550,6 +552,7 @@ class Card(IntEnum):
|
|||
FLAG_TOKEN = 6
|
||||
EXTEND_TOKEN = 7
|
||||
|
||||
|
||||
class TType(IntEnum):
|
||||
STRUCT_BEGIN = 0
|
||||
STRUCT_END = 1
|
||||
|
@ -563,3 +566,14 @@ class TType(IntEnum):
|
|||
FLOAT64 = 9
|
||||
EXTEND_TYPE = 10
|
||||
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
455
tools/Impulse.py
Normal 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
|
Loading…
Reference in a new issue