C/C++ Par où commencer ?

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#21
3 car c'est dofus qui l'a décidé x) je ne suis pas un pro en parsing :p
Sinon oui c'est exactement sa si je me trompe pas
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#22
Ok merci j'essaye ça et je vous tiens au courant !
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#23
Un de mes amis (qui fait du java) m'a dit que cette ligne :

Code:
super.deserialize(param1);
permettais d'appeler la méthode deserialize de la classe parente, c'est donc elle :

Code:
public function deserializeAs_ChatAbstractServerMessage(param1:IDataInput) : void {
         this.channel = param1.readByte();
         if(this.channel < 0)
         {
            throw new Error("Forbidden value (" + this.channel + ") on element of ChatAbstractServerMessage.channel.");
         }
         else
         {
            this.content = param1.readUTF();
            this.timestamp = param1.readInt();
            if(this.timestamp < 0)
            {
               throw new Error("Forbidden value (" + this.timestamp + ") on element of ChatAbstractServerMessage.timestamp.");
            }
            else
            {
               this.fingerprint = param1.readUTF();
               return;
            }
         }
Je pense que ces lignes :

Code:
 this.content = param1.readUTF();
          this.timestamp = param1.readInt();
Code:
this.fingerprint = param1.readUTF();
Sont importantes pour bien faire le truc parce que sinon ca me donnais encore des résultats improbables. Je vous tiens au courant !

EDIT :

Franchement j'ai du mal lol parce que meme avec la classe parente j'arrive a rien de bien. J'ai essayé de passer mon paquet dans un converteur hexa/ascii et ca me donne ca :

Code:
??T??5je defie tout le monde ! rejoignez moi en {map,5,1,2}S)?n??xd8pk40l?Ejp??Coah????
On voit clairement que c'est les 6 premiers octets qui sont utilisés pour qqch et le reste c'est du texte. Mais j'arrive pas trop a récupérer les informations x) ! Et aussi a la fin de la position ({map ....) on a de nouveau des infos
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#24
C'est exact, tu fais un readByte, pour le channel, un readUTF pour le content du message, un readint et un readutf, sa doit etre fait dans l'ordre sinon tu auras des infos erronés.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#25
Et ca je le fait apres les octets du header et celui/ceux (celui en l’occurrence ici) ?

Donc pour mon paquet :
Code:
0dc5540500356a6520646566696520746f7574206c65206d6f6e646520212072656a6f69676e657a206d6f6920656e207b6d61702c352c312c327d5329e96e0008786438706b34306c00456a700004436f616803011301
ce qui donne 0d c5 pour le header, 54 pour la taille et je commence ensuite à partir de 05 pour lire le channel ?

Désolé j'ai un peu de mal pour commencer mais une fois ca compris ca ira mieux x) !
Merci de ton aide en tout cas.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#26
D'abord l'id, le header et tu lis directement le paquet dans l'ordre donné par le message.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#27
Ok parfait !! J'ai réussis !!

Donc voila ce que ça donne à la sortie :
Code:
0dc5 => header id (881)
54 => taille (84)
05 => channel (5)
0035 => taille chaine utf (53)
6a6520646566696520746f7574206c65206d6f6e646520212072656a6f69676e657a206d6f6920656e207b6d61702c352c312c327d => chaine (je defie tout le monde ! rejoignez moi en {map,5,1,2})
5329e96e => timestamp (19/3/2014 à 20:01:02)
0008 => taille chaine utf (8)
786438706b34306c => chaine (xd8pk40l)
00456a70 => id personnage (4 549 232)
0004 => taille chaine utf (4)
436f6168  => chaine (Coah)
03011301 => id du compte (50 402 049)
J'ai mis les valeurs que je trouve entre parenthèses.

En tout cas merci beaucoup de ta patience pour m'avoir expliqué tous ça !!
Maintenant que c'est acquis on va pouvoir envisager d'automatiser.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#28
Content que tu y sois arrivé, bonne soirée.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#29
Re,

désolé de continuer de vous embetez mais maintenant que mes potes et moi avons compris comment désérializer les paquets on commence à coder.
Le soucis c'est qu'en regardant la fonction à coder pour se connecter au serveur, on se demande si il faut aussi recoder les classe parentes, et "grand parents", etc ?

Merci
Deep
 
Inscrit
27 Aout 2012
Messages
264
Reactions
0
#30
Je dirais : ca depend.
Si la classe parente est une classe de la librairie ActionScript, non, tu vas pas la recoder, t'essaye de trouver une alternative en C++.
Sinon, certains paquets dependent d'autres paquets et en héritent, ceux-la tu dois les recoder aussi.
Grosso modo :).
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#31
Par contre c'est une bonne idée de respecter les répertoire non ? Histoire de coller avec l'original et pas etre perdu?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#32
Si tu fais un truc propre de ton coté, mieux vaut faire ta propre structure. Ne copie pas le network de dofus fais le tien.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#33
Ok parce que y'a vraiment des class/interfaces useless (sans aucun code ni méthode pures wtf) ^^ !
 

Kyu

Staff
Membre du personnel
Inscrit
4 Octobre 2009
Messages
327
Reactions
8
#34
Rien de bisard à avoir des interfaces vides, ça sert uniquement pour le polymorphysme.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#35
Salut tout le monde, ça fait longtemps que j'suis pas passé ! Les cours toussa ^^

J'ai une question concernant l'architecture de mon code.
Pour éviter un gros switch ignoble j'avais l'idée de faire une classe parseur dans laquelle j'ai une méthode qui récup l'ID du paquet et cet ID serait l'index d'un vecteur de pointeur sur méthode. Dans chaque méthode j'instancierai la classe qu'il faut pour utiliser le déserializeur.
Est-ce une bonne idée ? Est ce que j'ai besoin de coder du coup des classes spécifiquent ou c'est une meilleure idée d'avoir une grosse classe parseur avec tout les désérializeur à l'intérieur ?

Merci de votre aide :) !

PS: Bon 14 juillet ! (quoique la c'est déjà 1h du mat lol)
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#36
Alors, bien que je n'aie pas beaucoup d'expérience dans les bots ou même les parseurs, j'en ai pas mal dans la prog, et je pense que si tu fais de la traduction automatique des sources de D2, c'est plus pratique de respecter la séparation des classes. Mais si au contraire, tu n'as besoin que de quelques classes, pas besoin de s'embêter pour s'adapter à la structure des sources.
En fait, les deux sont équivalents, mais si tu as une seule classe parseur ce sera peut-être, je dis bien peut-être puisque ça dépend de comment tu gères ton projet, plus propre.
(Et, ma question inutile vient sûrement du fait que j'ai pas touché au C++ depuis 3 ans, mais est-ce qu'il y a un autre moyen pour pointer vers les méthodes que utiliser des pointeurs ? C'est de la pure curiosité...)
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#37
L'appel à la dite méthode oui.
En gros tu as ces deux moyens :

appel traditionnel avec un switch
Code:
void parseur(int id)
{
 switch(id)
 {
  case 1:
   func1();
   break;
  case 2:
   func2();
   break;
 }
}
et la méthode pointeur sur fonction
Code:
typedef void (maClasse::*ptrFunc)();

void  parseur(int id)
{
 // On peut faire l'initialisation du tab de pointeur dans le constructeur
 tab[0] = &maClasse::func1;
 tab[1] = &maClasse::func2;

 // Appel a la bonne méthode sans switch <3
 (this->*tab[id])();
}
Disons que pour entretenir le code, la méthode pointeur est plus simple. On a juste à ajouter une case au tableau. Je pense que niveau rapidité aussi c'est mieux ^^.

Autre question, j'ai un peu de mal (j'suis encore débutant en réseau) à voir comment enchainer mes paquet.
La j'ai fait mon parseur qui envoi dans la bonne classe et sortie de la fonction adéquat, celle-ci renvoi l'ID de la prochaine classe à appeler. Genre je recoit HelloConnectMEssage, je le traite et je renvoi l'ID d'IdentifcationMessage.

Est ce que c'est bien ? Est ce qu'il y a mieux ? Comment vous, vous avez fait :D ?
Merci de votre aide !
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#38
D'accord, merci :) En effet, cela paraît mieux.
Bon, je n'ai pas traité l'authentification, vu que je suis en MITM, et qu'il fallait que j'intercepte un paquet et le modifie, mais je ne pense pas que ce que tu as fait est très pratique, sauf pour l'authentification ou des action purement itératives.
A ta place, je ferais une fonction authentification() qui reçoit HelloConnectMessage puis appelle parseur(42) (je crois), parseur appelle le deserialize qui fait son boulot. Après, retour dans authentification() qui appelle le serialize de IdentificationMessage avec les paramètres adéquats, éventuellement présents dans les arguments de authentification().
Ou alors plus simple, tu appelles directement les classes de l'authentification dans la fonction authentification(), sans t'embêter, puisque le parser sert uniquement quand tu reçois des messages inconnus, alors que l'authentification est un processus distinct en soi, car il respecte un protocole précis et ne dépend pas de l'arbitraire des actions des autres joueurs (sauf pour la connexion au serveur de jeu, mais même là, tu as connaissance des paquets qui te seront envoyés). Pour le reste du jeu, tu peux faire un thread qui reçoit les paquets et modifie les variables du jeu avec les informations qu'il contient, un thread qui est ton AI et qui crée parfois des évènements pour que le troisième thread d'envoi fasse les actions appropriées. Mais pour cette dernière phrase, je ne suis pas totalement sûr parce que je ne suis pas un expert en programmation réseau multi-thread ou évènementielle.

Encore une petite question : pourquoi est-ce que ton parseur reçoit comme argument un id et pas un paquet ? Chez moi, le parseur reçoit un paquet, sépare les informations qu'il contient, et passe les données au deserialize adéquat.
 
Inscrit
1 Mars 2014
Messages
120
Reactions
0
#39
Ok merci je vais faire comme tu dis, une classe authentification, ce sera bien plus simple !
Pour le reste j'verrai comment faire et au pire je sais où poser mes questions :D !

Sinon mon parseur prend bien le paquet en argument, c'était pour simplifier mon exemple :).
Merci beaucoup pour ton aide en tout cas.

A plus tard :D !
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#40
De rien, je pense que je suis plus doué pour expliquer aux autres que pour le faire moi-même :p
Bon, mon avenir de chef de projet tyrannique est tout tracé :lol:

Tu m'as donné envie de me remettre au C++, ce langage tellement beau et solide me manque !
 
Haut Bas