Traduire deserializeAs_ProtocolRequired [NOOB]

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

Etant donné, que je me suis connecté avec succès et que j'ai tout bien parsé le header des sockets que je reçoie (youpie), je cherche maintenant à parser le corps !

Alors, je commence avec le premier socket que je reçois (ProtocolRequired), parceque c'est le premier et qu'il est assez court, donc grace aux enums que j'ai recupérer et son id, j'en déduit le fichier ou il est désérializé: ProtocolRequired.as.

Je vais directement à la function qui m'interesse: unpack(arg1) -> deserialize(arg1) -> deserializeAs_ProtocolRequired(arg1)

deserializeAs_ProtocolRequired

Code:
public function deserializeAs_ProtocolRequired(param1:ICustomDataInput) : void
      {
         this.requiredVersion = param1.readInt();
         if(this.requiredVersion < 0)
         {
            throw new Error("Forbidden value (" + this.requiredVersion + ") on element of ProtocolRequired.requiredVersion.");
         }
         this.currentVersion = param1.readInt();
         if(this.currentVersion < 0)
         {
            throw new Error("Forbidden value (" + this.currentVersion + ") on element of ProtocolRequired.currentVersion.");
         }
      }
C'est une fonction assez simple, ce qui est vraiment bien pour mon apprentissage, j'en déduis qu'il check si le jeu est à la bonne version au nom des variables, donc je commence dans un premier temps à penser ma traduction, this.requireVersion = param1.readInt() Ok, en voyant la docu as3
Reads a signed 32-bit integer from the byte stream.
,
donc je dois lire le buffer en int32, je pense utiliser la fonction
readInt32BE() de l'API Buffer node, (corrigez moi si je me trompe).

Ensuite on passe à this.currentVersion = param1.readInt() ok.. WAIT!! C'est pas deux fois la même chose ça ?!

Je suis perdus là.. o-o

Ducoup j'ai deux questions:
1) La fonction que j'ai choisie, ( readInt32BE() ), est-elle bonne ?
2) Comment fonctionne cette function ? :$

Merci ! :)
 
Inscrit
2 Juin 2009
Messages
49
Reactions
44
#2
Bonsoir,
Voici une petite doc pour toi qui sera utile : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/IDataInput.html

Et pour t'expliquer le deux fois la même fonction.un Integer est codé sur 32 bits. (donc oui ta fonction est OK) Ce qui équivaut a 32 / 8 = 4 octets. Là tu lis 2 integer = 8 octets.

Le premier readInt lis les 4 premiers octets, il en reste quatre.
Le second lis les 4 autres.

voici un tableau pour les valeurs : https://fr.wikipedia.org/wiki/Entier_(informatique)

EDIT : J'ai regardé sur google pour ta fonction, j'ai trouvé ça, a voir : https://github.com/codemix/atomicbuffers
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#3
Ahh d'accord, en lisant les 4 premiers bytes du buffer ça les saques ! ( c'est vraie que en y réfléchissant j'ai le souvenir d'avoir lus un readInt fait maison avec une boucle for ) !

En tout cas merci je vais expérimenter ça ! :p


[EDIT]

Wooh, génial merci, en lisant le readme.md..
JavaScript is faster than C++ ;)
Quand tu regrette pas la techno que t'as choisie :3
 
Dernière édition:
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#4
Après avoir traduit cette petite function et recherché sur le net sans aucune réponse, j'en déduit que ma classe est sûrement correcte, le hic, c'est qu'elle me retourne :
Code:
{ requiredVersion: 329728, currentVersion: 329728 }
D'après votre expérience ce sont de bonnes valeurs ? ( je ne sais pas comment D fait son versioning ), mais c'est sûrement bon car les deux coïncident !

Mon code:
JavaScript:
function deserializeAsProtocolRequired(buf) {
    let requiredVersion = buf.readInt32BE()
    if ( requiredVersion < 0 ) throw new Error('Invalid version !')
    let currentVersion = buf.readInt32BE()
    if ( currentVersion < 0 ) throw new Error('An Error occurred in game version parsing ! :(')

    return { requiredVersion: requiredVersion, currentVersion: currentVersion }
}
Merci à vous ! ;)
 
Inscrit
2 Juin 2009
Messages
49
Reactions
44
#5
Re,
Tes valeurs ne sont pas bonnes :/

Tu devrais avoir sur la derniere version du client :

reequired = 1717
current = 1723
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#6
Merde, attends, en as3 .readInt() lit 32 bits = 4 bytes,

Mon buffer = <Buffer 08 00 00 06 b5 00> = 6 bytes,

Comme je dois faire 2x readInt() = 2 x 4 bytes = 8 bytes

Comment lire 8 bytes dans 6 bytes ?! o-o
 
Inscrit
2 Juin 2009
Messages
49
Reactions
44
#7
08 00 00 06 b5 00 = 6 bytes
00 00 08 00 00 06 b5 00 = 8 bytes
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#8
JavaScript is faster than C++ ;)
C'est de la mauvaise fois ou de l'humour ça ^^' ... Node est écrit en C++ ... Si nodejs est plus rapide que C++, autant réécrire nodejs en nodejs :cool:.
De plus si tu regarde les sources de son code, tu pourras constaté que le code est écrit en C++.

L'auteur à simplement montré qu'on pouvait optimiser les méthodes de lecture des buffers, et si elles sont écrites en JS c'est normal qu'elle sois optimisable avec C++.

Si tu veut faire plus rapide que du C/C++, alors 2 cas de figure s'offre à toi :
  • apprendre a écrire correctement en C/C++ :teeth:
  • ou apprendre des langages de description matériel comme VHDL (en Europe surtout) ou Verilog (au US surtout) et avoir le matériel pour.

PS: Je ne dit pas que nodejs est une mauvaise tech, c'est génial (même si harmony met du temps à être implémenté, j'attend avec impatience les imports). Mais je tiens quand même à préciser pour éviter les fabulations des éventuels lecteur :p.
 
Dernière édition:
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#9
C'est de la mauvaise fois ou de l'humour ça ^^' ... Node est écrit en C++ ... Si nodejs est plus rapide que C++, autant réécrire nodejs en nodejs :cool:.
De plus si tu regarde les sources de son code, tu pourras constaté que le code est écrit en C++.

L'auteur à simplement montré qu'on pouvait optimiser les méthodes de lecture des buffers, et si elle était écrite en JS c'est normal qu'elle sois optimisation.

Si tu veut faire plus rapide que du C/C++, alors 2 cas de figure s'offre à toi :
  • apprendre a écrire correctement en C/C++ :teeth:
  • ou apprendre des langages de description matériel comme VHDL (en Europe surtout) ou Verilog (au US surtout) et avoir le matériel pour.

PS: Je ne dit pas que nodejs est une mauvaise tech, c'est génial (même si harmony met du temps à être implémenté, j'attend avec impatience les imports). Mais je tiens quand même à préciser pour éviter les fabulations des éventuels lecteur :p.
Effectivement honte sur moi, ça me paraissait gros aussi :x.

@dampenfr31 Alala honte sur moi x2 j'apprend sur la tas désolé j'avais oublié que ça doit être divisible en 8 ^^

Pour remédié à ça j'ai fait :

JavaScript:
let fillBuff = Buffer.alloc(2)
let bufvers = Buffer.concat([ fillBuff, bodyBuff ]) // Un jolie buffer divisible par 8
Puis j'ai rappellé ma méthode qui me retourne :

Code:
{ requiredVersion: 2048, currentVersion: 2048 }
C'est bon maestro ? :)
 
Inscrit
2 Juin 2009
Messages
49
Reactions
44
#10
C'est bizzare. J'ai vu sur github des gens qui demandaient un "vrai" ReadInt.
Tu devrais avoir requiredVersion à 1717
et currentVersion à 1723
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#11
Je crois savoir d'où viens le problème, node ne saque pas les bits après les avoir lus, pour prouvé ça j'ai fait un simple calcul :

JavaScript:
let buf = Buffer.from('bonjour je suis un buffer!', 'base64')
function chained(buffer) {
    let one = buffer.readInt32BE()
    let two = buffer.readInt32BE()
    let tree = buffer.readInt32BE()
    let four = buffer.readInt32BE()

    return { one:one, two: two, tree: tree, four: four }
}
console.log( chained(buf) )
OUTPUT:
Code:
> node test.js
{ one: 1854530466,
  two: 1854530466,
  tree: 1854530466,
  four: 1854530466 }
Du coup j'ai dis à node de lire les 4 premier bytes puis les 4 seconds, mais ça me retourne { requiredVersion: 2048, currentVersion: 439552 } :(
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#13
Encore pire x')

Code:
{ requiredVersion: 524288, currentVersion: 11863552 }
Je vais voir pour une lib
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#14
JavaScript:
let requiredVersion = buffer.readInt32BE(0)
let currentVersion = buffer.readInt32BE(4)
Dans la doc il est dit que la méthode prend un paramètre comme offset.
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#15
JavaScript:
let requiredVersion = buffer.readInt32BE(0)
let currentVersion = buffer.readInt32BE(4)
Dans la doc il est dit que la méthode prend un paramètre comme offset.
En voyant les exemples :
Code:
const buf = Buffer.from([0, 0, 0, 5]);

// Prints: 5
console.log(buf.readInt32BE());
On peux en déduire que 0 est par défaut ^^

JavaScript:
function deserializeAsProtocolRequired(buf) {
    let requiredVersion = buf.readInt32BE(0)
    if ( requiredVersion < 0 ) throw new Error('Invalid version !')
    let currentVersion = buf.readInt32BE(4)
    if ( currentVersion < 0 ) throw new Error('An Error occurred in game version parsing ! :(')

    return { requiredVersion: requiredVersion, currentVersion: currentVersion }
}
OUTPUT:
{ requiredVersion: 2048, currentVersion: 439552 }
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#17
Elle est pas à jour y'a des erreurs de build (même GitH li dit)7

Ducoup j'ai test avec : https://www.npmjs.com/package/buffer-reader
Mais ça donne la meme chose..

Pff.. c'est vraiment bizarre... :(

Peut être que j'ai mal découpé la head de mon packet ? pourtant l'ordre des packets selon leurs id semble bon ce qui réfute une mauvaise interprétation de la tête..

Rooh!
Je sais pas quoi faire.. pourtant mon code est bon nan ? :'(
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#19
@dampenfr31 a 100% raison, c'est la première chose à faire dans ce genre de cas. on regarde le contenu de la mémoire que l'on veut traiter.
 
Inscrit
4 Aout 2016
Messages
166
Reactions
0
#20
Oui, autant pour moi désolé, j'ai refait tout le parcours du packet reçus :

Code:
> node test.js
Buffer complet: <Buffer 00 05 08 00 00 06 b5 00 00 06 bb>
Tête du buffer: { header: 5, id: 1, typeLen: 1, messageLen: 8 }
Packet id: 1, name: ProtocolRequired, typeLen; 1, messageLen: 8
Corps du buffer: <Buffer 08 00 00 06 b5 00>

====  Essaye de parsage du corps ====

Corps du buffer remis sur une syntaxe correcte: <Buffer 00 00 08 00 00 06 b5 00>
Valeurs retournées du deserializer: { requiredVersion: 2048, currentVersion: 2048 }
Voilà les logs,

Pour ce qui est des de comment je traite le buffer :

JavaScript:
let buff = packetsData.get(1)
console.log('Buffer complet:', buff);

let header = packetManager.handleHeader(buff)
console.log('Tête du buffer:', header);
packetManager.sumup(header)

let body = packetManager.handleBody(buff, header.messageLen)
console.log('Corps du buffer:', body);

console.log('\n====  Essaye de parsage du corps ====\n');

let fillBuff = Buffer.alloc(2)
let bufvers = Buffer.concat([ fillBuff, body ])
console.log( 'Corps du buffer remis sur une syntaxe correcte:', bufvers );
console.log('Valeurs retournées du deserializer:', deserializeAsProtocolRequired(bufvers));

function deserializeAsProtocolRequired(buf) {
    let reader = new bufferReader(buf)
    let requiredVersion = buf.readInt32BE()
    if ( requiredVersion < 0 ) throw new Error('Invalid version !')
    let currentVersion = buf.readInt32BE()
    if ( currentVersion < 0 ) throw new Error('An Error occurred in game version parsing ! :(')

    return { requiredVersion: requiredVersion, currentVersion: currentVersion }
}

Et si j'indique le bon offset :
JavaScript:
function deserializeAsProtocolRequired(buf) {
    let reader = new bufferReader(buf)
    let requiredVersion = buf.readInt32BE[B](0, 4)
    if ( requiredVersion < 0 ) throw new Error('Invalid version !')
    let currentVersion = buf.readInt32BE[B](4, 8)
    if ( currentVersion < 0 ) throw new Error('An Error occurred in game version parsing ! :(')

    return { requiredVersion: requiredVersion, currentVersion: currentVersion }
}
La fonction me retourne :
Code:
Valeurs retournées du deserializer: { requiredVersion: 2048, currentVersion: 439552 }
J'ai enregistré les deux premiers packets que le serv m'envoie à chaque connexion pour gagner du temps.
Ne faites pas attention à la manière dont mes fichiers sont rangés, ce n'est pas un sniffer ni même un bot j'essaye vraiment d'apprendre comment réceptionner des packets :)
 
Dernière édition:
Haut Bas