C# InventoryContentMessage désérialiser

Inscrit
13 Mars 2013
Messages
9
Reactions
1
#1
Bonsoir,

Je m'excuse d'avance pour le dérangement, mais je m'arrache les cheveux sur la désérialisation du packet InventoryContentMessage :(

Voici mon code pas propre du tout, mais que j'ai du simplifier au maximum pour essayer de trouver où pouvait se passer le problème :
Code:
using Elypse.UI;
using Elypse.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Elypse.Protocol.Server.Game.Inventory.Items
{
    public class InventoryContentMessage
    {
        private tabBot _Program;
        public const int _ProtocolID = 3016;
        private DataReader reader;

        public InventoryContentMessage(tabBot parent, byte[] data)
        {
            this._Program = parent;

            this.reader = new DataReader(data);
            deserialize();
        }

        private void deserialize_ObjectItem()
        {
            byte position = reader.ReadByte();
            MessageBox.Show("position = " + position);
            if (position < 0 || position > 255)
            {
                this._Program.Log("Erreur dans la position : " + position);
                return;
            }

            short objectGID = reader.ReadShort();
            MessageBox.Show("objectGID = " + objectGID);
            if (objectGID < 0)
            {
                this._Program.Log("Erreur dans objectGID : " + objectGID);
                return;
            }

            short powerRate = reader.ReadShort();
            bool overMax = reader.ReadBool();

            ushort limit = reader.ReadUnsignedShort();
            MessageBox.Show("LIMIT = " + limit);
            for (int j = 0; j < limit; j++)
            {
                short id = reader.ReadShort();
                short actionID = reader.ReadShort();
                MessageBox.Show("ID = " + id + " ; actionID = " + actionID);
            }

            int objectUID = reader.ReadInt();
            MessageBox.Show("objectUID = " + objectUID);
            if (objectUID < 0)
            {
                this._Program.Log("Erreur dans objectUID : " + objectUID);
                return;
            }

            int quantity = reader.ReadInt();
            MessageBox.Show("quantity = " + quantity);
            if (quantity < 0)
            {
                this._Program.Log("Erreur dans quantity : " + quantity);
                return;
            }
        }

        private void deserialize()
        {
            int nbrObjets = reader.ReadUnsignedShort();
            this._Program.Log("Il y a " + nbrObjets + " objets sur le personnage.");

            for (int i = 0; i < nbrObjets; i++)
            {
                deserialize_ObjectItem();
            }

            int kamas = reader.ReadInt();
            this._Program.Log("Il y a " + kamas + " kamas sur le personnage.");

            //deserialize_ObjectItemTEST();
        }

        

        private void deserialize_ObjectItemTEST()
        {
            byte[] dataToTest = { 0x0C, 0x05, 0x39, 0x00, 0x2A, 0x00, 0x00, 0x01, 0x00, 0x4C, 0x00, 0x7B, 0x07, 0x5B, 0xCD, 0x15, 0x00, 0x00, 0x00, 0x0C };
            DataReader reader2 = new DataReader(dataToTest);

            byte position = reader2.ReadByte();
            MessageBox.Show("position = " + position);
            if (position < 0 || position > 255)
            {
                this._Program.Log("Erreur dans la position : " + position);
                return;
            }

            short objectGID = reader2.ReadShort();
            MessageBox.Show("objectGID = " + objectGID);
            if (objectGID < 0)
            {
                this._Program.Log("Erreur dans objectGID : " + objectGID);
                return;
            }

            short powerRate = reader2.ReadShort();
            bool overMax = reader2.ReadBool();
            MessageBox.Show("powerRate = " + powerRate + " ; overMax = " + overMax);

            ushort limit = reader2.ReadUnsignedShort();
            MessageBox.Show("LIMIT = " + limit);
            for (int j = 0; j < limit; j++)
            {
                short id = reader2.ReadShort();
                short actionID = reader2.ReadShort();
                MessageBox.Show("ID = " + id + " ; actionID = " + actionID);
            }

            int objectUID = reader2.ReadInt();
            MessageBox.Show("objectUID = " + objectUID);
            if (objectUID < 0)
            {
                this._Program.Log("Erreur dans objectUID : " + objectUID);
                return;
            }

            int quantity = reader2.ReadInt();
            MessageBox.Show("quantity = " + quantity);
            if (quantity < 0)
            {
                this._Program.Log("Erreur dans quantity : " + quantity);
                return;
            }
        }
    }
}

Pourtant, quand je me connecte avec un personnage équipé d'une simple panoplie du débutant, j'obtiens :
  • Il y a 13 objets sur le personnage.
    position = 5
    objectGID = 10794
    LIMIT = 3
    ID = 70 ; actionID = 125
    ID = 1 ; actionID = 70
    ID = 174 ; actionID = 1
    objectUID = 4981717
    quantity = 99102742

    position = 0
    objectGID = 0
    LIMIT = 8448
    ...

Or, il y a bien 13 objets sur le personnage, je reçois position = 5, c'est à dire les bottes, 10794 correspond bien à l'ID des bottes, mais je n'ai aucun moyen de vérifier les effets.
De plus, l'objectUID me semble suspect, et la quantité est fausse...

J'ai testé (avec Moonlight-Angel, merci ! :p ) mon DataReader, et il est correct, donc ça ne vient pas de là.

J'ai l'impression que j'oublie de lire une information, ce qui fait que la suite se retrouve faussée...

Quelqu'un aurait une petite idée ? :?

Merci beaucoup !
 
Inscrit
29 Septembre 2011
Messages
393
Reactions
3
#2
Lanquemar a dit:
Bonsoir,
Voici mon code pas propre du tout, mais que j'ai du simplifier au maximum pour essayer de trouver où pouvait se passer le problème :
Je pense que tu a rendu le code plus illisible...

Tu à oublier de lire Item qui est l'heritage de la class ObjectItem
Code:
public class ObjectItem extends Item implements INetworkType
Code:
    public function deserializeAs_ObjectItem(param1:IDataInput) : void {
         var _loc4_:uint = 0;
         var _loc5_:ObjectEffect = null;
         super.deserialize(param1);
         this.position=param1.readUnsignedByte();
Ankamas lis l'heritage avant puis il lis la position de l'item et toi tu lis la position de l'item mais pas l'heritage!

Code:
   private void deserialize_ObjectItem()
        {
            byte position = reader.ReadByte();
            MessageBox.Show("position = " + position);
            if (position < 0 || position > 255)
            {
                this._Program.Log("Erreur dans la position : " + position);
                return;
            }
utilise les héritages tu trouvera mieux t'est erreur car la c'est pas du tous lisible!

J'espère t'avoir aider!
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#3
Tien cadeau j'avais essayé de m'équiper de certain équipement et il me manqué les emplacement donc voilà pour toi:
0|Amulette
1|CAC
2|Anneau
3|Ceinture
4|Anneau 2
5|Chaussure
6|Chapeau
7|Cape
8|Familier
63|Inventaire
 
Inscrit
13 Mars 2013
Messages
9
Reactions
1
#4
Bonjour !
Merci de la réponse ! :)

tifoux a dit:
Tu à oublier de lire Item qui est l'heritage de la class ObjectItem
Oui je le sais, et c'est volontaire parce qu'Item se désérialise comme ceci :
Code:
public function deserializeAs_Item(param1:IDataInput) : void {

}
C'est possible que mon code soit plus illisible oui, mais j'avais commencé par utiliser l'héritage, et j'avais déjà des problèmes, alors j'ai synthétisé le code...

Merci pour les énumérations, mais je les ai déjà ! :p
 
Inscrit
13 Mars 2013
Messages
9
Reactions
1
#5
J'ai quand même remis en place mes classes de départ avec l'héritage, j'ai simplifié comme ceci :
InventoryContentMessage
Code:
using Elypse.Protocol.Server.Types.Game.Data.Items;
using Elypse.UI;
using Elypse.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Elypse.Protocol.Server.Game.Inventory.Items
{
    public class InventoryContentMessage
    {
        private tabBot _Program;
        public const int _ProtocolID = 3016;
        private DataReader reader;

        public ObjectItem[] objects;
        public int kamas = 0;

        public InventoryContentMessage(tabBot parent, byte[] data)
        {
            this._Program = parent;

            this.reader = new DataReader(data);
            deserialize();
        }

        private void deserialize()
        {
            ushort limit = reader.ReadUnsignedShort();
            this._Program.Log("Il y a " + limit + " objets sur le personnage.");

            this.objects = new ObjectItem[limit];

            for (int i = 0; i < limit; i++)
            {
                this.objects[i] = new ObjectItem(this._Program);
                this.objects[i].deserialize(reader);
            }

            this.kamas = reader.ReadInt();
            this._Program.Log("Il y a " + kamas + " kamas sur le personnage.");
        }
    }
}
ObjectItem
Code:
using Elypse.Protocol.Server.Types.Game.Data.Items.Effects;
using Elypse.UI;
using Elypse.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Elypse.Protocol.Server.Types.Game.Data.Items
{
    public class ObjectItem : Item
    {
        private tabBot _Program;
        public const int _ProtocolID = 37;

        public byte position = 63;
        public short objectGID = 0;
        public short powerRate = 0;
        public bool overMax = false;
        public ObjectEffect[] effects;
        public int objectUID = 0;
        public int quantity = 0;

        public ObjectItem(tabBot parent) : base(parent)
        {
            this._Program = parent;
        }

        public void deserialize(DataReader reader)
        {
            base.deserialize(reader);
            this.position = reader.ReadByte();
            if (position < 0 || position > 255)
                this._Program.Log("Erreur dans la position, position = " + position);
            MessageBox.Show("position = " + position);
            this.objectGID = reader.ReadShort();
            if (objectGID < 0)
                this._Program.Log("Erreur dans l'objectGID, objectGID = " + objectGID);
            MessageBox.Show("objectGID = " + objectGID);
            this.powerRate = reader.ReadShort();
            this.overMax = reader.ReadBool();
            MessageBox.Show("powerRate = " + powerRate + " ; overMax = " + overMax);
            ushort limit = reader.ReadUnsignedShort();
            MessageBox.Show("limit = " + limit);
            this.effects = new ObjectEffect[limit];
            for (int i = 0; i < limit; i++)
            {
                short a = reader.ReadShort();
                MessageBox.Show("a = " + a);
                this.effects[i] = new ObjectEffect(this._Program);
                this.effects[i].deserialize(reader);
            }
            this.objectUID = reader.ReadInt();
            if (this.objectUID < 0)
                this._Program.Log("Erreur dans l'objectUID, objectUID = " + objectUID);
            this.quantity = reader.ReadInt();
            if (this.quantity < 0)
                this._Program.Log("Erreur dans quantity, quantity = " + quantity);
        }
    }
}
Item
Code:
using Elypse.UI;
using Elypse.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Elypse.Protocol.Server.Types.Game.Data.Items
{
    public class Item
    {
        private tabBot _Program;
        public const int _ProtocolID = 7;

        public Item(tabBot parent)
        {
            this._Program = parent;
        }

        public void serialize(DataWriter writer)
        {

        }

        public void deserialize(DataReader reader)
        {

        }
    }
}
ObjectEffect
Code:
using Elypse.UI;
using Elypse.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Elypse.Protocol.Server.Types.Game.Data.Items.Effects
{
    public class ObjectEffect
    {
        private tabBot _Program;
        public const int _ProtocolID = 76;

        public short actionID = 0;

        public ObjectEffect(tabBot parent)
        {
            this._Program = parent;
        }

        public void serialize(DataWriter writer)
        {
            writer.WriteShort(actionID);
        }

        public void deserialize(DataReader reader)
        {
            actionID = reader.ReadShort();
            if (actionID < 0)
                this._Program.Log("Erreur sur l'ActionID, ActionID = " + actionID);
        }
    }
}

Mais ça ne change rien, j'ai toujours les mêmes résultats, et le même problème :(

Merci pour les réponses ! :)
 
Inscrit
13 Mars 2013
Messages
9
Reactions
1
#6
J'ai continué mon débogage (à la main), et mes données à traiter se présentent comme ceci (uniquement le début) :
00 0D 05 2A 2A 00 00 01 00 03 00 46 00 7D 00 01
00 46 00 AE 00 01 00 4C 03 D5 06 7F BE E4 00 00
00 01 02 2A 21 00 00 01 00 03 00 46 00 7D 00 01
00 46 00 AE 00 01 00 4C 03 D5 06 7F BE E5 00 00
00 01

Si je décompose :

  • 00 0D = 13 -> nombre d'objets dans l'inventaire : correct.
    05 = 5 -> position 5, c'est à dire les bottes : correct.
    2A 2A = 10794 -> objectGID, l'ID des bottes : correct.
    00 00 = 0 -> powerRate, je pense que c'est correct.
    01 = true -> overMax, je pense que c'est correct.
    00 03 = 3 -> limit à 3, c'est à dire 3 effets : correct.
    00 46 & 00 7D = 70 & 125 -> l'effet et l'actionID numéro 1, je pense que c'est correct.
    00 01 & 00 46 = 1 & 70 -> l'effet et l'actionID numéro 2, je pense que c'est correct.
    00 AE & 00 01 = 174 & 1 -> l'effet et l'actionID numéro 3, je pense que c'est correct.
    00 4C 03 D5 = 4981717 -> objectUID, je ne sais pas si c'est correct ou pas...
    06 7F BE E4 = 109035236 -> un int (ou 4bytes), je sais pas à quoi elles servent => mon problème ?
    00 00 00 01 = 1 -> la quantité, qui est correct ici !

Donc j'ai un décalage de 4bytes, je ne sais pas comment ça se fait, et quand j'essaye de compenser ces bytes (en avançant dans ma lecture de 4), j'ai quand même une erreur plus loin car ces 4 bytes se compensent seules et disparaissent...

Quelqu'un aurait une idée ? Sivouplé ? :p
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#7
InventoryContentMessage
Code:
private void deserialize()
        {
            ObjectItem _loc_4 = null;
dynamic _loc_2 = reader.readUnsignedShort();
for (i = 0; i <= _loc_2; i++) {
	_loc_4 = new ObjectItem();
	_loc_4.deserialize(reader);
	_objects.@add(_loc_4);
}
_kamas = param1.readInt();
        }
ObjectItem
Code:
private void deserialize(DataReader reader)
        {
uint _loc_4 = 0;
ObjectEffect _loc_5 = null;
base.deserialize(param1);
_position = param1.readUnsignedByte();
_objectGID = param1.readShort();
_powerRate = param1.readShort();
_overMax = param1.readBoolean();
dynamic _loc_2 = param1.readUnsignedShort();
for (i = 0; i <= _loc_2; i++) {
	_loc_4 = param1.ReadUnSignedshort();
	_loc_5 = ProtocolTypeManager.GetInstance(_loc_4);
	_loc_5.Deserialize(param1);
	_effects.Add(_loc_5);
}
_objectUID = param1.readInt();
_quantity = param1.readInt();
}
ObjectEffect
Code:
public void deserialize(DataReader reader)
        {
            _actionId == param1.readShort()
        }
J'ai traduit à ma facon, je ne code pas en C#, j'ai fais de mon mieux.
Il y a peut être des erreurs mais essaye.

EDIT:
Evite ce genre de chose:
private DataReader reader;
Met plutot des arguments à tes fonctions.
 
Inscrit
13 Mars 2013
Messages
9
Reactions
1
#8
Merci lolodu93 :)

J'ai trouvé mon problème, et ce n'était pas ça :?

Je réécris moi même les packets pour organiser comme je le souhaite mon projet et pour essayer de comprendre le maximum de chose, et donc mon problème se trouvait sur cette ligne :
Code:
_loc5_=ProtocolTypeManager.getInstance(ObjectEffect,_loc4_);
Je pensais que cette ligne était là pour créer un nouvel objet de type ObjectEffect, et donc je désérialisais la suite du packet comme si je désérialisais un ObjectEffect (avec l'actionID)..
Sauf qu'en fait, ce n'est pas exactement ça, Moonlight-Angel m'a aidé à me mettre sur la piste (merci beaucoup !!! :p), et donc la ligne ci dessus va créer un nouvel objet, mais la classe de ce type dépend de loc4..
C'est à dire que si loc4 vaut 76, alors loc5 sera bien un ObjectEffect, mais par contre si loc4 vaut 70, alors loc5 sera un ObjectEffectInteger, et il faut alors désérialiser le packet comme un ObjectEffectInteger... D'où mon décalage dans les bytes :?

Je ne sais pas si mon explication va aider quelqu'un, mais bon, on ne sait jamais :)

Enfin bref, j'ai trouvé, merci beaucoup à ceux qui m'ont aidé ! :D
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#9
Ca m'étais arrivé aussi a mon commencement, ton explication est très clair quelqu'un qui a le même souci devrait comprendre.

Cordialement
 
Haut Bas