2.0 A quoi servent les flags ? Et, où dois-je prendre mes valeurs pour sérializer ?

Inscrit
4 Aout 2016
Messages
166
Reactions
0
#1
Re !

Pour faire simple je suis en train d'analyser le IdentificationMessage(4), et je me suis d'abord intéresse à la function qui le sérialize car d'après mes analyses (très poussées xp), c'est le premier message que je dois envoyer au serveur !

Code:
public function serializeAs_IdentificationMessage(param1:ICustomDataOutput) : void
      {
         var _loc2_:uint = 0;
         _loc2_ = BooleanByteWrapper.setFlag(_loc2_,0,this.autoconnect);
         _loc2_ = BooleanByteWrapper.setFlag(_loc2_,1,this.useCertificate);
         _loc2_ = BooleanByteWrapper.setFlag(_loc2_,2,this.useLoginToken);
         param1.writeByte(_loc2_);
         this.version.serializeAs_VersionExtended(param1);
         param1.writeUTF(this.lang);
         param1.writeVarInt(this.credentials.length);
         var _loc3_:uint = 0;
         while(_loc3_ < this.credentials.length)
         {
            param1.writeByte(this.credentials[_loc3_]);
            _loc3_++;
         }
         param1.writeShort(this.serverId);
         if(this.sessionOptionalSalt < -9007199254740990 || this.sessionOptionalSalt > 9007199254740990)
         {
            throw new Error("Forbidden value (" + this.sessionOptionalSalt + ") on element sessionOptionalSalt.");
         }
         param1.writeVarLong(this.sessionOptionalSalt);
         param1.writeShort(this.failedAttempts.length);
         var _loc4_:uint = 0;
         while(_loc4_ < this.failedAttempts.length)
         {
            if(this.failedAttempts[_loc4_] < 0)
            {
               throw new Error("Forbidden value (" + this.failedAttempts[_loc4_] + ") on element 9 (starting at 1) of failedAttempts.");
            }
            param1.writeVarShort(this.failedAttempts[_loc4_]);
            _loc4_++;
         }
      }

Donc tout est facilement compréhensible hein ! Sauf, ce bout de code :
Code:
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,0,this.autoconnect);
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,1,this.useCertificate);
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,2,this.useLoginToken);
param1.writeByte(_loc2_);
Je ne comprend pas pourquoi _loc2_ est réécris à chaque fois !
C'est sûrement une notion sur les flags que je ne connais pas mais bon, c'est vraiment bizarre :[

Et ma deuxième question
En voyant tout ça, je me demande, mais d'où viennent les args ? Je dois piocher tout ça dans un fichier ? Il est où ? Sinon ou je vois "l'index" là où est la logique de connexion ?


Merci ! :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#2
Bonsoir,

La classe BooleanByteWrapper permet de serializer plusieurs variables boolean en une seule de type byte.

On pourrai traduire la fonction SetFlag() en C# de cette manière:

C#:
        public static byte SetFlag(byte flag, byte offset, bool value)
        {
            if (offset >= 8)
                throw new ArgumentException("offset must be lesser than 8");

            return value ? (byte)(flag | (1 << offset)) : (byte)(flag & 255 - (1 << offset));
        }

        public static byte SetFlag(int flag, byte offset, bool value)
        {
            if (offset >= 8)
                throw new ArgumentException("offset must be lesser than 8");

            return value ? (byte)(flag | (1 << offset)) : (byte)(flag & 255 - (1 << offset));
        }
Pour le cas de la classe IdentificationMessage,

Code:
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,0,this.autoconnect);
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,1,this.useCertificate);
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,2,this.useLoginToken);
param1.writeByte(_loc2_);
Si tes variables sont de valeur false, la fonction va retourner une valeur nulle, par contre si ta variable est à true, le résultat sera positif. Les valeurs sont additionnés et envoyés au serveur qui arrivera à inverser le processus pour récupérer les valeurs de tes variables.

Donc si ton autoConnect est à true, loc2 aura pour valeur 1.
Si ton useCertificate est à true, loc2 aura pour valeur 3.
Et si ton useLoginToken est à false, loc2 conservera la valeur 3.
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#3
Merci de la réponse ! :)

Ça je l'avais plus ou moins grossièrement compris mais regarde :
C#:
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,0,this.autoconnect); // _loc2_ == 1
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,1,this.useCertificate); // Mais maintenant la variable a été réécrite
_loc2_ = BooleanByteWrapper.setFlag(_loc2_,2,this.useLoginToken); // Et la aussi o-o
param1.writeByte(_loc2_);
En fait comme à chaque fois on réécris la variable si ça avais été un truc du style var _loc2_ = new writer(); _loc2_.setFlag([...]) ...

Mais là on remplace l'ancienne valeur, y'a un truc qui m'échappe ! :'(
 
Inscrit
2 Juin 2016
Messages
82
Reactions
3
#4
En C#, une variable bool prend un octet. (byte)
Afin de gagner de la place lors des échanges réseaux, Dofus a opté pour "compacté" les bools sur un seul octet (max: 8 valeurs donc) et les flags permettent donc de faire un traitement bit-à-bit. (en gros)
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#5
C'est effectivement du traitement bit à bit, et en plus l'ancienne valeur de _loc2_ n'est pas juste effacé,
si tu regarde bien, _loc2_ est utiliser pour réécrire _loc2_. Donc tu ne perd pas son ancienne valeur, tu fait juste une modification sur un bit.
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#6
Meerde ! OUI ! Arf! Je suis con ! Effectivement il reste une part de chaque _loc_ en leur réécriture !

Merci !!
 
Haut Bas