adding debug decode message

This commit is contained in:
AleaJactaEst 2019-06-04 21:19:06 +02:00
parent f66e4219e6
commit aa291fdb92

276
client.py
View file

@ -52,6 +52,10 @@ class BitStream():
self._pos = 0
self._read = 0
self._tampon = []
self._groupRead = []
def __len__(self):
return (self._pos + 7) // 8
def needRead(self):
return self._pos - self._read
@ -62,6 +66,17 @@ class BitStream():
def sizeRead(self):
return self._read
def getRead(self):
return self._read
def getPos(self):
return self._pos
def putRead(self, value):
if value > self._pos:
raise ValueError
self._read = value
# ------------------------------------
def internalSerial(self, value, nbits):
if nbits == 0:
@ -153,14 +168,31 @@ class BitStream():
for i in valeur:
self.pushUint8(i)
def pushBitStream(self, source):
srcRead = source.getRead()
source.putRead(0)
need = 8 - (self._pos % 8)
if need != 8:
self.internalSerial(source.readSerial(need), need)
while source.needRead() >= 8:
self.pushUint8(source.readUint8())
need = source.needRead()
if need > 0:
self.internalSerial(source.readSerial(need), need)
source.putRead(srcRead)
# ------------------------------------
def readSerial(self, nbits):
def readSerial(self, nbits, decode=True):
if nbits == 0:
return
elif nbits > 32:
raise "Out of range"
if self._read + nbits > self._pos:
raise "Stream Overflow"
if decode:
self._groupRead.append((self._read, self._read+nbits))
value = 0
pos = self._read // 8
_FreeBits = 8 - (self._read % 8)
@ -168,7 +200,7 @@ class BitStream():
if nbits > _FreeBits:
value |= (v << (nbits-_FreeBits))
self._read += _FreeBits
value |= self.readSerial(nbits - _FreeBits)
value |= self.readSerial(nbits - _FreeBits, False)
else:
value |= (v >> (_FreeBits-nbits))
self._read += nbits
@ -262,8 +294,8 @@ class BitStream():
return ''.join([ chr(x) for x in self._tampon])
def message(self):
# return str(self._pos) + ':' + str(self._tampon)
return str(self._pos) + ':' + '.'.join([ format(x, "02x") for x in self._tampon])
# return str(self._pos) + ':' + '.'.join([ format(x, "02x") for x in self._tampon])
return str(self._pos) + ':' + '.'.join([ "{0:08b}".format(x) for x in self._tampon])
def toBytes(self):
return bytes( self._tampon )
@ -283,11 +315,33 @@ class BitStream():
data = self.readSerial(self._pos - self._read)
if ret != "":
ret += "."
ret += hex(data)
#ret += hex(data)
ret += "{0:08b}".format(data)
self._read = readBefore
return ret
def showAllData(self):
ret = ""
readBefore = self._read
self._read = 0
while self._read < self._pos:
if self._pos - self._read >= 8:
data = self.readSerial(8, False)
else:
data = self.readSerial(self._pos - self._read, False)
ret += "{0:08b}".format(data)
self._read = readBefore
ret2 = ""
last = 0
for x, y in self._groupRead:
ret2 += "[" + ret[x:y] + "]"
last = y
if last < self._pos:
ret2 += "{" + ret[last:] + "}"
return ret2
def showAllDataBis(self):
ret = ""
readBefore = self._read
self._read = 0
@ -298,8 +352,10 @@ class BitStream():
data = self.readSerial(self._pos - self._read)
if ret != "":
ret += "."
ret += hex(data)
#ret += hex(data)
ret += "{0:08b}".format(data)
self._read = readBefore
ret += ' ' + '.'.join([ str(x) + ':' + str(y) for x, y in self._groupRead] )
return ret
def TestBitStream():
@ -359,6 +415,49 @@ def TestBitStream():
print(b.readChar())
print(b.readString())
print(b.toBytes())
print("-" * 80)
c = BitStream()
c.pushBool(True)
c.pushBitStream(a)
c.pushBitStream(b)
print(c.readBool())
print("-" * 80)
print(c.readBool())
print(c.readBool())
print(c.readBool())
print(c.readBool())
print(c.readUint32())
print(c.readSint32())
print(c.readUint16())
print(c.readSint16())
print(c.readUint8())
print(c.readSint8())
print(c.readFloat())
print(c.readDouble())
print(c.readUint64())
print(c.readSint64())
print(c.readChar())
print(c.readString())
print(c.toBytes())
print("-" * 80)
print(c.readBool())
print(c.readBool())
print(c.readBool())
print(c.readBool())
print(c.readUint32())
print(c.readSint32())
print(c.readUint16())
print(c.readSint16())
print(c.readUint8())
print(c.readSint8())
print(c.readFloat())
print(c.readDouble())
print(c.readUint64())
print(c.readSint64())
print(c.readChar())
print(c.readString())
print(c.toBytes())
NL_BITLEN = 32
class CBitSet:
def __init__(self):
@ -935,6 +1034,61 @@ class CArg:
#
# #####################################################
class CGenericMultiPartTemp():
def __init__(self, log):
self.log = log
self.NbBlock = 0xFFFFFFFF
self.NbCurrentBlock = 0
self.TempSize = 0
self.Temp = []
self.BlockReceived = []
def set(self, Number, Part, NbBlock, PartCont):
'''
khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::CGenericMultiPartTemp::set (CActionGenericMultiPart *agmp, CNetworkConnection *parent)
'''
if self.NbBlock == 0xFFFFFFFF:
# Initialize
self.NbBlock = NbBlock
self.NbCurrentBlock = 0
self.TempSize = 0
self.Temp = []
while len(self.Temp) < NbBlock:
self.Temp.append(None)
while len(self.BlockReceived) < NbBlock:
self.BlockReceived.append(False)
if self.BlockReceived[Part]:
self.log.warning('This part is already received, discard it %d' % Part)
return
self.Temp[Part] = PartCont
self.BlockReceived[Part] = True
self.NbCurrentBlock += 1
self.TempSize += len(PartCont)
self.log.debug("NbCurrentBlock:%d / NbBlock:%d" % (self.NbCurrentBlock, self.NbBlock))
if self.NbCurrentBlock == self.NbBlock:
# reform the total action
bms = BitStream()
self.NbBlock == 0xFFFFFFFF
for data in self.Temp:
bms.pushBitStream(data)
self.log.debug("data : %s" % bms.showAllData())
self.log.debug("*" * 80)
class World():
def __init__(self, log):
self.log = log
self.GenericMultiPartTemp = {}
self.timestamp = 0
def addGenericMultiPartTemp(self, id):
self.GenericMultiPartTemp.setdefault(id, CGenericMultiPartTemp(self.log))
def setGenericMultiPartTemp(self, Number, Part, NbBlock, PartCont):
self.GenericMultiPartTemp[Number].set(Number, Part, NbBlock, PartCont)
class CPersistentDataRecord:
def __init__(self, log):
self.log = log
@ -1620,7 +1774,7 @@ def getPowerOf2(v):
return ret
class DecodeImpulse():
def __init__(self, log):
def __init__(self, log, world):
'''
khanat-opennel-code/code/ryzom/client/src/net_manager.cpp # void initializeNetwork()
'''
@ -1629,6 +1783,7 @@ class DecodeImpulse():
self.databaseXml = None
self.GenericMsgHeaderMngr = {}
self.initializeNetwork()
self.world = world
def impulseDatabaseUpdatePlayer(self, msgin):
self.log.debug("TODO:%s" % msgin)
@ -1679,7 +1834,7 @@ class DecodeImpulse():
self.log.debug("TODO")
def impulseDynString(self, msgin):
self.log.debug("TODO")
def inpulseDynStringInChatGroup(self, msgin):
def inpulseDynStringInChatGroup(self, msgin):
self.log.debug("TODO")
def impulseTell2(self, msgin):
self.log.debug("TODO")
@ -1735,8 +1890,8 @@ class DecodeImpulse():
def impulseStringResp(self, msgin):
self.log.debug("TODO")
def impulseReloadCache(self, msgin):
timestamp = msgin.readUint32()
self.log.debug("Reload Cache timestamp:%d" % timestamp)
self.world.timestamp = msgin.readUint32()
self.log.debug("Reload Cache timestamp:%d" % self.world.timestamp)
self.log.debug("Message not read (%d) %s" % (msgin.needRead(), msgin.showLastData() ))
def impulseBotChatForceEnd(self, msgin):
@ -1841,11 +1996,11 @@ class DecodeImpulse():
self.log.debug("TODO")
def cbImpulsionGatewayOpen(self, msgin):
def cbImpulsionGatewayOpen(self, msgin):
self.log.debug("TODO")
def cbImpulsionGatewayMessage (self, msgin):
self.log.debug("TODO")
def cbImpulsionGatewayClose (self, msgin):
def cbImpulsionGatewayClose (self, msgin):
self.log.debug("TODO")
def impulseOutpostChooseSide (self, msgin):
@ -1902,7 +2057,7 @@ class DecodeImpulse():
self.GenericMsgHeaderMngr.setdefault("STRING:FAR_TELL", self.impulseFarTell)
self.GenericMsgHeaderMngr.setdefault("STRING:CHAT2", self.impulseChat2)
self.GenericMsgHeaderMngr.setdefault("STRING:DYN_STRING", self.impulseDynString)
self.GenericMsgHeaderMngr.setdefault("STRING:DYN_STRING_GROUP", self.inpulseDynStringInChatGroup)
self.GenericMsgHeaderMngr.setdefault("STRING:DYN_STRING_GROUP", self.inpulseDynStringInChatGroup)
self.GenericMsgHeaderMngr.setdefault("STRING:TELL2", self.impulseTell2)
self.GenericMsgHeaderMngr.setdefault("TP:DEST", self.impulseTP)
@ -2001,7 +2156,7 @@ class DecodeImpulse():
self.GenericMsgHeaderMngr.setdefault( "MODULE_GATEWAY:FEOPEN", self.cbImpulsionGatewayOpen)
self.GenericMsgHeaderMngr.setdefault( "MODULE_GATEWAY:GATEWAY_MSG", self.cbImpulsionGatewayMessage )
self.GenericMsgHeaderMngr.setdefault( "MODULE_GATEWAY:FECLOSE", self.cbImpulsionGatewayClose )
self.GenericMsgHeaderMngr.setdefault( "MODULE_GATEWAY:FECLOSE", self.cbImpulsionGatewayClose )
self.GenericMsgHeaderMngr.setdefault( "OUTPOST:CHOOSE_SIDE", self.impulseOutpostChooseSide )
self.GenericMsgHeaderMngr.setdefault( "OUTPOST:DECLARE_WAR_ACK", self.impulseOutpostDeclareWarAck )
@ -2094,13 +2249,14 @@ class DecodeImpulse():
self.databaseXml = databaseXml
class CAction:
def __init__(self, slot=INVALID_SLOT, code=0):
def __init__(self, slot, code, world):
self.Code = code
self.PropertyCode = code
self.Slot = slot
self._Priority = 1
self.Timeout = 0
self.GameCycle = 0
self.world = world
def unpack(self, message):
raise RuntimeError
@ -2142,57 +2298,57 @@ class CAction:
return "[%d,%d]" % (self.Code , self.Slot)
class CActionPosition(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionPosition" + super().__str__()
class CActionSync(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionSync" + super().__str__()
class CActionDisconnection(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionDisconnection" + super().__str__()
class CActionAssociation(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionAssociation" + super().__str__()
class CActionDummy(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionDummy" + super().__str__()
class CActionLogin(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionLogin" + super().__str__()
class CActionTargetSlot(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionTargetSlot" + super().__str__()
class CActionGeneric(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
self._Message = None
def unpack(self, message):
@ -2212,8 +2368,8 @@ class CActionGenericMultiPart(CAction):
'''
khanat-opennel-code/code/ryzom/common/src/game_share/action_generic_multi_part.h # class CActionGenericMultiPart
'''
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
self.PartCont = []
self.Number = 0
self.Part = 0
@ -2239,21 +2395,23 @@ class CActionGenericMultiPart(CAction):
'''
self.log = logging.getLogger('myLogger')
self.log.debug("Number:%d Part:%d NbBlock:%d" % (self.Number, self.Part, self.NbBlock))
self.log.debug("TODO")
self.world.addGenericMultiPartTemp(self.Number)
self.world.setGenericMultiPartTemp(self.Number, self.Part, self.NbBlock, self.PartCont)
def __str__(self):
return "CActionGenericMultiPart" + super().__str__() + "[" + str(self.Number) + ',' + str(self.Part) + ',' + str(self.NbBlock) + ',' + self.PartCont.showAllData() + ']'
class CActionSint64(CAction):
def __init__(self, slot, code):
super().__init__(slot, code)
def __init__(self, slot, code, world):
super().__init__(slot, code, world)
def __str__(self):
return "CActionSint64" + super().__str__()
class CActionFactory:
def __init__(self, log):
def __init__(self, log, world):
self.log = log
self.world = world
self.RegisteredAction = {}
self.RegisteredAction.setdefault(TActionCode.ACTION_POSITION_CODE, [])
self.RegisteredAction.setdefault(TActionCode.ACTION_GENERIC_CODE, [])
@ -2269,34 +2427,34 @@ class CActionFactory:
def createFactory(self, slot, code):
if code == TActionCode.ACTION_POSITION_CODE:
self.log.debug("Create CActionPosition")
return CActionPosition(slot, code)
return CActionPosition(slot, code, self.world)
elif code == TActionCode.ACTION_GENERIC_CODE:
self.log.debug("Create CActionGeneric")
return CActionGeneric(slot, code)
return CActionGeneric(slot, code, self.world)
elif code == TActionCode.ACTION_GENERIC_MULTI_PART_CODE:
self.log.debug("Create CActionGenericMultiPart")
return CActionGenericMultiPart(slot, code)
return CActionGenericMultiPart(slot, code, self.world)
elif code == TActionCode.ACTION_SINT64:
self.log.debug("Create CActionSint64")
return CActionSint64(slot, code)
return CActionSint64(slot, code, self.world)
elif code == TActionCode.ACTION_SYNC_CODE:
self.log.debug("Create CActionSync")
return CActionSync(slot, code)
return CActionSync(slot, code, self.world)
elif code == TActionCode.ACTION_DISCONNECTION_CODE:
self.log.debug("Create CActionDisconnection")
return CActionDisconnection(slot, code)
return CActionDisconnection(slot, code, self.world)
elif code == TActionCode.ACTION_ASSOCIATION_CODE:
self.log.debug("Create CActionAssociation")
return CActionAssociation(slot, code)
return CActionAssociation(slot, code, self.world)
elif code == TActionCode.ACTION_LOGIN_CODE:
self.log.debug("Create CActionLogin")
return CActionLogin(slot, code)
return CActionLogin(slot, code, self.world)
elif code == TActionCode.ACTION_TARGET_SLOT_CODE:
self.log.debug("Create CActionTargetSlot")
return CActionTargetSlot(slot, code)
return CActionTargetSlot(slot, code, self.world)
elif code == TActionCode.ACTION_DUMMY_CODE:
self.log.debug("Create CActionDummy")
return CActionDummy(slot, code)
return CActionDummy(slot, code, self.world)
else:
log = logging.getLogger('myLogger')
log.warning('create() try to create an unknown action (%u)' % code)
@ -2347,15 +2505,17 @@ class CImpulseDecoder:
'''
see : khanat-opennel-code/code/ryzom/client/src/impulse_decoder.cpp
'''
def __init__(self, log):
def __init__(self, log, world):
self.log = log
self.world = world
self.reset()
self._CActionFactory = CActionFactory(log)
self._CActionFactory = CActionFactory(log, world)
def removeCAction(self, action):
self._CActionFactory.RegisteredAction[action.Code].append(action)
def decode(self, msgin, receivedPacket, receivedAck, nextSentPacket):
self.log.debug("receivedPacket:%d receivedAck:%d nextSentPacket:%d" %(receivedPacket, receivedAck, nextSentPacket))
actions = []
for level in range(0, 3):
if level == 0:
@ -2370,6 +2530,7 @@ class CImpulseDecoder:
keep = True
checkOnce = False
num = 0
self.log.debug("channel:%d lAck:%s" %(channel, ':'.join([str(x) for x in lAck])))
# lastAck = lAck[channel]
while True:
next = msgin.readBool()
@ -2378,8 +2539,10 @@ class CImpulseDecoder:
if not checkOnce:
checkOnce = True
keep = receivedAck >= lAck[channel]
self.log.debug("keep:%s" % str(keep))
if keep:
lAck[channel] = nextSentPacket
self.log.debug("lAck:%s" % ':'.join([str(x) for x in lAck]))
num += 1
action = self._CActionFactory.unpack(msgin)
if keep:
@ -2443,7 +2606,8 @@ class ClientNetworkConnection:
self._AckBitMask = 0
self._LongAckBitField = CBitSet()
self._LatestSyncTime = 0
self._ImpulseDecoder = CImpulseDecoder(self.log)
self.world = World(self.log)
self._ImpulseDecoder = CImpulseDecoder(self.log, self.world)
self._LongAckBitField.resize(1024)
self._LatestProbeTime = 0
self._LatestProbe = 0
@ -2452,7 +2616,7 @@ class ClientNetworkConnection:
self._ReceivedAckQuit = False
self._Actions = []
self._PacketStamps = []
self.decodeImpulse = DecodeImpulse(self.log)
self.decodeImpulse = DecodeImpulse(self.log, self.world)
def signal_exit(self, sig, frame):
self.log.warning("Receive signal to quit program")
@ -2483,6 +2647,7 @@ class ClientNetworkConnection:
def buildSystemHeader(self, msgout): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout)
msgout.pushSint32(self._CurrentSendNumber)
msgout.pushBool(True) # systemMode
self._CurrentSendNumber += 1
def sendSystemLogin(self): # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemLogin()
if self._sock is None:
@ -2564,12 +2729,12 @@ class ClientNetworkConnection:
if self.checkMessageNumber and self._CurrentReceivedNumber > self._LastReceivedPacketInBothModes:
self._TotalLostPackets += self._CurrentReceivedNumber - self._LastReceivedPacketInBothModes - 1
self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber
else:
self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1
# else:
# self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1
if not self._SystemMode:
self.log.debug("Normal Mode")
self._LastReceivedAck = msg.readSint32();
self.log.debug("Normal Mode _LastReceivedAck:%d" % self._LastReceivedAck)
else:
self.log.debug("System Mode")
@ -2891,9 +3056,9 @@ class ClientNetworkConnection:
stateBroke = True
while stateBroke:
buffer, addr = self.buildStream()
self.log.debug("received message: %s" % buffer)
msgin = BitStream()
msgin.fromBytes(buffer)
self.log.debug("received message: %s" % msgin.showAllData())
if self._ConnectionState == TConnectionState.Login:
self.log.debug("state:Login")
stateBroke = self.stateLogin(msgin)
@ -2914,6 +3079,7 @@ class ClientNetworkConnection:
stateBroke = self.stateQuit(msgin)
else:
stateBroke = False
self.log.debug("message decoded: %s" % msgin.showAllData())
counterLoop += 1
if counterLoop > 10:
break