예제 #1
0
        /// <summary>
        /// Deserializes the data elements from the internal buffer.
        /// </summary>
        /// <remarks></remarks>
        private void ReadData()
        {
            // Read version
            string version = _buffer.ReadString(4);

            if (version != "1.21")
            {
                throw new InvalidDataException($"Invalid primary file version: '{version}'");
            }

            // Read remaining file header
            _buffer.ReadUInteger();            // Header length
            _buffer.ReadInteger();             // Unknown constant = 2
            LastSaveTimestamp = _buffer.ReadUInteger();
            int instructionsLength = _buffer.ReadInteger();

            ScenarioInstructions = _buffer.ReadString(instructionsLength);
            _buffer.ReadUInteger();             // Unknown constant = 0
            PlayerCount = _buffer.ReadUInteger();

            // Create memory stream for decompression
            using (MemoryStream output = new MemoryStream())
                using (MemoryStream input = _buffer.ToMemoryStream())
                {
                    // Go to begin of uncompressed data
                    input.Seek(_buffer.Position, SeekOrigin.Begin);

                    // Create decompressor stream
                    using (DeflateStream decompressor = new DeflateStream(input, CompressionMode.Decompress))
                    {
                        // Decompress
                        decompressor.CopyTo(output);
                        decompressor.Close();
                    }

                    // Save decompressed data into buffer
                    _buffer = new RAMBuffer(output.ToArray());
                }

            // Read parts
            Header             = new DataElements.Header().ReadData(_buffer);
            MessagesCinematics = new DataElements.MessagesCinematics().ReadData(_buffer);
            PlayerAiResources  = new DataElements.PlayerAiResources().ReadData(_buffer);
            GlobalVictory      = new DataElements.GlobalVictory().ReadData(_buffer);
            Diplomacy          = new DataElements.Diplomacy().ReadData(_buffer);
            Disables           = new DataElements.Disables().ReadData(_buffer);
            Map   = new DataElements.Map().ReadData(_buffer);
            Units = new DataElements.Units().ReadData(_buffer);
            PlayerDiplomacyVarious = new DataElements.PlayerDiplomacyVarious().ReadData(_buffer);
            Triggers      = new DataElements.Triggers().ReadData(_buffer);
            IncludedFiles = new DataElements.IncludedFiles().ReadData(_buffer);

            // Clear buffer to save memory
            _buffer.Clear();
        }
예제 #2
0
        /// <summary>
        /// Serializes the data elements into the internal buffer.
        /// </summary>
        /// <remarks></remarks>
        private void WriteData()
        {
            // Initialize buffer
            if (_buffer == null)
            {
                _buffer = new RAMBuffer();
            }
            else if (_buffer.Length != 0)
            {
                _buffer.Clear();
            }

            // Write header
            _buffer.WriteString("1.21", 4);
            _buffer.WriteUInteger(4 + 4 + 4 + (uint)ScenarioInstructions.Length + 4 + 4);
            _buffer.WriteInteger(2);
            _buffer.WriteUInteger(LastSaveTimestamp);
            _buffer.WriteInteger(ScenarioInstructions.Length);
            _buffer.WriteString(ScenarioInstructions);
            _buffer.WriteUInteger(0);
            _buffer.WriteUInteger(PlayerCount);

            // Create buffer for compressed data elements
            RAMBuffer comprBuffer = new RAMBuffer();

            Header.WriteData(comprBuffer);
            MessagesCinematics.WriteData(comprBuffer);
            PlayerAiResources.WriteData(comprBuffer);
            GlobalVictory.WriteData(comprBuffer);
            Diplomacy.WriteData(comprBuffer);
            Disables.WriteData(comprBuffer);
            Map.WriteData(comprBuffer);
            Units.WriteData(comprBuffer);
            PlayerDiplomacyVarious.WriteData(comprBuffer);
            Triggers.WriteData(comprBuffer);
            IncludedFiles.WriteData(comprBuffer);

            // Compress data and copy to main buffer
            using (MemoryStream output = new MemoryStream())
                using (MemoryStream input = comprBuffer.ToMemoryStream())
                {
                    // Create compressor stream
                    using (DeflateStream compressor = new DeflateStream(output, CompressionMode.Compress))
                    {
                        // Compress
                        input.CopyTo(compressor);
                        input.Close();
                    }

                    // Save compressed data into main buffer
                    _buffer.Write(output.ToArray());
                }
        }
예제 #3
0
        /// <summary>
        /// Lädt alle Daten aus dem internen Puffer in die jeweiligen Variablen.
        /// </summary>
        /// <remarks></remarks>
        private void ReadData()
        {
            // Dateiversion lesen
            string version = _buffer.ReadString(8);

            if (version != "VER 5.7\0")
            {
                throw new InvalidDataException("Invalid file format or wrong version.");
            }

            // Anzahlen lesen
            ushort terrainRestrictionCount = _buffer.ReadUShort();
            ushort terrainCount            = _buffer.ReadUShort();

            // Terrain-Pointer lesen
            TerrainRestrictionPointers1 = new List <int>(terrainRestrictionCount);
            for (int i = 0; i < terrainRestrictionCount; ++i)
            {
                TerrainRestrictionPointers1.Add(_buffer.ReadInteger());
            }
            TerrainRestrictionPointers2 = new List <int>(terrainRestrictionCount);
            for (int i = 0; i < terrainRestrictionCount; ++i)
            {
                TerrainRestrictionPointers2.Add(_buffer.ReadInteger());
            }

            // Terrain-Beschränkungen lesen
            TerrainRestrictions = new List <DataElements.TerrainRestriction>(terrainRestrictionCount);
            DataElements.TerrainRestriction.TerrainCount = terrainCount;
            for (int i = 0; i < terrainRestrictionCount; ++i)
            {
                TerrainRestrictions.Add(new DataElements.TerrainRestriction().ReadData(_buffer));
            }

            // Anzahl lesen
            ushort playerColorCount = _buffer.ReadUShort();

            // Spielerfarben lesen
            PlayerColors = new List <DataElements.PlayerColor>(playerColorCount);
            for (int i = 0; i < playerColorCount; ++i)
            {
                PlayerColors.Add(new DataElements.PlayerColor().ReadData(_buffer));
            }

            // Anzahl lesen
            ushort soundCount = _buffer.ReadUShort();

            // Sounds lesen
            Sounds = new List <DataElements.Sound>(soundCount);
            for (int i = 0; i < soundCount; ++i)
            {
                Sounds.Add(new DataElements.Sound().ReadData(_buffer));
            }

            // Anzahl lesen
            int graphicCount = _buffer.ReadUShort();

            // Grafik-Pointer lesen
            GraphicPointers = new List <int>(graphicCount);
            for (int i = 0; i < graphicCount; ++i)
            {
                GraphicPointers.Add(_buffer.ReadInteger());
            }

            // Grafiken lesen
            Graphics = new Dictionary <int, DataElements.Graphic>(graphicCount);
            for (int p = 0; p < GraphicPointers.Count; ++p)
            {
                if (GraphicPointers[p] != 0)
                {
                    Graphics.Add(p, new DataElements.Graphic().ReadData(_buffer));
                }
            }

            // Terrain-Daten lesen
            TerrainBlock = new DataElements.TerrainBlock().ReadData(_buffer);

            // RandomMap-Daten lese
            RandomMaps = new DataElements.RandomMaps().ReadData(_buffer);

            // Anzahl lesen
            int techageCount = _buffer.ReadInteger();

            // Technologie-Effekte lesen
            Techages = new List <DataElements.Techage>(techageCount);
            for (int i = 0; i < techageCount; ++i)
            {
                Techages.Add(new DataElements.Techage().ReadData(_buffer));
            }

            // Anzahl lesen
            int unitCount = _buffer.ReadInteger();

            // Einheiten-Header lesen
            UnitHeaders = new List <DataElements.UnitHeader>(unitCount);
            for (int i = 0; i < unitCount; ++i)
            {
                UnitHeaders.Add(new DataElements.UnitHeader().ReadData(_buffer));
            }

            // Anzahl lesen
            int civCount = _buffer.ReadUShort();

            // Kulturen lesen
            Civs = new List <DataElements.Civ>(civCount);
            for (int i = 0; i < civCount; ++i)
            {
                Civs.Add(new DataElements.Civ().ReadData(_buffer));
            }

            // Anzahl lesen
            int researchCount = _buffer.ReadUShort();

            // Technologien lesen
            Researches = new List <DataElements.Research>(researchCount);
            for (int i = 0; i < researchCount; ++i)
            {
                Researches.Add(new DataElements.Research().ReadData(_buffer));
            }

            // Unbekannte Technologiebaum-Daten lesen
            TechTreeUnknown = new List <int>(7);
            for (int i = 0; i < 7; ++i)
            {
                TechTreeUnknown.Add(_buffer.ReadInteger());
            }

            // TechTree lesen
            TechTree = new DataElements.TechTree().ReadData(_buffer);

            // Auf neuen TechTree prüfen
            if (_buffer.Length - _buffer.Position > 4)
            {
                // Marker einlesen
                string newTechTreeMarker = _buffer.ReadString(3);
                if (newTechTreeMarker == NEW_TECH_TREE_MARKER)
                {
                    _newTechTree = true;
                }
            }
            if (_newTechTree)
            {
                TechTreeNew = new DataElements.TechTreeNew().ReadData(_buffer);
            }

            // Puffer leeren, um Speicher zu sparen
            _buffer.Clear();
        }