update decode message khanat send to client

This commit is contained in:
AleaJactaEst 2019-11-06 14:13:23 +01:00
parent b21cf254cc
commit 63efd10dad
3 changed files with 72 additions and 7 deletions

View file

@ -157,10 +157,12 @@ class SpyPcap():
'world': World.World(), 'world': World.World(),
'GenericMultiPartTemp': CGenericMultiPartTemp.GenericMultiPartTemp(), 'GenericMultiPartTemp': CGenericMultiPartTemp.GenericMultiPartTemp(),
'CImpulseDecoder': None, 'CImpulseDecoder': None,
'CActionFactory': None,
'LastAck0': [-1], 'LastAck0': [-1],
'LastAck1': [-1, -1], 'LastAck1': [-1, -1],
'LastAck2': [-1, -1, -1, -1]}) 'LastAck2': [-1, -1, -1, -1]})
self.client_state[clientid]['CImpulseDecoder'] = CImpulseDecoder.CImpulseDecoder(self.client_state[clientid]['world']) self.client_state[clientid]['CImpulseDecoder'] = CImpulseDecoder.CImpulseDecoder(self.client_state[clientid]['world'])
self.client_state[clientid]['CActionFactory'] = CActionFactory.CActionFactory(self.client_state[clientid]['world'])
def add_registered_action(self, clientid, action): def add_registered_action(self, clientid, action):
self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, []) self.client_state[clientid]['RegisteredAction'].setdefault(action.Code, [])
@ -208,11 +210,37 @@ 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_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'] ) # 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 -> Khanat] actions:%s" % str(actions)) # logging.getLogger(LOGGER).info("[Client -> Khanat] actions:%s" % str(actions))
# decodeVisualProperties( msgin ); # # decodeVisualProperties( msgin );
def decode_client_send_normal_message(self, msgin, clientid, dst):
'''
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 = []
noerror = True
msgin.disable_LogErrorOnStreamOverflow()
while noerror:
try:
cycle = msgin.readUint32("Cycle")
num = msgin.readUint8("num")
logging.getLogger(LOGGER).debug("[Client -> Khanat] Cycle:%u num:%u" % (cycle, num))
for i in range(0, num):
actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin))
pass
except BitStream.OverflowError:
noerror = False
except Exception as e:
logging.getLogger(LOGGER).debug("[Client -> Khanat] end %s (not read:%u)" % (e.__class__, msgin.needRead()))
raise e
msgin.enable_LogErrorOnStreamOverflow()
logging.getLogger(LOGGER).debug("[Client -> Khanat] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions])))
# decodeVisualProperties( msgin );
def decode_client_message(self, msgin, clientid, dst): def decode_client_message(self, msgin, clientid, dst):
CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber')
@ -230,7 +258,7 @@ class SpyPcap():
self.client_state[clientid]['AckBitMask'] = AckBitMask self.client_state[clientid]['AckBitMask'] = AckBitMask
logging.getLogger(LOGGER).info("[Client -> Khanat] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) logging.getLogger(LOGGER).info("[Client -> Khanat] 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_receive_normal_message(msgin, clientid, dst) self.decode_client_send_normal_message(msgin, clientid, dst)
else: else:
message = msgin.readUint8('message') message = msgin.readUint8('message')
try: try:
@ -376,7 +404,10 @@ class SpyPcap():
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) self.decode_client_message(msgin, src, dst)
if self.show_message_decoded: if self.show_message_decoded:
logging.getLogger(LOGGER).debug("[%s] %s" % (_provenance, msgin.showAllData())) moredata='(message decoded)'
if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7:
moredata = "(message decoded: not full)"
logging.getLogger(LOGGER).debug("[%s] %s %s" % (_provenance, moredata, msgin.showAllData()))
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']))
@ -393,6 +424,7 @@ def main():
logger.append(logging.getLogger(CStringManager.LOGGER)) logger.append(logging.getLogger(CStringManager.LOGGER))
logger.append(logging.getLogger(CAction.LOGGER)) logger.append(logging.getLogger(CAction.LOGGER))
logger.append(logging.getLogger(CActionFactory.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

@ -18,11 +18,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from ctypes import * from ctypes import *
import sys import sys
import inspect import inspect
import copy import copy
LOGGER='BitStream'
class OverflowError(Exception): class OverflowError(Exception):
pass pass
@ -34,6 +36,7 @@ class BitStream():
self._tampon = [] self._tampon = []
self._groupRead = [] self._groupRead = []
self._groupWrite = [] self._groupWrite = []
self._CheckStreamOverflow = True
def __len__(self): def __len__(self):
return (self._pos + 7) // 8 return (self._pos + 7) // 8
@ -47,6 +50,12 @@ class BitStream():
ret._groupWrite = copy.deepcopy(self._groupWrite, memo) ret._groupWrite = copy.deepcopy(self._groupWrite, memo)
return ret return ret
def enable_LogErrorOnStreamOverflow(self):
self._CheckStreamOverflow = True
def disable_LogErrorOnStreamOverflow(self):
self._CheckStreamOverflow = False
def needRead(self): def needRead(self):
return self._pos - self._read return self._pos - self._read
@ -515,7 +524,8 @@ class BitStream():
elif nbits > 32: elif nbits > 32:
raise "Out of range" raise "Out of range"
if self._read + nbits > self._pos: if self._read + nbits > self._pos:
print("Error: Stream Overflow - nbits:%d/%d name:'%s' decode:'%s' typeName:'%s' emulate:%s msg:%s" %(nbits, self._pos-self._read, name, str(decode), typeName, str(emulate), self.showAllData()), file=sys.stderr) if self._CheckStreamOverflow:
logging.getLogger(LOGGER).error("Error: Stream Overflow - nbits:%d/%d name:'%s' decode:'%s' typeName:'%s' emulate:%s msg:%s" % (nbits, self._pos-self._read, name, str(decode), typeName, str(emulate), self.showAllData()))
raise OverflowError raise OverflowError
if emulate: if emulate:
oldRead = self._read oldRead = self._read
@ -855,6 +865,19 @@ class BitStream():
self._read = readBefore self._read = readBefore
return ret return ret
def checkOnlyZeroAtEnd(self):
readBefore = self._read
while self._read < self._pos:
if self._pos - self._read >= 8:
nsize = 8
else:
nsize = self._pos - self._read
data = self.readSerial(nsize, decode=False)
if data > 0:
return False
self._read = readBefore
return True
def getPosInBit(self): def getPosInBit(self):
return self._pos return self._pos

View file

@ -359,6 +359,15 @@ class CActionBlock:
for action in self.Actions: for action in self.Actions:
action.pack(msgout) action.pack(msgout)
def readSerial(self, msgin):
actions = []
_cycle = msgin.readUint32("Cycle")
_numberActions = msgin.readUint8("numberActions")
logging.getLogger(LOGGER).debug("_cycle:%d _numberActions:%d" % (_cycle, _numberActions))
for i in range(0,_numberActions):
actions.append( msgin.unpack(msgin) )
return actions
def insert(self, actions, begin, end): def insert(self, actions, begin, end):
for i in range(0, end): for i in range(0, end):
if i>= begin: if i>= begin:
@ -370,6 +379,7 @@ class CActionBlock:
def push_back(self, action): def push_back(self, action):
self.Actions.append(action) self.Actions.append(action)
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]) + "]"