diff --git a/SabreTools.DatFiles/DatFile.FromMetadata.cs b/SabreTools.DatFiles/DatFile.FromMetadata.cs index c5ba4e1a..98b00df0 100644 --- a/SabreTools.DatFiles/DatFile.FromMetadata.cs +++ b/SabreTools.DatFiles/DatFile.FromMetadata.cs @@ -136,6 +136,17 @@ namespace SabreTools.DatFiles Default = infos.ReleaseNumber.Default.AsYesNo(), }); } + // TODO: Uncomment this when the change to both Models and Serialization is done + //if (infos.ImageNumber != null) + //{ + // offlineListInfos.Add(new Formats.OfflineListInfo + // { + // Name = "imageNumber", + // Visible = infos.ImageNumber.Visible.AsYesNo(), + // InNamingOption = infos.ImageNumber.InNamingOption.AsYesNo(), + // Default = infos.ImageNumber.Default.AsYesNo(), + // }); + //} if (infos.LanguageNumber != null) { offlineListInfos.Add(new Formats.OfflineListInfo @@ -206,13 +217,15 @@ namespace SabreTools.DatFiles if (newDat != null) { Header.SetFieldValue("DATVERSIONURL", newDat.DatVersionUrl); - //Header.SetFieldValue("DATURL", newDat.DatUrl); // TODO: Add to internal model + Header.SetFieldValue("DATURL", newDat.DatUrl); Header.SetFieldValue("IMURL", newDat.ImUrl); } } if (item.ContainsKey(Models.Metadata.Header.SearchKey)) { - // TODO: Add to internal model + var search = item.Read(Models.Metadata.Header.SearchKey); + if (search != null) + Header.SetFieldValue(Models.Metadata.Header.SearchKey, search); } // Selectively set all possible fields -- TODO: Figure out how to make this less manual diff --git a/SabreTools.DatFiles/DatFile.ToMetadata.cs b/SabreTools.DatFiles/DatFile.ToMetadata.cs index 8f5dfcd1..21578d40 100644 --- a/SabreTools.DatFiles/DatFile.ToMetadata.cs +++ b/SabreTools.DatFiles/DatFile.ToMetadata.cs @@ -55,7 +55,7 @@ namespace SabreTools.DatFiles // Convert subheader values if (Header.CanOpenSpecified) - header[Models.Metadata.Header.CanOpenKey] = Header.GetFieldValue(Models.Metadata.Header.CanOpenKey); + header[Models.Metadata.Header.CanOpenKey] = new Models.OfflineList.CanOpen { Extension = Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey) }; // if (Header.ImagesSpecified) // // TODO: Add to internal model if (Header.InfosSpecified) @@ -180,13 +180,13 @@ namespace SabreTools.DatFiles var newDat = new Models.OfflineList.NewDat { DatVersionUrl = Header.GetStringFieldValue("DATVERSIONURL"), - //DatUrl = Header.GetFieldValue("DATURL"), // TODO: Add to internal model + DatUrl = Header.GetFieldValue("DATURL"), ImUrl = Header.GetStringFieldValue("IMURL"), }; header[Models.Metadata.Header.NewDatKey] = newDat; } - // if (Header.SearchSpecified) - // // TODO: Add to internal model + if (Header.SearchSpecified) + header[Models.Metadata.Header.SearchKey] = Header.GetFieldValue(Models.Metadata.Header.SearchKey); return header; } diff --git a/SabreTools.DatFiles/DatHeader.cs b/SabreTools.DatFiles/DatHeader.cs index b5ad63b0..67cee0e7 100644 --- a/SabreTools.DatFiles/DatHeader.cs +++ b/SabreTools.DatFiles/DatHeader.cs @@ -7,7 +7,6 @@ using SabreTools.Core; using SabreTools.Core.Tools; using SabreTools.DatFiles.Formats; using SabreTools.Filter; -using SabreTools.Serialization; namespace SabreTools.DatFiles { @@ -98,7 +97,7 @@ namespace SabreTools.DatFiles { get { - var canOpen = GetFieldValue(Models.Metadata.Header.CanOpenKey); + var canOpen = GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey); return canOpen != null && canOpen.Length > 0; } } @@ -109,11 +108,20 @@ namespace SabreTools.DatFiles get { return GetStringFieldValue("DATVERSIONURL") != null - //&& GetFieldValue("DATURL") != null // TODO: Add to internal model + && GetFieldValue("DATURL") != null && GetStringFieldValue("IMURL") != null; } } + [JsonIgnore] + public bool SearchSpecified + { + get + { + return GetFieldValue(Models.Metadata.Header.SearchKey) != null; + } + } + /// /// Internal Header model /// @@ -312,6 +320,7 @@ namespace SabreTools.DatFiles header.SetFieldValue(Models.Metadata.Header.SampleModeKey, GetStringFieldValue(Models.Metadata.Header.SampleModeKey).AsEnumValue().AsStringValue()); header.SetFieldValue(Models.Metadata.Header.ScreenshotsHeightKey, GetStringFieldValue(Models.Metadata.Header.ScreenshotsHeightKey)); header.SetFieldValue(Models.Metadata.Header.ScreenshotsWidthKey, GetStringFieldValue(Models.Metadata.Header.ScreenshotsWidthKey)); + header.SetFieldValue(Models.Metadata.Header.SearchKey, GetFieldValue(Models.Metadata.Header.SearchKey)); // TODO: Perform a deep clone header.SetFieldValue(Models.Metadata.Header.SystemKey, GetStringFieldValue(Models.Metadata.Header.SystemKey)); header.SetFieldValue(Models.Metadata.Header.TypeKey, GetStringFieldValue(Models.Metadata.Header.TypeKey)); header.SetFieldValue(Models.Metadata.Header.UrlKey, GetStringFieldValue(Models.Metadata.Header.UrlKey)); diff --git a/SabreTools.DatFiles/Formats/OfflineList.Writer.cs b/SabreTools.DatFiles/Formats/OfflineList.Writer.cs index 62b2f0ca..9a6623b9 100644 --- a/SabreTools.DatFiles/Formats/OfflineList.Writer.cs +++ b/SabreTools.DatFiles/Formats/OfflineList.Writer.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using SabreTools.Core; -using SabreTools.Core.Tools; using SabreTools.DatItems; using SabreTools.DatItems.Formats; @@ -27,10 +25,6 @@ namespace SabreTools.DatFiles.Formats { var missingFields = new List(); - // Check item name - if (string.IsNullOrEmpty(datItem.GetName())) - missingFields.Add(Models.Metadata.Rom.NameKey); - switch (datItem) { case Rom rom: @@ -51,7 +45,9 @@ namespace SabreTools.DatFiles.Formats { logger.User($"Writing to '{outfile}'..."); - var datafile = CreateDat(ignoreblanks); + // Serialize the input file + var metadata = ConvertMetadata(ignoreblanks); + var datafile = new Serialization.CrossModel.OfflineList().Deserialize(metadata); if (!(new Serialization.Files.OfflineList().Serialize(datafile, outfile))) { logger.Warning($"File '{outfile}' could not be written! See the log for more details."); @@ -67,346 +63,5 @@ namespace SabreTools.DatFiles.Formats logger.User($"'{outfile}' written!{Environment.NewLine}"); return true; } - - #region Converters - - /// - /// Create a Dat from the current internal information - /// - /// True if blank roms should be skipped on output, false otherwise - private Models.OfflineList.Dat CreateDat(bool ignoreblanks) - { - var dat = new Models.OfflineList.Dat - { - NoNamespaceSchemaLocation = "datas.xsd", - Configuration = CreateConfiguration(), - Games = CreateGames(ignoreblanks), - GUI = CreateGUI(), - }; - - return dat; - } - - /// - /// Create a Configuration from the current internal information - /// - private Models.OfflineList.Configuration? CreateConfiguration() - { - // If we don't have a header, we can't do anything - if (this.Header == null) - return null; - - var configuration = new Models.OfflineList.Configuration - { - DatName = Header.GetStringFieldValue(Models.Metadata.Header.NameKey), - ImFolder = Header.GetStringFieldValue(Models.Metadata.Header.ImFolderKey), - DatVersion = Header.GetStringFieldValue(Models.Metadata.Header.DatVersionKey), - System = Header.GetStringFieldValue(Models.Metadata.Header.SystemKey), - ScreenshotsWidth = Header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsWidthKey), - ScreenshotsHeight = Header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsHeightKey), - Infos = CreateInfos(), - CanOpen = CreateCanOpen(), - NewDat = CreateNewDat(), - Search = CreateSearch(), - RomTitle = Header.GetStringFieldValue(Models.Metadata.Header.RomTitleKey), - }; - - return configuration; - } - - /// - /// Create a Infos from the current internal information - /// - private Models.OfflineList.Infos? CreateInfos() - { - // If we don't have infos, we can't do anything - if (!Header.InfosSpecified) - return null; - - var infos = new Models.OfflineList.Infos(); - foreach (var info in Header.GetFieldValue(Models.Metadata.Header.InfosKey)!) - { - switch (info.Name) - { - case "title": - infos.Title = new Models.OfflineList.Title - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "location": - infos.Location = new Models.OfflineList.Location - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "publisher": - infos.Publisher = new Models.OfflineList.Publisher - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "sourceRom": - infos.SourceRom = new Models.OfflineList.SourceRom - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "saveType": - infos.SaveType = new Models.OfflineList.SaveType - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "romSize": - infos.RomSize = new Models.OfflineList.RomSize - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "releaseNumber": - infos.ReleaseNumber = new Models.OfflineList.ReleaseNumber - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "languageNumber": - infos.LanguageNumber = new Models.OfflineList.LanguageNumber - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "comment": - infos.Comment = new Models.OfflineList.Comment - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "romCRC": - infos.RomCRC = new Models.OfflineList.RomCRC - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "im1CRC": - infos.Im1CRC = new Models.OfflineList.Im1CRC - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "im2CRC": - infos.Im2CRC = new Models.OfflineList.Im2CRC - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - - case "languages": - infos.Languages = new Models.OfflineList.Languages - { - Visible = info.Visible?.ToString(), - InNamingOption = info.InNamingOption?.ToString(), - Default = info.Default?.ToString(), - }; - break; - } - } - - return infos; - } - - /// - /// Create a CanOpen from the current internal information - /// - private Models.OfflineList.CanOpen? CreateCanOpen() - { - // If we don't have a canopen, we can't do anything - if (!Header.CanOpenSpecified || Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey) == null) - return null; - - var canOpen = new Models.OfflineList.CanOpen - { - Extension = [.. Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey)], - }; - - return canOpen; - } - - /// - /// Create a NewDat from the current internal information - /// - private Models.OfflineList.NewDat? CreateNewDat() - { - // If we don't have a Header, we can't do anything - if (Header == null) - return null; - - var newDat = new Models.OfflineList.NewDat - { - DatVersionUrl = Header.GetStringFieldValue("DATVERSIONURL"), - //DatUrl = Header.GetFieldValue("DATURL"); // TODO: Add to internal model - ImUrl = Header.GetStringFieldValue("IMURL"), - }; - - return newDat; - } - - /// - /// Create a Search from the current internal information - /// - private Models.OfflineList.Search? CreateSearch() - { - // If we don't have a Header, we can't do anything - if (Header == null) - return null; - - // TODO: Add to internal model - return null; - } - - /// - /// Create a Games from the current internal information - /// - /// True if blank roms should be skipped on output, false otherwise - private Models.OfflineList.Games? CreateGames(bool ignoreblanks) - { - // If we don't have items, we can't do anything - if (this.Items == null || !this.Items.Any()) - return null; - - // Create a list of hold the games - var games = new List(); - - // Loop through the sorted items and create games for them - foreach (string key in Items.SortedKeys) - { - var items = Items.FilteredItems(key); - if (items == null || !items.Any()) - continue; - - // Get the first item for game information - var machine = items[0].GetFieldValue(DatItem.MachineKey); - var game = OfflineList.CreateGame(machine!); - - // Create holders for all item types - var romCRCs = new List(); - - // Loop through and convert the items to respective lists - for (int index = 0; index < items.Count; index++) - { - // Get the item - var item = items[index]; - - // Check for a "null" item - item = ProcessNullifiedItem(item); - - // Skip if we're ignoring the item - if (ShouldIgnore(item, ignoreblanks)) - continue; - - switch (item) - { - case Rom rom: - romCRCs.Add(CreateRomCRC(rom)); - break; - } - } - - // Assign the values to the game - game.Files = new Models.OfflineList.Files { RomCRC = [.. romCRCs] }; - - // Add the game to the list - games.Add(game); - } - - return new Models.OfflineList.Games { Game = [.. games] }; - } - - /// - /// Create a Machine from the current internal information - /// - private static Models.OfflineList.Game CreateGame(Machine machine) - { - var game = new Models.OfflineList.Game - { - ImageNumber = machine.GetStringFieldValue(Models.Metadata.Machine.ImageNumberKey), - ReleaseNumber = machine.GetStringFieldValue(Models.Metadata.Machine.ReleaseNumberKey), - Title = machine.GetStringFieldValue(Models.Metadata.Machine.NameKey), - SaveType = machine.GetStringFieldValue(Models.Metadata.Machine.SaveTypeKey), - Publisher = machine.GetStringFieldValue(Models.Metadata.Machine.PublisherKey), - Location = machine.GetStringFieldValue(Models.Metadata.Machine.LocationKey), - SourceRom = machine.GetStringFieldValue(Models.Metadata.Machine.SourceRomKey), - Language = machine.GetStringFieldValue(Models.Metadata.Machine.LanguageKey), - Im1CRC = machine.GetStringFieldValue(Models.Metadata.Machine.Im1CRCKey), - Im2CRC = machine.GetStringFieldValue(Models.Metadata.Machine.Im2CRCKey), - Comment = machine.GetStringFieldValue(Models.Metadata.Machine.CommentKey), - DuplicateID = machine.GetStringFieldValue(Models.Metadata.Machine.CloneOfKey), - }; - - return game; - } - - /// - /// Create a RomCRC from the current Rom DatItem - /// - private static Models.OfflineList.FileRomCRC CreateRomCRC(Rom item) - { - var romCRC = new Models.OfflineList.FileRomCRC - { - Content = item.GetStringFieldValue(Models.Metadata.Rom.CRCKey), - }; - - return romCRC; - } - - /// - /// Create a GUI from the current internal information - /// - private Models.OfflineList.GUI? CreateGUI() - { - // If we don't have a header, we can't do anything - if (this.Header == null) - return null; - - // TODO: Add to internal model - return null; - } - - #endregion } }