2.0 Deserialisation de paquet ? Besoin d'un peu d'aide :)

Inscrit
30 Juillet 2017
Messages
9
Reactions
0
#1
Bonjour,

dans le cadre d'un projet de récupération des données des hdv, je cherche à récupérer les informations contenu dans un paquet reçu lorsque que l'on appuie sur une ressource en HDV pour dérouler les prix.
Capture d’écran 2020-03-22 à 02.54.53.png

Le paquet reçu lors du clique sur la ressource est le id : 5752 (je crois) et cela semble coller avec la fonction de deserialisation trouvé dans les sources de Dofus.

Code:
      public function deserializeAs_BidExchangerObjectInfo(input:ICustomDataInput) : void
      {
         var _id2:uint = 0;
         var _item2:ObjectEffect = null;
         var _val3:Number = NaN;
         this._objectUIDFunc(input);
         var _effectsLen:uint = input.readUnsignedShort();
         for(var _i2:uint = 0; _i2 < _effectsLen; _i2++)
         {
            _id2 = input.readUnsignedShort();
            _item2 = ProtocolTypeManager.getInstance(ObjectEffect,_id2);
            _item2.deserialize(input);
            this.effects.push(_item2);
         }
         var _pricesLen:uint = input.readUnsignedShort();
         for(var _i3:uint = 0; _i3 < _pricesLen; _i3++)
         {
            _val3 = input.readVarUhLong();
            if(_val3 < 0 || _val3 > 9007199254740990)
            {
               throw new Error("Forbidden value (" + _val3 + ") on elements of prices.");
            }
            this.prices.push(_val3);
         }
      }
Dans ce code sans compter les sous fonctions, il y a plusieurs lectures sur la data de différents types.
Première question : ceci est-il correcte ?
UnsignedShort = 2 octets
VarUhInt (dans une sous fonction) = 4 octets
VarUhLong = 8 octets

J'ai essayé de suivre rigoureusement les sources de Dofus pour deserialiser le paquet reçu, cependant je n'y parviens pas.
J'ai donc adopter une stratégie brute:
1.Générer un paquet par le biais du client et noter les informations affichées.
2.Convertir les informations affichées en héxadécimal.
3.Rechercher les valeurs en héxadécimal directement dans le paquet reçu.

Par exemple pour la ressource du screen plus haut, nous avons comme valeur affichées:
154 -> 9a ou a9 (on sait jamais peut-être c'est inversé ??)
194 -> c2 ou 2c
897 -> 381 ou 183
40994 -> a022 ou 220a

Le paquet reçu est le suivant :
59e118000000380001b5b003b00200000038000000038a8c02b90e02c0

Comme on peut le voir on ne retrouve pas les datas dans le paquet.

Pour deserialiser je me suis appuyer sur le tutoriel de Labo : https://cadernis.fr/index.php?threads/de-lanalyse-des-paquets.1056/. Un grand merci pour son excellent tutoriel.

Deuxième question:
Validez-vous l'id du paquet que j'ai trouvé ?

Troisième question:
Ma méthode est-elle bonne pour vérifier si la data est bien présente dans le paquet ?

Quatrième question:
Si oui, quels pourrait-être mes erreurs lors de la deserialisation (basé sur vos expériences et connaissances personnelles)

Un grand merci par avance à ce qui prendrons le temps de s'attarder sur mon problème ! :)
 
Inscrit
23 Janvier 2019
Messages
9
Reactions
5
#2
L'id du paquet est bon.
Code:
{
    'id': 5752,
    'name': 'ExchangeTypesItemsExchangerDescriptionForUserMessage',
    'objectType': 184,
    'itemTypeDescriptions': [{
        'name': 'BidExchangerObjectInfo',
        'objectUID': 1972599,
        'objectGID': 16819,
        'objectType': 184,
        'effects': [{
            '__type__': 'ObjectEffectInteger',
            'actionId': 209,
            'value': 2331
        }],
        'prices': [1587, 15889, 197598]
    }]
}



Et, pour reprendre les travaux de Labo, son decodeur avec ton paquet : https://louisabraham.github.io/LaBo...80001b5b003b00200000038000000038a8c02b90e02c0

J'ai volontairement omis les autres questions, voici également la liste (pour cette version : 2.54.16.344) des messages_id et messages_name si cela peut te permettre d'avancer dans ton debug : https://pastebin.com/raw/puXmg73f
 
Inscrit
22 Juillet 2018
Messages
81
Reactions
12
#3
Inscrit
10 Mai 2015
Messages
357
Reactions
55
#4
Selon moi quand vous essayez de traduire un packet Dofus 2, il faut pas essayer de mettre du sens au nom des méthodes mais plutôt faire une traduction de l'AS3 vers votre langage.

Pour commencer, pour identifier un packet selon son identifiant, rendez-vous dans script.com.ankamagames.jerakine.network.ServerConnection :

JavaScript:
   protected function lowReceive(src:IDataInput) : INetworkMessage
      {
         var msg:INetworkMessage = null;
         var staticHeader:uint = 0;
         var messageId:uint = 0;
         var messageLength:uint = 0;
         if(!this._splittedPacket)
         {
            if(src.bytesAvailable < 2)
            {
               if(DEBUG_LOW_LEVEL_VERBOSE)
               {
                  _log.info("[" + this._id + "] Not enough data to read the header, byte available : " + src.bytesAvailable + " (needed : 2)");
               }
               return null;
            }
            staticHeader = src.readUnsignedShort();
            messageId = this.getMessageId(staticHeader);
            if(src.bytesAvailable >= (staticHeader & NetworkMessage.BIT_MASK))
            {
               messageLength = this.readMessageLength(staticHeader,src);
               if(src.bytesAvailable >= messageLength)
               {
                  this.updateLatency();
                  if(this.getUnpackMode(messageId,messageLength) == UnpackMode.ASYNC)
                  {
                     src.readBytes(this._input,this._input.length,messageLength);
                     msg = this._rawParser.parseAsync(new CustomDataWrapper(this._input),messageId,messageLength,this.computeMessage);
                     if(DEBUG_LOW_LEVEL_VERBOSE && msg != null)
                     {
                        _log.info("[" + this._id + "] Async " + this.getType(msg) + " parsing, message length : " + messageLength + ")");
                     }
                  }
                  else
                  {
                     msg = this._rawParser.parse(new CustomDataWrapper(src),messageId,messageLength);
                     if(DEBUG_LOW_LEVEL_VERBOSE)
                     {
                        _log.info("[" + this._id + "] Full parsing done");
                     }
                  }
                  return msg;
               }
               if(DEBUG_LOW_LEVEL_VERBOSE)
               {
                  _log.info("[" + this._id + "] Not enough data to read msg content, byte available : " + src.bytesAvailable + " (needed : " + messageLength + ")");
               }
               this._staticHeader = -1;
               this._splittedPacketLength = messageLength;
               this._splittedPacketId = messageId;
               this._splittedPacket = true;
               src.readBytes(this._inputBuffer,0,src.bytesAvailable);
               return null;
            }
            if(DEBUG_LOW_LEVEL_VERBOSE)
            {
               _log.info("[" + this._id + "] Not enough data to read message ID, byte available : " + src.bytesAvailable + " (needed : " + (staticHeader & NetworkMessage.BIT_MASK) + ")");
            }
            this._staticHeader = staticHeader;
            this._splittedPacketLength = messageLength;
            this._splittedPacketId = messageId;
            this._splittedPacket = true;
            return null;
         }
         if(this._staticHeader != -1)
         {
            this._splittedPacketLength = this.readMessageLength(this._staticHeader,src);
            this._staticHeader = -1;
         }
         if(src.bytesAvailable + this._inputBuffer.length >= this._splittedPacketLength)
         {
            src.readBytes(this._inputBuffer,this._inputBuffer.length,this._splittedPacketLength - this._inputBuffer.length);
            this._inputBuffer.position = 0;
            this.updateLatency();
            if(this.getUnpackMode(this._splittedPacketId,this._splittedPacketLength) == UnpackMode.ASYNC)
            {
               msg = this._rawParser.parseAsync(new CustomDataWrapper(this._inputBuffer),this._splittedPacketId,this._splittedPacketLength,this.computeMessage);
               if(DEBUG_LOW_LEVEL_VERBOSE && msg != null)
               {
                  _log.info("[" + this._id + "] Async splitted " + this.getType(msg) + " parsing, message length : " + this._splittedPacketLength + ")");
               }
            }
            else
            {
               msg = this._rawParser.parse(new CustomDataWrapper(this._inputBuffer),this._splittedPacketId,this._splittedPacketLength);
               if(DEBUG_LOW_LEVEL_VERBOSE)
               {
                  _log.info("[" + this._id + "] Full parsing done");
               }
            }
            this._splittedPacket = false;
            this._inputBuffer = new ByteArray();
            return msg;
         }
         src.readBytes(this._inputBuffer,this._inputBuffer.length,src.bytesAvailable);
         return null;
      }
Ensuite pour lire le contenu du packet. vous devrez traduire la méthode unpack qui n'est rien d'autre qu'un deserialize du packet en question. Ici rien de compliqué mais attention a bien traduire la classe script.com.ankamagames.jerakine.network.CustomDataWrapper
Celle-ci répertorie toutes les méthodes pour lire le contenu de votre packet. (ainsi que toutes les méthodes pour l'écrire).

Quelques petits conseils sur mes erreurs passées (en .NET framework)

JavaScript:
      public function readByte() : int
      {
         return this._data.readByte();
      }
    
      public function readUnsignedByte() : uint
      {
         return this._data.readUnsignedByte();
      }
L'équivalent de la méthode readByte() en AS3 est enfaite un readSbyte() en c# [-128;127]
L'équivalent de la méthode readUnsignedByte() en AS3 est enfaite un readByte() en c# [0;255]

Pour traduire l'équivalent du <<< en AS3, Je procède de cette manière en c# : j’effectue l'opération << le tout d'un cast en Uint

Voila, je pense un peu avoir fait le tour, c'est vraiment important de bien savoir traduire du code AS3 vers ton language de programmation ainsi que d'avoir une idée globale de l'architecture du jeu.
 
Haut Bas