/// <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(); }
/// <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()); } }
/// <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(); }