VB/VB.Net CustomDataWrapper

4R7Y

Contributeur
Inscrit
6 Mars 2011
Messages
213
Reactions
0
#1
Salut les potes !

Je me suis relancé dans un p'tit programme, et j'ai voulu le mettre à jour (2 semaines sans l'utiliser et voilà qu'ils sortent des nouveaux reader/writers ! super)

Bref, j'galère un peu sur le CustomDataWrapper

Traduction VB.Net :
Code:
Public Sub writeVarInt(param1 As Integer)
        Dim _loc_5 As Integer = 0
        Dim _loc_2 As Byte = New ByteArray()
        If (param1 >= 0 And param1 <= MASK_01111111) Then
            _loc_2.writeByte(param1)
            Me._data.writeBytes(_loc_2)
            Return
        End If
        Dim _loc_3 As Byte = param1
        Dim _loc_4 As Byte = New ByteArray()
        While (_loc_3 <> 0)
            _loc_4.writeByte(_loc_3 & MASK_01111111)
            _loc_4.position = _loc_4.length - 1
            _loc_5 = _loc_4.readByte()
                _loc_3 = _loc_3 >>> CHUNCK_BIT_SIZE
            If (_loc_3 > 0) Then
                _loc_5 = _loc_5 Or MASK_10000000
            End If
            _loc_2.writeByte(_loc_5)
        End While
        Me._data.writeBytes(_loc_2)
    End Sub


Classe AS3 :
Code:
        public function writeVarInt(param1:int) : void
        {
            var _loc_5:int = 0;
            var _loc_2:* = new ByteArray();
            if (param1 >= 0 && param1 <= MASK_01111111)
            {
                _loc_2.writeByte(param1);
                this._data.writeBytes(_loc_2);
                return;
            }
            var _loc_3:* = param1;
            var _loc_4:* = new ByteArray();
            while (_loc_3 != 0)
            {
                
                _loc_4.writeByte(_loc_3 & MASK_01111111);
                _loc_4.position = _loc_4.length - 1;
                _loc_5 = _loc_4.readByte();
                _loc_3 = _loc_3 >>> CHUNCK_BIT_SIZE;
                if (_loc_3 > 0)
                {
                    _loc_5 = _loc_5 | MASK_10000000;
                }
                _loc_2.writeByte(_loc_5);
            }
            this._data.writeBytes(_loc_2);
            return;
        }// end function

Voilà j'ai ça, mais sa compile pas :
-ByteArray n'existe pas (Bon je suppose que c'est un stream sauf qu'ayant pas fait de vb depuis longtemps je sais plus comment implémenter ça facilement)
-Le décalage de bit vers la droite avec un signe décalé (>>>) n'existe pas en vb, comment le faire ?

Merci bien, bonne journée ! ;)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#2
Tu défini un nouveau writer simplement pour IDataOut.
Pour le >>> Cela decale un byte de maniere unsigned donc tu converti tes bytes en unsigned tu décales les bytes et tu remets sa en signed.
 

Lakh92

Membre Actif
Inscrit
24 Decembre 2009
Messages
118
Reactions
0
#3
C'est une méthode connue.

Un octet est composé de 8 bits. L'idée est de dédié 7 bits à la valeur que tu veux écrire et d'utiliser le dernier pour indiquer si l'octet suivant dans le flux fait partie de la valeur.
Pour une valeur sur 16 bits, mettons que je veuille envoyer 0x5634 :

L'équivalent en binaire de 0x5634 est 0101 0110 0011 0100 (ici on s'en fout un peu de l'endianness mais il faut y penser)
Pour écrire 0x5634 sur le stream, je le décompose en paquets de 7 bits :

0101011 0001101 0000000 (le dernier paquet est rempli de 0 si les 7 bits de son pas atteints)

Il manque un bit à chaque paquet pour faire un octet complet. Pour savoir quelle valeur mettre dans ce dernier bit (le plus haut), on regarde si le paquet courant est le dernier paquet du lot de paquets de 7 bits.
On obtient alors :

1010 1011 1000 1101 0000 0000

Ce qui nous donne 0xAB8B00

On remarque alors que la valeur n'est plus encodée sur 2 octets, mais sur 3.

Enfin... je crois...
 

4R7Y

Contributeur
Inscrit
6 Mars 2011
Messages
213
Reactions
0
#4
Merci de vos réponses !

Voilà ma fonction finale :
Code:
   Public Sub writeVarInt(param1 As Integer)
        Dim _loc_5 As Integer = 0
        Dim _loc_2 As DofusReader = New DofusReader
        If (param1 >= 0 And param1 <= MASK_01111111) Then
            _loc_2.writeByte(param1)
            Me._data.WriteBytes(_loc_2.BytesToSend.ToArray)
            Return
        End If
        Dim _loc_3 As Byte = param1
        Dim _loc_4 As DofusReader = New DofusReader
        While (_loc_3 <> 0)
            _loc_4.writeByte(_loc_3 & MASK_01111111)
            _loc_4.BaseStream.Position = _loc_4.BytesToSend.Count - 1
            _loc_5 = _loc_4.readByte()
            _loc_3 = CInt(CUInt(_loc_3) >> CHUNCK_BIT_SIZE)
            If (_loc_3 > 0) Then
                _loc_5 = _loc_5 Or MASK_10000000
            End If
            _loc_2.writeByte(_loc_5)
        End While
        Me._data.WriteBytes(_loc_2.BytesToSend.ToArray)
    End Sub
Mais je me demandais si
Code:
            _loc_3 = CInt(CUInt(_loc_3) >> CHUNCK_BIT_SIZE)
est ce qu'il faut faire pour une déplacement non signé vers la droite, ou bien s'il est préférable d'utiliser les opérateurs binaires.

Ensuite j'ai un dépassement de capacité, sur cette ligne là :
Code:
            _loc_4.writeByte(_loc_3 & MASK_01111111)
Je ne sais pas trop d'où il sort, peut-être faut il écrire cette ligne :
Code:
        Me._data.WriteBytes(_loc_2.BytesToSend.ToArray)
en endian ?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#5
Tout a l'air parfait sauf le & a remplacer par 'And' en VB.
 

Lakh92

Membre Actif
Inscrit
24 Decembre 2009
Messages
118
Reactions
0
#6
Code:
Dim _loc_3 As Byte = param1
Cette ligne est fausse.
Logiquement, si tu déclares _loc_3 en tant qu'unsigned int, tu ne devrais pas avoir besoin de gérer tous les casts inutiles.
Au moment du writeByte, il faudra juste que tu cast (_loc_3 & 0x7F) en Byte.

Je rajoute quand même que ce que tu fais est plutôt mauvais. Beaucoup d'opérations inutiles...
 

4R7Y

Contributeur
Inscrit
6 Mars 2011
Messages
213
Reactions
0
#7
Je n'ai jamais vraiment manipulé les bytes, juste un petit peu dans le traitement d'image pour créer des filtres.

Je suis conscient que ce que je tente peut avoir l'air idiot ! ;)

Mais merci de votre aide
 
Inscrit
27 Aout 2012
Messages
264
Reactions
0
#8
Je me demandais un truc perso :
Code:
_loc_2.writeByte(param1)
Me._data.WriteBytes(_loc_2.BytesToSend.ToArray)
À quoi ça sert de faire tout ce bordel ?
On peut pas simplement faire un writeByte directement sur la bonne destination au lieu de passer pas un byteArray intermédiaire ?
Même chose un peu plus bas dans la boucle.
 

4R7Y

Contributeur
Inscrit
6 Mars 2011
Messages
213
Reactions
0
#9
Code:
 Public Sub writeVarInt16(ByVal param1 As Integer)
        Dim _loc_5 As Integer = 0
        Dim _loc_2 As New List(Of Byte)
        If (param1 >= 0 And param1 <= MASK_01111111) Then
            _loc_2.Add(param1)
            Me.WriteBytes(_loc_2.ToArray)
            Return
        End If
        Dim _loc_3 As UInteger = param1 And 65535
        Dim _loc_4 As New List(Of Byte)
        While (_loc_3 <> 0)
            _loc_4.Add(CByte(_loc_3 And MASK_01111111))
            '     _loc_4.BaseStream.Position = _loc_4.BytesToSend.Count - 1
            _loc_5 = _loc_4.Item(_loc_4.Count - 1)
            _loc_4.RemoveAt(_loc_4.Count - 1)
            _loc_3 = _loc_3 >> CHUNCK_BIT_SIZE
            If (_loc_3 > 0) Then
                _loc_5 = _loc_5 Or MASK_10000000
            End If
            _loc_2.Add(_loc_5)
        End While
        Me.WriteBytes(_loc_2.ToArray)
    End Sub
J'ai fini par faire comme ça


Mais sinon maintenant la connexion bloque au paquet 151 (réception de la liste des personnages), je sais pas trop pour quoi encore
 

Sorrow

Membre Actif
Inscrit
5 Mai 2012
Messages
376
Reactions
26
#10
Moonlight-Angel a dit:
Je me demandais un truc perso :
Code:
_loc_2.writeByte(param1)
Me._data.WriteBytes(_loc_2.BytesToSend.ToArray)
À quoi ça sert de faire tout ce bordel ?
On peut pas simplement faire un writeByte directement sur la bonne destination au lieu de passer pas un byteArray intermédiaire ?
Même chose un peu plus bas dans la boucle.
Oui c'est inutile, tu peux sauter ce truc.
 
Inscrit
25 Février 2012
Messages
178
Reactions
3
#11
S'il te plait t'as ouvrer ce writeVarInt où ?
J'ai besoin de traduire le writeVarShort pour le packet 42 pour la connexion.

Merci :)
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#12
writeshort = 2 fois writebyte
on a dire que le short est 1200 alors les 2 bytes c'est :
1er : 1200/256 = 4,6875 , mais on s'en fou de ce qu'il ya apres la virgule donc 4
2iem : 1200 - (4 * 256) = 1200 - 1024 = 176 (c'est aussi ce qu'il y'avais apres la virgule)
writeshort(1200) = writebyte(4) et writebyte(176)
 
Inscrit
6 Juin 2012
Messages
41
Reactions
0
#13
Salut
@Natsu go com.ankamagames.jerakine.network.CustomDataWrapper
 
Haut Bas