Bien le bonjour pour mon premier tutoriel sur Cadernis !
Ici nous allons voir les bases pour traduire les fichiers Action Script (AS) du fichier D*fusInvoker en VB.Net.
Prenons une class quelconque pour ces bases.
Bases
Ici j'ai choisi le 1er packet envoyé par le serveur (et donc reçu par le client) il s'agit de :
HelloConnectMessage
Cliquez pour révéler
Cliquez pour masquer
package com.ankamagames.dofus.network.messages.connection
{
import com.ankamagames.jerakine.network.*;
import flash.utils.*;
public class HelloConnectMessage extends NetworkMessage implements INetworkMessage
{
private var _isInitialized:Boolean = false;
public var connectionType:uint = 1;
public var key:String = "";
public static const protocolId:uint = 3;
public function HelloConnectMessage()
{
return;
}// end function
override public function get isInitialized() : Boolean
{
return this._isInitialized;
}// end function
override public function getMessageId() : uint
{
return 3;
}// end function
public function initHelloConnectMessage(param1:uint = 1, param2:String = "") : HelloConnectMessage
{
this.connectionType = param1;
this.key = param2;
this._isInitialized = true;
return this;
}// end function
override public function reset() : void
{
this.connectionType = 1;
this.key = "";
this._isInitialized = false;
return;
}// end function
override public function pack(param1:IDataOutput) : void
{
var _loc_2:* = new ByteArray();
this.serialize(_loc_2);
writePacket(param1, this.getMessageId(), _loc_2);
return;
}// end function
override public function unpack(param1:IDataInput, param2:uint) : void
{
this.deserialize(param1);
return;
}// end function
public function serialize(param1:IDataOutput) : void
{
this.serializeAs_HelloConnectMessage(param1);
return;
}// end function
public function serializeAs_HelloConnectMessage(param1:IDataOutput) : void
{
param1.writeByte(this.connectionType);
param1.writeUTF(this.key);
return;
}// end function
public function deserialize(param1:IDataInput) : void
{
this.deserializeAs_HelloConnectMessage(param1);
return;
}// end function
public function deserializeAs_HelloConnectMessage(param1:IDataInput) : void
{
this.connectionType = param1.readByte();
if (this.connectionType < 0)
{
throw new Error("Forbidden value (" + this.connectionType + ") on element of HelloConnectMessage.connectionType.");
}
this.key = param1.readUTF();
return;
}// end function
}
}
Nous allons séparer ce code en plusieurs parties
=> L'en-tête
package com.ankamagames.dofus.network.messages.connection
{
import com.ankamagames.jerakine.network.*;
import flash.utils.*;
Pour chaque traduction, vous pouvez supprimer les imports AS pour les remettre une fois le fichier traduits
package com.ankamagames.dofus.network.messages.connection
Voici l'espace de nom de la class, en VB.Net pour déclarer cet espace, nous utilisons "Namespace"
=>
Namespace com.ankamagames.dofus.network.messages.connection
N'oubliez pas le End Namespace, en fin de class pour ne pas avoir d'erreur
=> Le nom et les instanciations possible
public class HelloConnectMessage extends NetworkMessage implements INetworkMessage
-Le nom, ici pas de secret : HelloConnectMessage
Mais que signifie cet "extends" ?
Ici, il ne nous est pas utile, nous reverrons plus tard
-implements INetworkMessage. C'est bien un message, et non un type (INetworkType)
Supprimons ce qui ne nous intéresse pas :
public class HelloConnectMessage
On avance !!
=> Les déclarations de variables
private var _isInitialized:Boolean = false;
public var connectionType:uint = 1;
public var key:String = "";
public static const protocolId:uint = 3;
- Private / Public Ici c'est le niveau d'accessibilité de la variable, pas besoin de changer c'est la même chose en VB
- var / static const var (comme variable) et donc qui peut changer / static const (comme constante et donc statique), qui ne changera pas
- Ensuite c'est le nom de cette variable
- : (se traduit par As en vb.net)
- Le type de la variable (Boolean, String, Uinteger, etc ..)
- = XXX; valeur par défaut de cette variable.
Traduisons :
private _isInitialized As Boolean = false
public connectionType As uinteger = 1
public key As String = ""
public protocolId As uinteger = 3
Tadada, pas dur !
=> Les fonctions
Prenons la fonction qui nous intéresse dans la plupart des cas (utilise pour obtenir les informations envoyée par le serveur) : Deserialize
public function deserialize(param1:IDataInput) : void
{
this.deserializeAs_HelloConnectMessage(param1);
return;
}// end function
public function deserializeAs_HelloConnectMessage(param1:IDataInput) : void
{
this.connectionType = param1.readByte();
if (this.connectionType < 0)
{
throw new Error("Forbidden value (" + this.connectionType + ") on element of HelloConnectMessage.connectionType.");
}
this.key = param1.readUTF();
return;
}// end function
L'avantage du VB, c'est qu'il simplifie grandement la vie
Alors, commençons la 1ère ligne
public function deserialize(param1:IDataInput) : void
Cette fonction est donc publique, et à un argument : param1.
IDataInput
Data, de l'anglais : donnée
Input, de l'anglais : entrée
C'est donc une entrée de donnée : de la lecture de donnée !
IDataInput se remplacera alors par votre DataReader (Votre lecteur de donnée pour les anglophobe)
-Le : void, on le vire, VB.net n'en a pas besoin
Public function deserialize(Byval param1 as tonDataReader)
-> Ensuite !
this.deserializeAs_HelloConnectMessage(param1);
return;
}// end function
This, pas de secret : se traduit par "Me" en Vb, fait donc référence à la class sur laquelle on travaille actuellement.
Ici on appelle la fonction deserializeAs_HelloConnectMessage
les ;, on les enlève, VB n'en a pas besoin
Et c'est une fonction, pas un Sub donc on retourne une valeur (Me par exemple :p)
End function, je crois que c'est clair. Sauf qu'ici il est en commentaire (ça nous simplifie la vie, fainéant que nous sommes) donc on a juste à supprimer les 3 caractères devant
Nous avons donc
Me.deserializeAs_HelloConnectMessage(param1)
return me
end function
On a appelé une fonction, allons voir ce qu'il s'y passe !
public function deserializeAs_HelloConnectMessage(param1:IDataInput) : void
{
this.connectionType = param1.readByte();
if (this.connectionType < 0)
{
throw new Error("Forbidden value (" + this.connectionType + ") on element of HelloConnectMessage.connectionType.");
}
this.key = param1.readUTF();
return;
}// end function
- 1ere ligne : rien de nouveau
- 2eme ligne : param1.readByte ici on fait appel à une fonction de votre reader, j'espère qu'il est bien rodé :)
- Les if ne sont pas utiles, on supprime (mais attention, on ne supprime que le If et l'intérieur de la condition !)
- Pareil que pour la 1ere ligne
- Fin de la fonction
On traduis !!
public function deserializeAs_HelloConnectMessage(Byval param1 As tonDataReader)
me.connectionType = param1.readByte()
me.key = param1.readUTF()
return me
end function
Voilà, c'est tout pour cette fonction qui vous servira très souvent
Mais tout de même faites attention il y a des règles à respecter :
-Toujours traduire de la même manière qu'Ank4ma l'a faite
par exemple
me.key = param1.readUTF()
me.connectionType = param1.readByte()
est faux !
En effet, le serveur nous envoie une valeur, c'est à nous de nous adapter à ce que le serveur nous envoie et pas l'inverse
Sinon Me.key aura la valeur de Me.connectionType et me.connectionType aura la valeur de me.key (erreur, impossible d'effectuer une conversion de type "String" vers "Integer") et de plus les valeur seront totalement absurde.
-Ne jamais supprimer une ligne de lecture de donnée, même si vous ne comprenez pas ce que cette ligne veut dire. Sinon de la même manière que précédemment il y aura un décalage dans le flux de donnée, et là, c'est le drame.
Exemple très simple :
Le serveur m'envoie trois données
-True (Boolean)
-15 (Integer)
-"Coucou la pêche ?" (String)
Donc ces trois données se baladent, et pouf, arrivent sur ton client.
Le client à l'instruction de lire ces données (et est donc programmer pour qu'elles arrivent dans cet ordre là)
Donc il va se dire :
On m'a programmé pour que je lise trois données, La première en boolean, la seconde en Integer et la troisième en String. J’exécute !
Me.maValeurBoolean = param1.ReadBoolean 'True
Me.maValeurInteger = param1.ReadInteger '15
Me.maValeurString = param1.ReadString '"Coucou la pêche ?"
Voilà ce que fais le client.
Et si toi, gros malin, sur ton bot tu oublie de lire une ligne, il se crée un décalage ! Et oui, le serveur les a envoyé dans un ordre précis, à toi de le respecter !
Me.maValeurBoolean = param1.ReadBoolean 'On récupère True => Bien, il fallait lire sa en premier !
Me.maValeurString = param1.ReadString 'On devrait lire 15 mais on lit un nombre improbable (Fonction ReadString programmée pour lire un String pas un Integer) => Beurk pas propre
Me.maValeurInteger = param1.ReadInteger 'On récupère "Coucou la pêche ?", plus le décalage d'avant => Erreur
Je mettrais à jour ce tuto quand j'aurais plus de temps.
Pour toute infos, demande supplémentaires, hésitez pas à poster des commentaires (il se peut que j'explique mal/que je ne sois pas très clair dans mes propos)