Bonjour,
Il s'agit de mon premier poste sur ce forum absolument incroyable.
Je me suis mis à créer dans un premier temps, un espèce de framework en python pour sniffer des packets dofus2.0 avec pour but dans un second temps d'en faire un bot.
J'utilise pyshark comme librairie pour récupérer mes packets en direct.
Voici mon code pour récupérer un packet :
capture = pyshark.LiveCapture(interface=ethernetNicUUID)
for raw_packet in capture.sniff_continuously():
if hasattr(raw_packet, 'tcp'):
direction = None
if raw_packet.tcp.srcport == '5555':
direction = "from_client"
if raw_packet.tcp.dstport == '5555':
direction = "to_client"
if direction is not None:
# payload = getattr(raw_packet.tcp, 'payload', None)
# payload = getattr(raw_packet.tcp, 'data', None)
payload = None
try:
print(raw_packet.data.data)
payload = raw_packet.data.data
except:
print("no data")
if payload:
try:
dofus_packet = DofusPacket(bytes.fromhex(payload.replace(':', '')))
dofus_packet.direction = direction
print("------------------------------")
print(dofus_packet)
print("------------------------------")
Et voici ma classe DofusPacket:
import json
import struct
class DofusPacket:
# dofus packet id
packet_id = 0
# associated message type
message_type = ''
# length of payload
length = 0
# raw payload
content = ''
# hex content
hexContent = b''
# type of content length
length_type = 0
# correspondence between mesage ids and message type
correspondence = {}
# direction should to_client, from_client or None
direction = None
def __str__(self):
return f"packet_id: {self.packet_id}, message_type: {self.message_type}, lenght: {self.length}"
def __init__(self, packet):
with open("IdToMessage.json", "r") as correspondenceJsonFile:
self.correspondence = json.load(correspondenceJsonFile)
# find and decode hi_header
hi_header = packet[:2]
print("hi_deader: ", bytes.hex(hi_header))
self.packet_id, self.length_type = DofusPacket.decode_hi_header(hi_header)
self.message_type = self.correspondence[str(self.packet_id)]
# find and decode length
length_bytes = packet[2:2 + self.length_type]
self.length = DofusPacket.decode_length(length_bytes, self.length_type)
# set content
self.content = packet[2 + self.length_type:2 + self.length_type + self.length]
print("content: ", bytes.hex(self.content))
self.hexContent = self.content.hex()
@staticmethod
def decode_hi_header(hi_header):
hi_header = struct.unpack('>H', hi_header)[0]
packet_id = hi_header >> 2
length_type = hi_header & 3
return packet_id, length_type
@staticmethod
def decode_length(data, length_type):
if length_type == 0:
return 0
elif length_type == 1:
return struct.unpack('>B', data[:1])[0]
elif length_type == 2:
return struct.unpack('>H', data[:2])[0]
elif length_type == 3:
return struct.unpack('>I', b'\x00' + data[:3])[0]
@staticmethod
def parse_dofus_packet(raw_packet, correspondence):
if len(raw_packet) < 2:
return None
hi_header = raw_packet[:2]
packet_id, length_type = DofusPacket.decode_hi_header(hi_header)
length_bytes = raw_packet[2:2 + length_type]
length = DofusPacket.decode_length(length_bytes, length_type)
content = raw_packet[2 + length_type:2 + length_type + length]
return {
'packet_id': packet_id,
'message_type': correspondence.get(packet_id, 'Unknown'),
'length': length,
'content': content.hex()
}
Sur certains message comme le message : MapInformationsRequestMessage, je me retrouve avec une taille de message de 0 et donc, je ne peux pas récupérer le mapId comme prévu.
Quelqu'un aurait-il une idée de ce que je fais mal et de pourquoi certains paquets ont de tel incohérence ?