Autre Petite question

Inscrit
27 Juin 2012
Messages
238
Reactions
0
#1
Bonjour tout le monde,

J'ai commencé tranquillement à développé, je reçois maintenant les paquets 1 et 3, mais une question vient à mon esprit.

J'ai regardé dans différentes sources disponibles et sur le forum mais aucun sujet n'en parle. C'est une question plutôt bête et vous saurez sans doute m'aider.
J'ai compris à travers les lectures du forum que les échanges entre le client et serveur suivaient une trame, c'est à dire que l'on reçoit le paquet 1, puis 3 et l'on envoie le paquet 4.

Dans les différents tutoriels on nous explique comme traité nos paquets pour en extraire l'info. Mais pas pour interagir avec les autres paquets.
Par exemple pour le paquet 4, je dois prendre les infos du paquet 3, mais comment je peux savoir que le paquet 3 est arrivé, et dans le cas où il est arrivé où je récupère ces données ?

Je fais un pool avec tous mes objets messages et si le message précédent est arrivée je vais chercher les infos ?

Je ne sais pas si je m'exprime clairement ou du moins si vous comprenez ce que j'essaye de dire :lol:

Merci par avance :D
 
Inscrit
27 Aout 2012
Messages
264
Reactions
0
#2
Depuis quand deux paquets ont besoin de communiquer entre eux ?
Quand un paquet tient des infos d'un autre paquet, il en hérite et donc toutes les propriétés sont reçues en un seul paquet (l'héritage quoi).

Après, si tu parles des types et autres joyeusetés, ce ne sont pas vraiment des paquets réseaux mais des classes de stockage (dé)sérialisées depuis les données d'un paquet réseau.
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#3
Quand je dis que les packets communiquent entre eux c'est plutôt un paquet qui a besoin des infos d'un autre packet (par exemple HelloConnect et identification).
Il faudrait que je traite la réception du packet 3 et l'envoi du 4 direct après pour keep les valeurs dans une méthode ?

Je suis tellement une bite en archi haha.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#4
Bah tu créer un dossier data ou tu archives tout ce que tu reçois ;)
 

neross

Membre Actif
Inscrit
20 Decembre 2014
Messages
150
Reactions
0
#5
Tu stock les données du packet trois, tu vérifie ces données, si c'est bon tu renvois 4 puis si c'est mauvais tu renvois l'Erreur. :)
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#6
Oui mais dans une gestion dynamique des packets tu fais comment ?
Tu peux pas traiter tout les packets de la même façon s'il y a un ordre d'enchaînement, faut avoir une méthode par "intelligence" et règle de gestion ?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#7
Alors la je te redirige dans la section 'Projet' du forum pour étudier quelque codes sources de bot.
BiM, EuuBot et bien d'autres...
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#8
Justement j'ai fait EuuBot en long en large et en travers et j'ai pas trouvé. :(
Sauf si j'ai pas regardé la bonne classe je ne sais pas.

Et BiM je me noie dedans c'est chaud ^^'

En fait quand on reçoit un packet dans notre buffer, on analyse le packetID et on créer une instance de la classe en fonction de l'ID (grâce à l'enum).
Mais après je ne sais pas quoi faire je bloque.

Quelqu'un connaîtrait la classe à regardé (ou au moins le dossier) car là je me perds :(

Merci d'avance,

EDIT : J'ai pas encore été voir du côté des sources VB mais si vous avez quand même un indice je veux bien :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#9
C'est celui de BiM en modifié (amélioré ?):

Code:
private void WritePacket(IDataWriter writer, uint MessageId)
        {
            byte[] packet = writer.Data;

            writer.Clear();

            byte typeLen = ComputeTypeLen(packet.Length);
            var header = (short)SubComputeStaticHeader(MessageId, typeLen);
            writer.WriteShort(header);

            switch (typeLen)
            {
                case 0:
                    break;
                case 1:
                    writer.WriteByte((byte)packet.Length);
                    break;
                case 2:
                    writer.WriteShort((short)packet.Length);
                    break;
                case 3:
                    writer.WriteByte((byte)(packet.Length >> 16 & 255));
                    writer.WriteShort((short)(packet.Length & 65535));
                    break;
                default:
                    throw new System.Exception("Packet's length can't be encoded on 4 or more bytes");
            }
            writer.WriteBytes(packet);
        }

        private static byte ComputeTypeLen(int param1)
        {
            if (param1 > 65535)
                return 3;

            if (param1 > 255)
                return 2;

            if (param1 > 0)
                return 1;

            return 0;
        }

        private static uint SubComputeStaticHeader(uint id, byte typeLen)
        {
            return id << 2 | typeLen;
        }
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#10
Ça je comprends bien comment écrire le packet.
Mais l'intelligence de la création du packet, tu le fais où ?

Typiquement ça tiré du post de weeman, il le fait où ?

Et voici comment je construit mon paquet :

Code:
// [Reception] HelloConnectMessage
                    Protocol.Messages.Connection.HelloConnectMessage HelloConnectMessage = new BotDofus.Protocol.Messages.Connection.HelloConnectMessage();
                    HelloConnectMessage.Deserialize(reader);
                    
                    Log("Taille de la clé : "+ HelloConnectMessage.m_key.Count +"\r\n");
                    
                    // [Envoi] IdentificationMessage
                    Protocol.Messages.Connection.IdentificationMessage IdentificationMessage = new BotDofus.Protocol.Messages.Connection.IdentificationMessage();
                    byte[] credentials = Crypto.RSAManager.Encrypt(HelloConnectMessage.m_key, HelloConnectMessage.m_salt, textBoxAccount.Text, textBoxPassword.Text);
                    
                    Protocol.Types.Version.VersionExtended VersionExtended = new Protocol.Types.Version.VersionExtended();
                    VersionExtended.Init(2, 26, 1, 91397, 2, 0, 1, 1);
                    
                    IdentificationMessage.Init(true, false, false, VersionExtended, "fr", credentials, 0, 0);
                    
                    Common.IO.CustomDataWriter writer = new Common.IO.CustomDataWriter();
                    
                    IdentificationMessage.Serialize(writer);
                    
                    Console.WriteLine(writer.Data);
                    _Socket.Send(writer.Pack(IdentificationMessage.ProtocolId, writer.Data));
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#11
Ah il y a un système de Frame. Va voir du côté du dossier de la classe 'MessageHandler' ou 'MessageAttribute'
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#12
Tiens, un truc totalement inconnu au bataillon, merci Alex, de BiM ou des sources Dofus ?
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#14
Ah mais c'est génial ce truc, on met tout dans le ClientInformations, et on va piocher quand on reçoit les packets, et si les infos sont vide on retourne en erreur.

Merci Alex, je vais faire ça :D

J'ai juste une dernière petite question, les "Handlers" qui mette à jour le ClientInformations, sont appelé où ? J'ai fais une recherche sur le projet et pas une trace de ces Handlers à part sur la classe elle même :/
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#15
D'après ce que j'ai pu comprendre, ce qu'il y a au dessus des Handlers, sont des attributs, et lorsque l'on reçoit le message on chope l'handler correspondant grâce à l'attribut (ça reste encore obscur ça) et on lance.

handler.Action(handler.Container, token, message);

J'ai bien saisi la chose ?
 
Inscrit
27 Aout 2012
Messages
264
Reactions
0
#16
C'est plus ou moins ça. Ça s'appelle la réflexion. Pouvoir rechercher au runtime une classe et parcourir ses methodes/propriétés.
C'est utilisé entre autre dans le traitement de paquets (sur BiM). Ça évite de se taper un switch gigantesque. Il cherche dans toutes les classes qui héritent de NetworkMessage (la mère de tous les messages) celui dont la propriété ProtocolID est égale à l'ID du paquet qu'on vient de recevoir.
 

Kyu

Staff
Membre du personnel
Inscrit
4 Octobre 2009
Messages
327
Reactions
8
#17
Utiliser une collection pour mapper les id avec leur classe ne serait pas plus optimisé?
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#18
Je sais ce qu'est la réflexion Moon, juste là je n'arrive pas à percevoir la chose.
Je n'ai jamais utilisé les attributs avant en C# c'est pour ça.

Car il y a une méthode getHandlers (qui je pense récupére toutes les méthodes de Handlers) mais je ne vois pas de règle de gestion où il dit "je veux le handler du type de mon message" :(
Si quelqu'un sait où cette chose est située.

@Jones : Là c'est pas pour ça il me semble. Moi j'ai fais un .CreateInstance avec le type de message récupérer grâce à l'ID et l'Enum. Et ensuite j'appelle la méthode deserialize.
 
Inscrit
27 Aout 2012
Messages
264
Reactions
0
#19
jones a dit:
Utiliser une collection pour mapper les id avec leur classe ne serait pas plus optimisé?
Ça j'en sais rien. Niveau perfs, je ne sais pas ce que la réflexion donne, à mon avis la liste doit être un poil plus opti, mais j'en ai aucune idée.
En revanche, une chose dont je suis sûr, c'est que pour un mec flemmard comme moi, la réflexion c'est le Graal.
Donc si cette dernière est légèrement plus lente au runtime, ça m'empêchera pas de l'utiliser quand même. :D

Neewd a dit:
Je sais ce qu'est la réflexion Moon, juste là je n'arrive pas à percevoir la chose.
Je n'ai jamais utilisé les attributs avant en C# c'est pour ça.

Car il y a une méthode getHandlers (qui je pense récupére toutes les méthodes de Handlers) mais je ne vois pas de règle de gestion où il dit "je veux le handler du type de mon message" :(
Si quelqu'un sait où cette chose est située.
Les handlers sont appelés à la réception d'un message réseau. Le message est dispatché dans une fonction en-dessous de getHandlers si je dis pas de conneries (Dispatch()).
 
Inscrit
27 Juin 2012
Messages
238
Reactions
0
#20
Ouais MA, j'ai réussi à suivre la trame du message et c'est cette fonction qui reste obscure pour moi .

protected IEnumerable<MessageHandler> GetHandlers(Type messageType, object token)
{
foreach (var list in m_nonSharedHandlers.Values.Concat(m_handlers.Values).ToArray()) // ToArray : to avoid error if handler are added in the same time
{
List<MessageHandler> handlersList;
if (list.TryGetValue(messageType, out handlersList))
foreach (var handler in handlersList)
if (token == null || handler.TokenType.IsInstanceOfType(token))
yield return handler;
}

// note : disabled yet.

// recursivity to handle message from base class
//if (messageType.BaseType != null && messageType.BaseType.IsSubclassOf(typeof(Message)))
// foreach (var handler in GetHandlers(messageType.BaseType, token))
// {
// if (handler.Attribute.HandleChildMessages)
// yield return handler;
// }
}
 
Haut Bas