From efaba1f3d92d4c42eb0c639660a1a6cf71c070fd Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 30 Mar 2015 23:04:20 +0100 Subject: [PATCH] Added support for MESS BIOS xml datlist (mess -listxml) --- ROMVault2/DatReaders/DatMessBIOSReader.cs | 412 ++++++++++++++++++++++ ROMVault2/DatReaders/DatReader.cs | 4 + ROMVault2/ROMVault2.csproj | 1 + 3 files changed, 417 insertions(+) create mode 100644 ROMVault2/DatReaders/DatMessBIOSReader.cs diff --git a/ROMVault2/DatReaders/DatMessBIOSReader.cs b/ROMVault2/DatReaders/DatMessBIOSReader.cs new file mode 100644 index 0000000..89ac491 --- /dev/null +++ b/ROMVault2/DatReaders/DatMessBIOSReader.cs @@ -0,0 +1,412 @@ +/****************************************************** + * ROMVault2 is written by Gordon J. * + * Contact gordon@romvault.com * + * Copyright 2014 * + ******************************************************/ + +// Adapted to read MESS BIOS xml dat by Natalia Portillo + +using System; +using System.Xml; +using ROMVault2.RvDB; +using ROMVault2.Utils; + +namespace ROMVault2.DatReaders +{ + public static class DatMessBIOSXmlReader + { + private static bool _cleanFileNames = true; + + public static bool ReadDat(ref RvDir tDat, XmlDocument doc) + { + FileType thisFileType = FileType.Unknown; + + if (!LoadHeaderFromDat(ref tDat, ref doc, ref thisFileType)) + return false; + + if (doc.DocumentElement == null) + return false; + + XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType); + } + } + + XmlNodeList machineNodeList = doc.DocumentElement.SelectNodes("machine"); + + if (machineNodeList != null) + { + for (int i = 0; i < machineNodeList.Count; i++) + { + LoadMachineFromDat(ref tDat, machineNodeList[i], thisFileType); + } + } + + return true; + } + + public static bool ReadMessDat(ref RvDir tDat, XmlDocument doc) + { + FileType thisFileType = FileType.Unknown; + + if (!LoadMessHeaderFromDat(ref tDat, ref doc, ref thisFileType)) + return false; + + if (doc.DocumentElement == null) + return false; + + XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDat, dirNodeList[i], thisFileType); + } + } + + XmlNodeList machineNodeList = doc.DocumentElement.SelectNodes("machine"); + + if (machineNodeList != null) + { + for (int i = 0; i < machineNodeList.Count; i++) + { + LoadMachineFromDat(ref tDat, machineNodeList[i], thisFileType); + } + } + + return true; + } + + + + private static bool LoadHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType) + { + if (doc.DocumentElement == null) + return false; + XmlNode head = doc.DocumentElement.SelectSingleNode("header"); + + if (head == null) + return false; + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.SelectSingleNode("name"))); + tDat.AddData(RvDat.DatData.RootDir, VarFix.CleanFileName(head.SelectSingleNode("rootdir"))); + tDat.AddData(RvDat.DatData.Description, VarFix.String(head.SelectSingleNode("description"))); + tDat.AddData(RvDat.DatData.Category, VarFix.String(head.SelectSingleNode("category"))); + tDat.AddData(RvDat.DatData.Version, VarFix.String(head.SelectSingleNode("version"))); + tDat.AddData(RvDat.DatData.Date, VarFix.String(head.SelectSingleNode("date"))); + tDat.AddData(RvDat.DatData.Author, VarFix.String(head.SelectSingleNode("author"))); + tDat.AddData(RvDat.DatData.Email, VarFix.String(head.SelectSingleNode("email"))); + tDat.AddData(RvDat.DatData.HomePage, VarFix.String(head.SelectSingleNode("homepage"))); + tDat.AddData(RvDat.DatData.URL, VarFix.String(head.SelectSingleNode("url"))); + + + string superDAT = VarFix.String(head.SelectSingleNode("type")); + _cleanFileNames = superDAT.ToLower() != "superdat" && superDAT.ToLower() != "gigadat"; + if (!_cleanFileNames) tDat.AddData(RvDat.DatData.SuperDat, "superdat"); + + thisFileType = FileType.ZipFile; + + // Look for: + XmlNode packingNode = head.SelectSingleNode("romvault"); + if (packingNode == null) + // Look for: + packingNode = head.SelectSingleNode("clrmamepro"); + if (packingNode != null) + { + if (packingNode.Attributes != null) + { + string val = VarFix.String(packingNode.Attributes.GetNamedItem("forcepacking")).ToLower(); + switch (val.ToLower()) + { + case "zip": + tDat.AddData(RvDat.DatData.FileType, "zip"); + thisFileType = FileType.ZipFile; + break; + case "unzip": + case "file": + tDat.AddData(RvDat.DatData.FileType, "file"); + thisFileType = FileType.File; + break; + default: + thisFileType = FileType.ZipFile; + break; + } + + val = VarFix.String(packingNode.Attributes.GetNamedItem("forcemerging")).ToLower(); + switch (val.ToLower()) + { + case "split": + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + case "full": + tDat.AddData(RvDat.DatData.MergeType, "full"); + break; + default: + tDat.AddData(RvDat.DatData.MergeType, "split"); + break; + } + val = VarFix.String(packingNode.Attributes.GetNamedItem("dir")).ToLower(); // noautodir , nogame + if (!String.IsNullOrEmpty(val)) + tDat.AddData(RvDat.DatData.DirSetup,val); + } + } + + // Look for: true + string notzipped = VarFix.String(head.SelectSingleNode("notzipped")); + if (notzipped.ToLower() == "true" || notzipped.ToLower() == "yes") thisFileType = FileType.File; + + tDir.Dat = tDat; + return true; + } + + private static bool LoadMessHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType) + { + if (doc.DocumentElement == null) + return false; + XmlNode head = doc.SelectSingleNode("mess"); + + if (head == null || head.Attributes == null) + return false; + RvDat tDat = new RvDat(); + tDat.AddData(RvDat.DatData.DatName, VarFix.CleanFileName(head.Attributes.GetNamedItem("build"))); + tDat.AddData(RvDat.DatData.Description, VarFix.String(head.Attributes.GetNamedItem("build"))); + + thisFileType = FileType.ZipFile; + tDir.Dat = tDat; + return true; + } + + + private static void LoadDirFromDat(ref RvDir tDat, XmlNode dirNode, FileType thisFileType) + { + if (dirNode.Attributes == null) + return; + + RvDir parent = tDat; + + string fullname = VarFix.CleanFullFileName(dirNode.Attributes.GetNamedItem("name")); + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + dir = VarFix.CleanFileName(dir); + + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + + RvDir tDir = new RvDir(FileType.Dir) + { + Name = fullname, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + + int index1; + if (parent.ChildNameSearch(tDir, out index1) == 0) + tDir = (RvDir)parent.Child(index1); + else + tDat.ChildAdd(tDir, index1); + + XmlNodeList dirNodeList = dirNode.SelectNodes("dir"); + if (dirNodeList != null) + { + for (int i = 0; i < dirNodeList.Count; i++) + { + LoadDirFromDat(ref tDir, dirNodeList[i], thisFileType); + } + } + + XmlNodeList machineNodeList = dirNode.SelectNodes("machine"); + if (machineNodeList != null) + { + for (int i = 0; i < machineNodeList.Count; i++) + { + LoadMachineFromDat(ref tDir, machineNodeList[i], thisFileType); + } + } + } + + private static void LoadMachineFromDat(ref RvDir tDat, XmlNode machineNode, FileType thisFileType) + { + if (machineNode.Attributes == null) + return; + + RvDir parent = tDat; + RvDir tDir; + int index1 = 0; + + string fullname = VarFix.CleanFullFileName(machineNode.Attributes.GetNamedItem("name")); + if (_cleanFileNames) + fullname = fullname.Replace("/", "-"); + else + { + while (fullname.Contains("/")) + { + int firstSlash = fullname.IndexOf("/", StringComparison.Ordinal); + string dir = fullname.Substring(0, firstSlash); + dir = VarFix.CleanFileName(dir); + + fullname = fullname.Substring(firstSlash + 1); + int index; + if (parent.ChildNameSearch(new RvDir(FileType.Dir) { Name = dir }, out index) == 0) + { + parent = (RvDir)parent.Child(index); + } + else + { + RvDir tpDir = new RvDir(FileType.Dir) + { + Name = dir, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat, + Tree = new RvTreeRow() + }; + parent.ChildAdd(tpDir, index); + parent = tpDir; + } + } + } + + tDir = new RvDir(DBTypeGet.DirFromFile(thisFileType)) + { + Name = fullname, + DatStatus = DatStatus.InDatCollect, + Dat = tDat.Dat + }; + + string testName = tDir.Name; + int nameCount = 0; + while (parent.ChildNameSearch(tDir, out index1) == 0) + { + tDir.Name = testName + "_" + nameCount; + nameCount++; + } + + tDir.Game = new RvGame(); + tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(machineNode.Attributes.GetNamedItem("romof"))); + tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(machineNode.SelectSingleNode("description"))); + + tDir.Game.AddData(RvGame.GameData.Sourcefile, VarFix.String(machineNode.Attributes.GetNamedItem("sourcefile"))); + tDir.Game.AddData(RvGame.GameData.IsBios, VarFix.String(machineNode.Attributes.GetNamedItem("isbios"))); + tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(machineNode.Attributes.GetNamedItem("cloneof"))); + tDir.Game.AddData(RvGame.GameData.SampleOf, VarFix.CleanFileName(machineNode.Attributes.GetNamedItem("sampleof"))); + tDir.Game.AddData(RvGame.GameData.Board, VarFix.String(machineNode.Attributes.GetNamedItem("board"))); + tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(machineNode.SelectSingleNode("year"))); + tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.String(machineNode.SelectSingleNode("manufacturer"))); + + XmlNode trurip = machineNode.SelectSingleNode("trurip"); + if (trurip != null) + { + tDir.Game.AddData(RvGame.GameData.Trurip, "yes"); + tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(trurip.SelectSingleNode("year"))); + tDir.Game.AddData(RvGame.GameData.Publisher, VarFix.String(trurip.SelectSingleNode("publisher"))); + tDir.Game.AddData(RvGame.GameData.Developer, VarFix.String(trurip.SelectSingleNode("developer"))); + tDir.Game.AddData(RvGame.GameData.Edition, VarFix.String(trurip.SelectSingleNode("edition"))); + tDir.Game.AddData(RvGame.GameData.Version, VarFix.String(trurip.SelectSingleNode("version"))); + tDir.Game.AddData(RvGame.GameData.Type, VarFix.String(trurip.SelectSingleNode("type"))); + tDir.Game.AddData(RvGame.GameData.Media, VarFix.String(trurip.SelectSingleNode("media"))); + tDir.Game.AddData(RvGame.GameData.Language, VarFix.String(trurip.SelectSingleNode("language"))); + tDir.Game.AddData(RvGame.GameData.Players, VarFix.String(trurip.SelectSingleNode("players"))); + tDir.Game.AddData(RvGame.GameData.Ratings, VarFix.String(trurip.SelectSingleNode("ratings"))); + tDir.Game.AddData(RvGame.GameData.Peripheral, VarFix.String(trurip.SelectSingleNode("peripheral"))); + tDir.Game.AddData(RvGame.GameData.Genre, VarFix.String(trurip.SelectSingleNode("genre"))); + tDir.Game.AddData(RvGame.GameData.MediaCatalogNumber, VarFix.String(trurip.SelectSingleNode("mediacatalognumber"))); + tDir.Game.AddData(RvGame.GameData.BarCode, VarFix.String(trurip.SelectSingleNode("barcode"))); + } + + RvDir tDirCHD = new RvDir(FileType.Dir) + { + Name = tDir.Name, + DatStatus = tDir.DatStatus, + Dat = tDir.Dat, + Game = tDir.Game + }; + + XmlNodeList romNodeList = machineNode.SelectNodes("rom"); + if (romNodeList != null) + for (int i = 0; i < romNodeList.Count; i++) + LoadRomFromDat(ref tDir, romNodeList[i], thisFileType); + + XmlNodeList diskNodeList = machineNode.SelectNodes("disk"); + if (diskNodeList != null) + for (int i = 0; i < diskNodeList.Count; i++) + LoadDiskFromDat(ref tDirCHD, diskNodeList[i]); + + if (tDir.ChildCount > 0) + parent.ChildAdd(tDir, index1); + if (tDirCHD.ChildCount > 0) + parent.ChildAdd(tDirCHD); + } + + private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode, FileType thisFileType) + { + if (romNode.Attributes == null) + return; + + + RvFile tRom = new RvFile(thisFileType) + { + Dat = tGame.Dat, + Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), + Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")), + CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), + SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + MD5 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32), + Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")) + }; + + if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); + if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); + if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); + if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT); + + tGame.ChildAdd(tRom); + } + + private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode) + { + if (romNode.Attributes == null) + return; + + + RvFile tRom = new RvFile(FileType.File) + { + Dat = tGame.Dat, + Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")) + ".chd", + SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), + MD5CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32), + Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")), + Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")) + }; + + if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT); + if (tRom.MD5CHD != null) tRom.FileStatusSet(FileStatus.MD5CHDFromDAT); + + tGame.ChildAdd(tRom); + } + + } +} diff --git a/ROMVault2/DatReaders/DatReader.cs b/ROMVault2/DatReaders/DatReader.cs index 7e11135..6187229 100644 --- a/ROMVault2/DatReaders/DatReader.cs +++ b/ROMVault2/DatReaders/DatReader.cs @@ -129,6 +129,10 @@ namespace ROMVault2.DatReaders if (mame != null) return DatXmlReader.ReadMameDat(ref tDat, doc); + XmlNode mess = doc.SelectSingleNode("mess"); + if (mess != null) + return DatMessBIOSXmlReader.ReadMessDat(ref tDat, doc); + if (doc.DocumentElement != null) { XmlNode head = doc.DocumentElement.SelectSingleNode("header"); diff --git a/ROMVault2/ROMVault2.csproj b/ROMVault2/ROMVault2.csproj index d08bdeb..b62516f 100644 --- a/ROMVault2/ROMVault2.csproj +++ b/ROMVault2/ROMVault2.csproj @@ -97,6 +97,7 @@ +