private void _exportDatButton_Click(object sender, RoutedEventArgs e)
        {
            // Show save file dialog
            var saveFileDialog = new System.Windows.Forms.SaveFileDialog
            {
                Filter = "Genie database files (*.dat)|*.dat",
                Title  = "Export DAT file..."
            };

            if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            // Catch errors on export process
            try
            {
                // Reload internal genie file, apply changes and save
                GenieLibrary.GenieFile exportFile =
                    new GenieLibrary.GenieFile(GenieLibrary.GenieFile.DecompressData(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.BaseGenieFilePath)));
                BalancingFile.WriteChangesToGenieFile(exportFile);
                IORAMHelper.RAMBuffer exportFileBuffer = new IORAMHelper.RAMBuffer();
                exportFile.WriteData(exportFileBuffer);
                GenieLibrary.GenieFile.CompressData(exportFileBuffer).Save(saveFileDialog.FileName);
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to export modified DAT file: {ex.Message}");
            }
        }
예제 #2
0
        /// <summary>
        /// Computes the hash of the given genie file.
        /// </summary>
        /// <param name="genieFile">The genie file to be hashed.</param>
        /// <returns></returns>
        public static byte[] ComputeHash(GenieFile genieFile)
        {
            // Calculate hash over string of all unit and research IDs/names, such that each one is contained at least once
            using (MemoryStream hashString = new MemoryStream())
            {
                // Write unit IDs and names
                HashSet <int> unitIdsRead = new HashSet <int>();
                foreach (GenieLibrary.DataElements.Civ c in genieFile.Civs)
                {
                    foreach (var u in c.Units)
                    {
                        if (!unitIdsRead.Contains(u.Key))
                        {
                            // Append name and ID
                            byte[] uName = Encoding.ASCII.GetBytes(u.Value.Name1.TrimEnd('\0'));
                            hashString.Write(uName, 0, uName.Length);
                            hashString.Write(BitConverter.GetBytes((short)u.Key), 0, 2);

                            // Unit was added
                            unitIdsRead.Add(u.Key);
                        }
                    }
                }

                // Write research IDs and names
                for (short r = 0; r < genieFile.Researches.Count; ++r)
                {
                    // Append name and ID
                    byte[] rName = Encoding.ASCII.GetBytes(genieFile.Researches[r].Name.TrimEnd('\0'));
                    hashString.Write(rName, 0, rName.Length);
                    hashString.Write(BitConverter.GetBytes(r), 0, 2);
                }

                // Calculate hash and check
                hashString.Seek(0, SeekOrigin.Begin);
                using (MD5 md5 = MD5.Create())
                    return(md5.ComputeHash(hashString));
            }
        }
        private void _loadDatButton_Click(object sender, RoutedEventArgs e)
        {
            // Show window (create new first, as closed windows cannot be reopened)
            _currentFileSelectionWindow = new FileSelectionWindow();
            if (!(_currentFileSelectionWindow.ShowDialog() ?? false))
            {
                return;
            }

            // Check whether genie file exists
            if (!File.Exists(_currentFileSelectionWindow.BaseGenieFilePath))
            {
                // Error
                MessageBox.Show($"The given genie file path is invalid: '{_currentFileSelectionWindow.BaseGenieFilePath}'");
                return;
            }

            // Catch errors
            _languageFiles = new List <string>();
            try
            {
                // Find language files
                if (File.Exists(_currentFileSelectionWindow.LanguageX1P1DllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageX1P1DllFilePath);
                }
                if (File.Exists(_currentFileSelectionWindow.LanguageX1DllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageX1DllFilePath);
                }
                if (File.Exists(_currentFileSelectionWindow.LanguageDllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageDllFilePath);
                }

                // Load genie file
                _genieFile = new GenieLibrary.GenieFile(GenieLibrary.GenieFile.DecompressData(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.BaseGenieFilePath)));
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to load given genie file: {ex.Message}");
                return;
            }

            // Check for mapping requirement
            _mappingFile = null;
            if (!string.IsNullOrWhiteSpace(_currentFileSelectionWindow.MappingFilePath) && File.Exists(_currentFileSelectionWindow.MappingFilePath))
            {
                // Read mapping
                _mappingFile = new MappingFile(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.MappingFilePath));
                if (!_mappingFile.CheckCompabilityToGenieFile(_genieFile))
                {
                    MessageBox.Show($"The given mapping file does not match the given DAT file.");
                }
            }
            else if (_genieFile.Researches.Exists(r => r.Name.StartsWith("#BDep")))
            {
                MessageBox.Show($"This file was probably created using an editor that dynamically reassigns unit and research IDs.\nIt is strongly recommended to reload using a valid mapping file.");
            }

            // Create balancing data object
            BalancingFile      = new BalancingFile(_genieFile, _languageFiles.ToArray(), _mappingFile);
            _balancingFilePath = "";

            // Set filterable lists
            UnitEntryList = new GenericCollectionView <KeyValuePair <short, UnitEntry> >(CollectionViewSource.GetDefaultView(_balancingFile.UnitEntries));
            OnPropertyChanged(nameof(UnitEntryList));

            // Update child windows
            if (_projectileWindow != null)
            {
                _projectileWindow.GenieFile = _genieFile;
            }

            // Reset window title
            CurrentWindowTitle = WindowTitlePrefix;

            // Enable UI controls
            EnableEditorPanel = true;
        }
예제 #4
0
 /// <summary>
 /// Checks whether this mapping file is valid for the given genie file, by computing and comparing its hash.
 /// </summary>
 /// <param name="genieFile">The genie file to be checked.</param>
 /// <returns></returns>
 public bool CheckCompabilityToGenieFile(GenieFile genieFile)
 {
     // Calculate hash and compare
     return(Hash.SequenceEqual(ComputeHash(genieFile)));
 }