diff --git a/client.py b/client.py index 50d06f4..b784860 100755 --- a/client.py +++ b/client.py @@ -175,24 +175,26 @@ class BitStream(): if need != 8: self.internalSerial(source.readSerial(need), need) while source.needRead() >= 8: - self.pushUint8(source.readUint8()) + self.pushUint8(source.readSerial(8, False)) need = source.needRead() if need > 0: - self.internalSerial(source.readSerial(need), need) + self.internalSerial(source.readSerial(need, False), need) source.putRead(srcRead) # ------------------------------------ - def readSerial(self, nbits, decode=True): + def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False): 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)) + if decode and not emulate: + self._groupRead.append((self._read, self._read+nbits, name, typeName)) + if emulate: + oldRead = self._read value = 0 pos = self._read // 8 _FreeBits = 8 - (self._read % 8) @@ -200,93 +202,109 @@ class BitStream(): if nbits > _FreeBits: value |= (v << (nbits-_FreeBits)) self._read += _FreeBits - value |= self.readSerial(nbits - _FreeBits, False) + value |= self.readSerial(nbits - _FreeBits, decode=False) else: value |= (v >> (_FreeBits-nbits)) self._read += nbits + if emulate: + self._read = oldRead return value - def readBool(self): - v = self.readSerial(1) + def readBool(self, name): + v = self.readSerial(1, name=name, typeName='Bool') if v != 0: return True else: return False - def readUint32(self): - v = self.readSerial(32) + def readUint32(self, name, decode=True, typeName='Uint32'): + v = self.readSerial(32, name=name, decode=decode, typeName=typeName) return v - def readSint32(self): - v = self.readSerial(32) + def readSint32(self, name): + v = self.readSerial(32, name=name, typeName='Sint32') return c_int32(v).value - def readUint16(self): - v = self.readSerial(16) + def readUint16(self, name): + v = self.readSerial(16, name=name, typeName='Uint16') return v - def readSint16(self): - v = self.readSerial(16) + def readSint16(self, name): + v = self.readSerial(16, name=name, typeName='Sint16') return c_int16(v).value - def readUint8(self): - v = self.readSerial(8) + def readUint8(self, name, decode=True, typeName='Uint8'): + v = self.readSerial(8, decode=decode, name=name, typeName=typeName) return v - def readSint8(self): - v = self.readSerial(8) + def readSint8(self, name): + v = self.readSerial(8, name=name, typeName='Sint8') return c_int8(v).value - def readUint64(self): - v = self.readSerial(32) - v1 = self.readSerial(32) + def readUint64(self, name): + self._groupRead.append((self._read, self._read+64, name, 'Uint64')) + v = self.readSerial(32, decode=False) + v1 = self.readSerial(32, decode=False) v2 = v | (v1 << 32) return v2 - def readSint64(self): - v = self.readSerial(32) - v1 = self.readSerial(32) + def readSint64(self, name): + self._groupRead.append((self._read, self._read+64, name, 'Sint64')) + v = self.readSerial(32, decode=False) + v1 = self.readSerial(32, decode=False) v2 = v | (v1 << 32) return c_int64(v2).value - def readFloat(self): - v = self.readSerial(32) + def readFloat(self, name): + v = self.readSerial(32, name=name, typeName='Float') v1 = struct.pack('I', v) v2 = struct.unpack(' 0: - x = self.readChar() + x = self.readChar('', decode=False) tmp += x _size -= 1 + v2 = self._read + if v2 > self._pos: + raise ValueError + self._groupRead.append((v1, v2, name, 'String')) return tmp - def readArrayUint8(self, size): + def readArrayUint8(self, size, name): ret = [] + v1 = self._read for i in range(0, size): - ret.append(self.readUint8()) + ret.append(self.readUint8('', decode=False)) + v2 = self._read + self._groupRead.append((v1, v2, name, 'ArrayUint8')) return ret - def readBitStreamUint8(self, size): + def readBitStreamUint8(self, size, name): ret = BitStream() + v1 = self._read for i in range(0, size): - ret.pushUint8(self.readUint8()) + ret.pushUint8(self.readUint8('', decode=False)) + v2 = self._read + self._groupRead.append((v1, v2, name, 'StreamUint8')) return ret # ------------------------------------ @@ -310,12 +328,28 @@ class BitStream(): readBefore = self._read while self._read < self._pos: if self._pos - self._read >= 8: - data = self.readUint8() + nsize = 8 else: - data = self.readSerial(self._pos - self._read) + nsize = self._pos - self._read + data = self.readSerial(nsize, decode=False) + if nsize == 1: + ret += "{0:01b}".format(data) + elif nsize == 2: + ret += "{0:02b}".format(data) + elif nsize == 3: + ret += "{0:03b}".format(data) + elif nsize == 4: + ret += "{0:04b}".format(data) + elif nsize == 5: + ret += "{0:05b}".format(data) + elif nsize == 6: + ret += "{0:06b}".format(data) + elif nsize == 7: + ret += "{0:07b}".format(data) + else: + ret += "{0:08b}".format(data) if ret != "": ret += "." - #ret += hex(data) ret += "{0:08b}".format(data) self._read = readBefore return ret @@ -326,36 +360,66 @@ class BitStream(): self._read = 0 while self._read < self._pos: if self._pos - self._read >= 8: - data = self.readSerial(8, False) + nsize = 8 else: - data = self.readSerial(self._pos - self._read, False) - ret += "{0:08b}".format(data) + nsize = self._pos - self._read + data = self.readSerial(nsize, decode=False) + if nsize == 1: + ret += "{0:01b}".format(data) + elif nsize == 2: + ret += "{0:02b}".format(data) + elif nsize == 3: + ret += "{0:03b}".format(data) + elif nsize == 4: + ret += "{0:04b}".format(data) + elif nsize == 5: + ret += "{0:05b}".format(data) + elif nsize == 6: + ret += "{0:06b}".format(data) + elif nsize == 7: + ret += "{0:07b}".format(data) + else: + ret += "{0:08b}".format(data) self._read = readBefore ret2 = "" last = 0 - for x, y in self._groupRead: - ret2 += "[" + ret[x:y] + "]" + for x, y, name, typeName in self._groupRead: + ret2 += "[<" + str(x) + ':' + str(y-1) + "> " + str(name) + ' (' + typeName + ') = ' + ret[x:y] + "]" last = y if last < self._pos: ret2 += "{" + ret[last:] + "}" return ret2 - def showAllDataBis(self): + def showAllDataRaw(self): ret = "" readBefore = self._read self._read = 0 while self._read < self._pos: if self._pos - self._read >= 8: - data = self.readUint8() + nsize = 8 else: - data = self.readSerial(self._pos - self._read) + nsize = self._pos - self._read + data = self.readSerial(nsize, decode=False) + if nsize == 1: + ret += "{0:01b}".format(data) + elif nsize == 2: + ret += "{0:02b}".format(data) + elif nsize == 3: + ret += "{0:03b}".format(data) + elif nsize == 4: + ret += "{0:04b}".format(data) + elif nsize == 5: + ret += "{0:05b}".format(data) + elif nsize == 6: + ret += "{0:06b}".format(data) + elif nsize == 7: + ret += "{0:07b}".format(data) + else: + ret += "{0:08b}".format(data) if ret != "": ret += "." - #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(): @@ -376,87 +440,104 @@ def TestBitStream(): a.pushSint64(-1) a.pushChar('a') a.pushString("Test A Faire") - print('raw:', a) + print('raw:') + print(a.showAllDataRaw()) + print("-" * 20) print("-" * 80) - print(a.readBool()) - print(a.readBool()) - print(a.readBool()) - print(a.readBool()) - print(a.readUint32()) - print(a.readSint32()) - print(a.readUint16()) - print(a.readSint16()) - print(a.readUint8()) - print(a.readSint8()) - print(a.readFloat()) - print(a.readDouble()) - print(a.readUint64()) - print(a.readSint64()) - print(a.readChar()) - print(a.readString()) + print(a.readBool('a1')) + print(a.readBool('a2')) + print(a.readBool('a3')) + print(a.readBool('a4')) + print(a.readUint32('a5')) + print(a.readSint32('a6')) + print(a.readUint16('a7')) + print(a.readSint16('a8')) + print(a.readUint8('a9')) + print(a.readSint8('a10')) + print(a.readFloat('a11')) + print(a.readDouble('a12')) + print(a.readUint64('a13')) + print(a.readSint64('a14')) + print(a.readChar('a15')) + print(a.readString('a16')) print(a.toBytes()) + print("-" * 40) + print(a.showAllData()) print("-" * 80) b = BitStream() b.fromBytes(a.toBytes()) - print(b.readBool()) - print(b.readBool()) - print(b.readBool()) - print(b.readBool()) - print(b.readUint32()) - print(b.readSint32()) - print(b.readUint16()) - print(b.readSint16()) - print(b.readUint8()) - print(b.readSint8()) - print(b.readFloat()) - print(b.readDouble()) - print(b.readUint64()) - print(b.readSint64()) - print(b.readChar()) - print(b.readString()) + print(b.readBool('b1')) + print(b.readBool('b2')) + print(b.readBool('b3')) + print(b.readBool('b4')) + print(b.readUint32('b5')) + print(b.readSint32('b6')) + print(b.readUint16('b7')) + print(b.readSint16('b8')) + print(b.readUint8('b9')) + print(b.readSint8('b10')) + print(b.readFloat('b11')) + print(b.readDouble('b12')) + print(b.readUint64('b13')) + print(b.readSint64('b14')) + print(b.readChar('b15')) + print(b.readString('b16')) print(b.toBytes()) + print("-" * 40) + print(b.showAllData()) print("-" * 80) c = BitStream() c.pushBool(True) c.pushBitStream(a) c.pushBitStream(b) - print(c.readBool()) + print(c.readBool('c1')) 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.readBool('c2')) + print(c.readBool('c3')) + print(c.readBool('c4')) + print(c.readBool('c5')) + print(c.readUint32('c6')) + print(c.readSint32('c7')) + print(c.readUint16('c8')) + print(c.readSint16('c9')) + print(c.readUint8('c10')) + print(c.readSint8('c11')) + print(c.readFloat('c12')) + print(c.readDouble('c13')) + print(c.readUint64('c14')) + print(c.readSint64('c15')) + print(c.readChar('c16')) + print(c.readString('c17')) print(c.toBytes()) + print("-" * 50) + print(c.showAllData()) + print("-" * 50) + print(c.readBool('c18')) + print(c.readBool('c19')) + print(c.readBool('c20')) + print(c.readBool('c21')) + print(c.readUint32('c22')) + print(c.readSint32('c23')) + print(c.readUint16('c24')) + print(c.readSint16('c25')) + print(c.readUint8('c26')) + print(c.readSint8('c27')) + print(c.readFloat('c28')) + print(c.readDouble('c29')) + print(c.readUint64('c30')) + print(c.readSint64('c31')) + print(c.readChar('c32')) + print("-" * 40) + print(c.showAllData()) + print(c.readString('c33')) + print("-" * 40) + print(c.showAllData()) + print(c.toBytes()) + print("-" * 40) + print(c.showAllDataRaw()) + print("-" * 20) + print(c.showAllData()) 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: @@ -1890,7 +1971,7 @@ class DecodeImpulse(): def impulseStringResp(self, msgin): self.log.debug("TODO") def impulseReloadCache(self, msgin): - self.world.timestamp = msgin.readUint32() + self.world.timestamp = msgin.readUint32('timestamp') self.log.debug("Reload Cache timestamp:%d" % self.world.timestamp) self.log.debug("Message not read (%d) %s" % (msgin.needRead(), msgin.showLastData() )) @@ -2206,17 +2287,19 @@ class DecodeImpulse(): listpath = [] while True: nbBit = getPowerOf2(len(head)) - #self.log.debug('nbBit:%d' % nbBit) - id = msgin.readSerial(nbBit) - #self.log.debug('id:%s' % str(id)) + # def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False): + id = msgin.readSerial(nbBit, name='Ptr', typeName='Number', emulate=True) + ele = head[id] name = ele.attrib['name'] - #self.log.debug(name) listpath.append(name) fullname = ':'.join(listpath) + + id = msgin.readSerial(nbBit, name='Ptr', typeName='MsgXML<' + name + '>') if fullname in self.GenericMsgHeaderMngr: self.log.debug("Found : %s" % fullname) self.GenericMsgHeaderMngr[fullname](msgin) + self.log.debug("MessageXML decoded: %s" % msgin.showAllData() ) return True else: #self.log.debug("Non trouve") @@ -2226,24 +2309,13 @@ class DecodeImpulse(): break if head != ele: self.log.error("Impossible to found %s" % fullname ) + self.log.debug("MessageXML decoded: %s" % msgin.showAllData() ) return False + self.log.debug("MessageXML decoded: %s" % msgin.showAllData() ) return False - def loadMsg(self, msgXml): self.msgXml = msgXml -# print('-'*80) -# print(self.msgXml) -# print(dir(self.msgXml)) -# print('-'*80) -# print(self.sizeElement()) -# print(self.sizeElement('STRING')) -# print('-'*20) -# print(self.searchElement("DB_UPD_PLR")) -# print(self.searchElement("STRING:TELL")) -# print('-'*80) -# self.GenericMsgHeaderMngr['DB_UPD_PLR']('test') -# print('-'*80) def loadDatabase(self, databaseXml): self.databaseXml = databaseXml @@ -2352,8 +2424,8 @@ class CActionGeneric(CAction): self._Message = None def unpack(self, message): - size = message.readUint32() - self._Message = message.readBitStreamUint8(size) + size = message.readUint32('size') + self._Message = message.readBitStreamUint8(size, 'message') def reset(self): self._Message = None @@ -2376,12 +2448,12 @@ class CActionGenericMultiPart(CAction): self.NbBlock = 0 def unpack(self, message): - self.Number = message.readUint8() - self.Part = message.readUint16() - self.NbBlock = message.readUint16() + self.Number = message.readUint8('Number') + self.Part = message.readUint16('Part') + self.NbBlock = message.readUint16('NbBlock') - size = message.readUint32() - self.PartCont = message.readBitStreamUint8(size) + size = message.readUint32('size') + self.PartCont = message.readBitStreamUint8(size, 'PartCont') def reset(self): self.PartCont = [] @@ -2483,11 +2555,11 @@ class CActionFactory: khanat-opennel-code/code/ryzom/common/src/game_share/action_factory.cpp : CAction *CActionFactory::unpack (NLMISC::CBitMemStream &message, NLMISC::TGameCycle /* currentCycle */ ) ''' if msgin.needRead() >= 8: - shortcode = msgin.readBool() + shortcode = msgin.readBool('shortcode') if shortcode: - code = msgin.readSerial(2) + code = msgin.readSerial(2, 'code') else: - code = msgin.readUint8() + code = msgin.readUint8('code') action = self.create(INVALID_SLOT, code) if action: try: @@ -2533,7 +2605,7 @@ class CImpulseDecoder: self.log.debug("channel:%d lAck:%s" %(channel, ':'.join([str(x) for x in lAck]))) # lastAck = lAck[channel] while True: - next = msgin.readBool() + next = msgin.readBool('next:' + str(level) + ':' + str(channel)) if not next: break if not checkOnce: @@ -2710,8 +2782,9 @@ class ClientNetworkConnection: self._sock.sendto(msgout.toBytes(), self.frontend) def readDelta(self, msg): - propertyCount = msg.readUint16() + propertyCount = msg.readUint16('propertyCount') self.log.debug("propertyCount:%d" % propertyCount) + self.log.debug("TODO") for _ in range(0, propertyCount): pass @@ -2723,8 +2796,8 @@ class ClientNetworkConnection: def decodeHeader(self, msg): self._TotalMessages += 1 self._LastReceivedTime = self._UpdateTime - self._CurrentReceivedNumber = msg.readSint32() - self._SystemMode = msg.readBool() + self._CurrentReceivedNumber = msg.readSint32('CurrentReceivedNumber') + self._SystemMode = msg.readBool('SystemMode') if self.checkMessageNumber and self._CurrentReceivedNumber > self._LastReceivedPacketInBothModes: self._TotalLostPackets += self._CurrentReceivedNumber - self._LastReceivedPacketInBothModes - 1 @@ -2733,7 +2806,7 @@ class ClientNetworkConnection: # self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1 if not self._SystemMode: - self._LastReceivedAck = msg.readSint32(); + self._LastReceivedAck = msg.readSint32('LastReceivedAck'); self.log.debug("Normal Mode _LastReceivedAck:%d" % self._LastReceivedAck) else: self.log.debug("System Mode") @@ -2771,7 +2844,7 @@ class ClientNetworkConnection: def receiveSystemProbe(self, msg): self._LatestProbeTime = self._UpdateTime - self._LatestProbe = msg.readSint32() + self._LatestProbe = msg.readSint32('LatestProbe') self.log.debug("LatestProbe: %d" % self._LatestProbe) self._LatestProbes.append(self._LatestProbe) @@ -2780,13 +2853,13 @@ class ClientNetworkConnection: def receiveSystemSync(self, msg): self._LatestSyncTime = self._UpdateTime - self._Synchronize = msg.readUint32() - stime = msg.readSint64() - self._LatestSync = msg.readUint32() + self._Synchronize = msg.readUint32('Synchronize') + stime = msg.readSint64('stime') + self._LatestSync = msg.readUint32('LatestSync') self.log.debug("%d %d %d" %(self._Synchronize, stime, self._LatestSync)) # khanat-opennel-code/code/ryzom/client/src/network_connection.cpp : void CNetworkConnection::receiveSystemSync(CBitMemStream &msgin) - MsgData = msg.readArrayUint8(16) - DatabaseData = msg.readArrayUint8(16) + MsgData = msg.readArrayUint8(16, 'MsgData') + DatabaseData = msg.readArrayUint8(16, 'DatabaseData') self.log.debug("MsgData:" + str(MsgData)) self.log.debug("DatabaseData:" + str(DatabaseData)) md5Msg = bytes(MsgData) @@ -2862,7 +2935,7 @@ class ClientNetworkConnection: def stateLogin(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_SYNC_CODE: self._ConnectionState = TConnectionState.Synchronize @@ -2893,7 +2966,7 @@ class ClientNetworkConnection: def stateSynchronize(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_PROBE_CODE: self.log.debug("synchronize->probe") @@ -2928,7 +3001,7 @@ class ClientNetworkConnection: def stateConnected(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_PROBE_CODE: self.log.debug("Connected->probe") @@ -2959,7 +3032,7 @@ class ClientNetworkConnection: def stateProbe(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_SYNC_CODE: self.log.debug("probe->synchronize") @@ -2992,7 +3065,7 @@ class ClientNetworkConnection: def stateStalled(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_SYNC_CODE: self.log.debug("stalled->synchronize") @@ -3019,7 +3092,7 @@ class ClientNetworkConnection: def stateQuit(self, msgin): self.decodeHeader(msgin) if self._SystemMode: - message = msgin.readUint8() + message = msgin.readUint8('message') self.log.debug("_CurrentReceivedNumber:%d (mode:%s) %d [%d/%d/%d]" % (self._CurrentReceivedNumber, str(self._SystemMode), message, msgin.sizeData(), msgin.sizeRead(), msgin.needRead())) if message == CLFECOMMON.SYSTEM_SYNC_CODE: self.log.debug("quit->synchronize")