/// <summary> /// Loads the given creature collection file. /// </summary> /// <param name="filePath">File that contains the collection</param> /// <param name="keepCurrentCreatures">add the creatures of the loaded file to the current ones</param> /// <param name="keepCurrentSelections">don't change the species selection or tab</param> /// <returns></returns> private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = false, bool keepCurrentSelections = false) { Species selectedSpecies = speciesSelector1.SelectedSpecies; Species selectedlibrarySpecies = listBoxSpeciesLib.SelectedItem as Species; if (!File.Exists(filePath)) { MessageBox.Show($"Save file with name \"{filePath}\" does not exist!", "File not found", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } List <Creature> oldCreatures = null; if (keepCurrentCreatures) { oldCreatures = creatureCollection.creatures; } // for the case the collectionfile has no multipliers, keep the current ones ServerMultipliers oldMultipliers = creatureCollection.serverMultipliers; // Wait until the file is readable const int numberOfRetries = 5; const int delayOnRetry = 1000; FileStream fileStream = null; for (int i = 1; i <= numberOfRetries; ++i) { try { if (Path.GetExtension(filePath).ToLower() == ".xml") { using (fileStream = File.OpenRead(filePath)) { // use xml-serializer for old library-format XmlSerializer reader = new XmlSerializer(typeof(oldLibraryFormat.CreatureCollectionOld)); var creatureCollectionOld = (oldLibraryFormat.CreatureCollectionOld)reader.Deserialize(fileStream); List <Mod> mods = null; // first check if additional values are used, and if the according values-file is already available. // if not, abort conversion and first make sure the file is available, e.g. downloaded if (!string.IsNullOrEmpty(creatureCollectionOld.additionalValues)) { // usually the old filename is equal to the mod-tag bool modFound = false; string modTag = Path.GetFileNameWithoutExtension(creatureCollectionOld.additionalValues).Replace(" ", "").ToLower().Replace("gaiamod", "gaia"); foreach (KeyValuePair <string, ModInfo> tmi in Values.V.modsManifest.modsByTag) { if (tmi.Key.ToLower() == modTag) { modFound = true; MessageBox.Show("The library contains creatures of modded species. For a correct file-conversion the correct mod-values file is needed.\n\n" + "If the mod-value file is not loaded, the conversion may assign wrong species to your creatures.\n" + "If the mod-value file is not available locally, it will be tried to download it.", "Mod values needed", MessageBoxButtons.OK, MessageBoxIcon.Information); if (Values.V.loadedModsHash != CreatureCollection.CalculateModListHash(new List <Mod>())) { LoadStatAndKibbleValues(false); // reset values to default } LoadModValueFiles(new List <string> { tmi.Value.mod.FileName }, true, true, out mods); break; } } if (!modFound && MessageBox.Show("The additional-values file in the library you're loading is unknown. You should first get a values-file in the new format for that mod.\n" + "If you're loading the library the conversion of some modded species to the new format may fail and the according creatures have to be imported again later.\n\n" + $"File:\n{filePath}\n" + $"unknown mod-file: {modTag}\n\n" + "Do you want to load the library and risk losing creatures?", "Unknown mod-file", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) { return(false); } } creatureCollection = oldLibraryFormat.FormatConverter.ConvertXml2Asb(creatureCollectionOld, filePath); creatureCollection.ModList = mods; if (creatureCollection == null) { throw new Exception("Conversion failed"); } string fileNameWOExt = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); // check if new fileName is not yet existing filePath = fileNameWOExt + COLLECTION_FILE_EXTENSION; if (File.Exists(filePath)) { int fi = 2; while (File.Exists(fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION)) { fi++; } filePath = fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION; } // save converted library SaveCollectionToFileName(filePath); } } else { CreatureCollection tmpCC; using (StreamReader file = File.OpenText(filePath)) { JsonSerializer serializer = new JsonSerializer(); tmpCC = (CreatureCollection)serializer.Deserialize(file, typeof(CreatureCollection)); } if (!Version.TryParse(tmpCC.FormatVersion, out Version ccVersion) || !Version.TryParse(CreatureCollection.CURRENT_FORMAT_VERSION, out Version currentVersion) || ccVersion > currentVersion) { throw new FormatException("Unhandled format version"); } creatureCollection = tmpCC; } break; } catch (IOException) { // if file is not readable Thread.Sleep(delayOnRetry); } catch (FormatException) { // This FormatVersion is not understood, abort MessageBox.Show($"This library format is unsupported in this version of ARK Smart Breeding." + "\n\nTry updating to a newer version.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } catch (InvalidOperationException e) { MessageBox.Show($"The library-file\n{filePath}\ncouldn\'t be opened, we thought you should know.\nErrormessage:\n\n{e.Message}" + (e.InnerException == null ? string.Empty : $"\n\nInnerException:\n\n{e.InnerException.Message}"), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } finally { fileStream?.Close(); } } if (creatureCollection.ModValueReloadNeeded) { // load original multipliers if they were changed if (!LoadStatAndKibbleValues(false).statValuesLoaded) { creatureCollection = new CreatureCollection(); return(false); } } if (creatureCollection.ModValueReloadNeeded && !LoadModValuesOfCollection(creatureCollection, false, false)) { creatureCollection = new CreatureCollection(); return(false); } if (creatureCollection.serverMultipliers == null) { creatureCollection.serverMultipliers = oldMultipliers ?? Values.V.serverMultipliersPresets.GetPreset(ServerMultipliersPresets.OFFICIAL); } if (speciesSelector1.LastSpecies != null && speciesSelector1.LastSpecies.Length > 0) { tamingControl1.SetSpecies(Values.V.SpeciesByBlueprint(speciesSelector1.LastSpecies[0])); } creatureCollection.FormatVersion = CreatureCollection.CURRENT_FORMAT_VERSION; ApplySettingsToValues(); bool creatureWasAdded = false; if (keepCurrentCreatures) { creatureWasAdded = creatureCollection.MergeCreatureList(oldCreatures); } else { currentFileName = filePath; fileSync.ChangeFile(currentFileName); creatureBoxListView.Clear(); } creatureCollection.DeletedCreatureGuids = null; // no longer needed InitializeCollection(); filterListAllowed = false; SetLibraryFilter("Dead", creatureCollection.showFlags.HasFlag(CreatureFlags.Dead)); SetLibraryFilter("Unavailable", creatureCollection.showFlags.HasFlag(CreatureFlags.Unavailable)); SetLibraryFilter("Neutered", creatureCollection.showFlags.HasFlag(CreatureFlags.Neutered)); SetLibraryFilter("Obelisk", creatureCollection.showFlags.HasFlag(CreatureFlags.Obelisk)); SetLibraryFilter("Cryopod", creatureCollection.showFlags.HasFlag(CreatureFlags.Cryopod)); SetLibraryFilter("Mutated", creatureCollection.showFlags.HasFlag(CreatureFlags.Mutated)); checkBoxUseFiltersInTopStatCalculation.Checked = creatureCollection.useFiltersInTopStatCalculation; SetCollectionChanged(creatureWasAdded); // setCollectionChanged only if there really were creatures added from the old library to the just opened one ///// creatures loaded. // calculate creature values RecalculateAllCreaturesValues(); if (!keepCurrentSelections && creatureCollection.creatures.Count > 0) { tabControlMain.SelectedTab = tabPageLibrary; } creatureBoxListView.maxDomLevel = creatureCollection.maxDomLevel; UpdateCreatureListings(); // set global species that was set before loading if (selectedSpecies != null && creatureCollection.creatures.Any(c => c.Species != null && c.Species.Equals(selectedSpecies)) ) { speciesSelector1.SetSpecies(selectedSpecies); } else if (creatureCollection.creatures.Any()) { speciesSelector1.SetSpecies(creatureCollection.creatures[0].Species); } // set library species to what it was before loading if (selectedlibrarySpecies == null || !creatureCollection.creatures.Any(c => c.Species != null && c.Species.Equals(selectedlibrarySpecies)) ) { selectedlibrarySpecies = speciesSelector1.SelectedSpecies; } if (selectedlibrarySpecies != null) { listBoxSpeciesLib.SelectedIndex = listBoxSpeciesLib.Items.IndexOf(selectedlibrarySpecies); } filterListAllowed = true; FilterLib(); // apply last sorting listViewLibrary.Sort(); UpdateTempCreatureDropDown(); Properties.Settings.Default.LastSaveFile = filePath; lastAutoSaveBackup = DateTime.Now.AddMinutes(-10); return(true); }
/// <summary> /// Loads the given creature collection file. /// </summary> /// <param name="filePath">File that contains the collection</param> /// <param name="keepCurrentCreatures">add the creatures of the loaded file to the current ones</param> /// <param name="keepCurrentSelections">don't change the species selection or tab</param> /// <returns></returns> private bool LoadCollectionFile(string filePath, bool keepCurrentCreatures = false, bool keepCurrentSelections = false) { Species selectedSpecies = speciesSelector1.SelectedSpecies; Species selectedlibrarySpecies = listBoxSpeciesLib.SelectedItem as Species; if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) { MessageBox.Show($"Save file with name \"{filePath}\" does not exist!", "File not found", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } List <Creature> oldCreatures = null; if (keepCurrentCreatures) { oldCreatures = creatureCollection.creatures; } // for the case the collectionfile has no multipliers, keep the current ones ServerMultipliers oldMultipliers = creatureCollection.serverMultipliers; // Wait until the file is readable const int numberOfRetries = 5; const int delayOnRetry = 1000; FileStream fileStream = null; for (int i = 1; i <= numberOfRetries; ++i) { try { if (Path.GetExtension(filePath).ToLower() == ".xml") { // old format for backwards compatibility using (fileStream = File.OpenRead(filePath)) { // use xml-serializer for old library-format XmlSerializer reader = new XmlSerializer(typeof(oldLibraryFormat.CreatureCollectionOld)); var creatureCollectionOld = (oldLibraryFormat.CreatureCollectionOld)reader.Deserialize(fileStream); List <Mod> mods = null; // first check if additional values are used, and if the according values-file is already available. // if not, abort conversion and first make sure the file is available, e.g. downloaded if (!string.IsNullOrEmpty(creatureCollectionOld.additionalValues)) { // usually the old filename is equal to the mod-tag bool modFound = false; string modTag = Path.GetFileNameWithoutExtension(creatureCollectionOld.additionalValues).Replace(" ", "").ToLower().Replace("gaiamod", "gaia"); foreach (KeyValuePair <string, ModInfo> tmi in Values.V.modsManifest.modsByTag) { if (tmi.Key.ToLower() == modTag) { modFound = true; MessageBox.Show("The library contains creatures of modded species. For a correct file-conversion the correct mod-values file is needed.\n\n" + "If the mod-value file is not loaded, the conversion may assign wrong species to your creatures.\n" + "If the mod-value file is not available locally, it will be tried to download it.", "Mod values needed", MessageBoxButtons.OK, MessageBoxIcon.Information); if (Values.V.loadedModsHash != CreatureCollection.CalculateModListHash(new List <Mod>())) { LoadStatAndKibbleValues(false); // reset values to default } LoadModValueFiles(new List <string> { tmi.Value.mod.FileName }, true, true, out mods); break; } } if (!modFound && MessageBox.Show("The additional-values file in the library you're loading is unknown. You should first get a values-file in the new format for that mod.\n" + "If you're loading the library the conversion of some modded species to the new format may fail and the according creatures have to be imported again later.\n\n" + $"File:\n{filePath}\n" + $"unknown mod-file: {modTag}\n\n" + "Do you want to load the library and risk losing creatures?", "Unknown mod-file", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) { return(false); } } creatureCollection = oldLibraryFormat.FormatConverter.ConvertXml2Asb(creatureCollectionOld, filePath); creatureCollection.ModList = mods; if (creatureCollection == null) { throw new Exception("Conversion failed"); } string fileNameWOExt = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)); // check if new fileName is not yet existing filePath = fileNameWOExt + COLLECTION_FILE_EXTENSION; if (File.Exists(filePath)) { int fi = 2; while (File.Exists(fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION)) { fi++; } filePath = fileNameWOExt + "_" + fi + COLLECTION_FILE_EXTENSION; } // save converted library SaveCollectionToFileName(filePath); } } else { // new json-format if (FileService.LoadJSONFile(filePath, out CreatureCollection readCollection, out string errorMessage)) { if (!Version.TryParse(readCollection.FormatVersion, out Version ccVersion) || !Version.TryParse(CreatureCollection.CURRENT_FORMAT_VERSION, out Version currentVersion) || ccVersion > currentVersion) { throw new FormatException("Unhandled format version"); } creatureCollection = readCollection; } else { MessageBox.Show($"Error while trying to read the library-file\n{filePath}\n\n{errorMessage}", "Error reading library-file", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } break; }