C# Parsing DLM

Inscrit
25 Novembre 2015
Messages
111
J'aime
50
#1
Bonjour, je me heurte à un problème sur le parsing des .dlm, lors du parsing des elements (enfin je les skip c'est pas des données intéressantes côté serveur), j'ai une valeur suspicieuse sur le count de ces element, pourtant j'ai la même chose que ce qui se passe côté client pour le parsing et les valeurs d'avant sont correct, voici la sortie :

Map with id : 119013380, relativeId : 119016221, type : 1, version : 11, subAreaId : 98, top : 119013379, bot : 119013381, left : 119144964, right : 119013892, shadowBonus : -1, UseReverb : False, BackgroundsCount : 0, ForegroundsCount : 0
Layers : 43
Cells : 512
- CellId : 187
- Elements : 29696
[23-02-2019 | 16:12:24][Fatal] System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: elementType
Voici le code du jeu :

C#:
            this.cellId = raw.readShort();
            if(AtouinConstants.DEBUG_FILES_PARSING)
            {
               _log.debug("    (Cell) Id : " + this.cellId);
            }
            this.elementsCount = raw.readShort();
            if(AtouinConstants.DEBUG_FILES_PARSING)
            {
               _log.debug("    (Cell) Elements count : " + this.elementsCount);
            }
            this.elements = new Vector.<BasicElement>(this.elementsCount,true);
            for(i = 0; i < this.elementsCount; i++)
            {
               be = BasicElement.getElementFromType(raw.readByte(),this);
               if(AtouinConstants.DEBUG_FILES_PARSING)
               {
                  _log.debug("    (Cell) Element at index " + i + " :");
               }
               be.fromRaw(raw,mapVersion);
               this.elements[i] = be;
Et mon code (qui regroupe avec le layer comme je skip) :


C#:
        public DlmMap Parse(IReader reader)
        {
            if(reader.ReadValue<sbyte>() != 77) throw new InvalidOperationException(".dlm file corrupted");
            var map = new DlmMap { Version = reader.ReadValue<sbyte>(), Id = (int) reader.ReadValue<uint>() };

            if (map.Version >= 7)
            {
                var isEncrypted = reader.ReadValue<bool>();
                reader.Skip(1); // skip encryptedVersion
                var count = reader.ReadValue<int>();

                if (isEncrypted)
                {
                    var decryptedData = reader.ReadValues<byte>(count);
                    for (var i = 0; i < count; i++)
                        decryptedData[i] =
                            (byte)(decryptedData[i] ^ DlmHelper.DecryptionKey[i % DlmHelper.DecryptionKey.Length]);
                    reader = ServiceLocator.Container.GetInstance<IReader>(decryptedData);
                }
            }

            map.RelativeId = (int) reader.ReadValue<uint>();
            map.Type = reader.ReadValue<sbyte>();
            map.SubAreaId = reader.ReadValue<int>();
            map.TopNeighbourId = reader.ReadValue<int>();
            map.BottomNeighbourId = reader.ReadValue<int>();
            map.LeftNeighbourId = reader.ReadValue<int>();
            map.RightNeighbourId = reader.ReadValue<int>();
            map.ShadowBonusOnEntities = reader.ReadValue<int>();

            #region Skipped values

            if (map.Version >= 9) reader.Skip(8); // skip colors + gridColor
            if (map.Version >= 3) reader.Skip(3); // skip backgroundRed + Green + Blue
            if (map.Version >= 4) reader.Skip(6); // skip zoomScale + zoomOffsetX + Y
            if (map.Version > 10) reader.Skip(4); // skip tacticalModeTemplateId
            reader.Skip(1); // skip useLowPassFilter

            var useReverb = reader.ReadValue<bool>();
            if (useReverb) reader.Skip(4); // skip presetId

            var backgroundsCount = reader.ReadValue<sbyte>();
            for (var i = 0; i < backgroundsCount; i++) reader.Skip(DlmHelper.SizeOfFixture);

            var foregroundsCount = reader.ReadValue<sbyte>();
            for (var i = 0; i < foregroundsCount; i++) reader.Skip(DlmHelper.SizeOfFixture);
            reader.Skip(4); // not used read int on d2 src
            reader.Skip(4); // skip groundCRC

            var layersCount = reader.ReadValue<sbyte>();
            for (var i = 0; i < layersCount; i++)
            {
                reader.Skip(map.Version >= 9 ? 4 : 1); // inverted on dofus src but i got the right value this way wtf ??
                var cellsCount = reader.ReadValue<short>();
                if (cellsCount < 1) continue;
                for (var j = 0; j < cellsCount; j++)
                {
                    //reader.Skip(2); // skip cellId
                    var cellId = reader.ReadValue<short>();
                    var elementsCount = reader.ReadValue<short>(); // suspicious value here (29696, greater than file size), throw then
                    for (var k = 0; k < elementsCount; k++)
                    {
                        var elementType = (ElementTypes)reader.ReadValue<byte>();
                      
                        switch (elementType)
                        {
                            case ElementTypes.Graphical:
                                reader.Skip(15);
                                reader.Skip(map.Version <= 4 ? 2 : 4);
                                break;
                            case ElementTypes.Sound: reader.Skip(18);
                                break;
                            default: throw new ArgumentOutOfRangeException(nameof(elementType));
                        }
                    }
                }
            }
            #endregion

            for (var i = 0; i < DlmHelper.MaxCells; i++)
            {
                var cell = new DlmCellParser(map).Parse(reader);
                cell.Id = i;
                map.Cells.Add(cell);
            }

            return map;
        }
    }

Lorsque je remplace elementsCount par un readByte j'ai 116 en value ce qui semble plus déjà plausible, mais les valeurs ensuite sont erronés (j'ai quelques graphical elements dans le tas mais le reste ce sont des valeurs erronés style 0, -57...)

Je vous remercie d'avance pour votre aide !
 
Dernière édition:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
1 833
J'aime
210
#5
Je ne vois rien de particulier dans ton code, assez proche du mien.
Tu es sûr qu'avant le elemCount, les valeurs sont 100% officielles ?
 
Haut Bas