This repository has been archived on 2025-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
RomVault/ROMVault2/DatReaders/DatXMLReader.cs

422 lines
19 KiB
C#

/******************************************************
* ROMVault2 is written by Gordon J. *
* Contact gordon@romvault.com *
* Copyright 2014 *
******************************************************/
using System;
using System.Xml;
using ROMVault2.RvDB;
using ROMVault2.Utils;
namespace ROMVault2.DatReaders
{
public static class DatXmlReader
{
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)
{
foreach (XmlNode dirNode in dirNodeList)
LoadDirFromDat(ref tDat, dirNode, thisFileType);
}
XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game");
if (gameNodeList != null)
{
foreach (XmlNode gameNode in gameNodeList)
LoadGameFromDat(ref tDat, gameNode, thisFileType);
}
XmlNodeList machineNodeList = doc.DocumentElement.SelectNodes("machine");
if (machineNodeList != null)
{
foreach (XmlNode machineNode in machineNodeList)
LoadGameFromDat(ref tDat, machineNode, thisFileType);
}
return true;
}
public static bool ReadMameDat(ref RvDir tDat, XmlDocument doc)
{
FileType thisFileType = FileType.Unknown;
if (!LoadMameHeaderFromDat(ref tDat, ref doc, ref thisFileType))
return false;
if (doc.DocumentElement == null)
return false;
XmlNodeList dirNodeList = doc.DocumentElement.SelectNodes("dir");
if (dirNodeList != null)
{
foreach (XmlNode dirNode in dirNodeList)
LoadDirFromDat(ref tDat, dirNode, thisFileType);
}
XmlNodeList gameNodeList = doc.DocumentElement.SelectNodes("game");
if (gameNodeList != null)
{
foreach (XmlNode gameNode in gameNodeList)
LoadGameFromDat(ref tDat, gameNode, thisFileType);
}
XmlNodeList machineNodeList = doc.DocumentElement.SelectNodes("machine");
if (machineNodeList != null)
{
foreach (XmlNode machineNode in machineNodeList)
LoadGameFromDat(ref tDat, machineNode, 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: <romvault forcepacking="unzip"/>
XmlNode packingNode = head.SelectSingleNode("romvault");
if (packingNode == null)
// Look for: <clrmamepro forcepacking="unzip"/>
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: <notzipped>true</notzipped>
string notzipped = VarFix.String(head.SelectSingleNode("notzipped"));
if (notzipped.ToLower() == "true" || notzipped.ToLower() == "yes") thisFileType = FileType.File;
if (Settings.FixLevel == eFixLevel.Uncompressed)
thisFileType = FileType.File;
tDir.Dat = tDat;
return true;
}
private static bool LoadMameHeaderFromDat(ref RvDir tDir, ref XmlDocument doc, ref FileType thisFileType)
{
if (doc.DocumentElement == null)
return false;
XmlNode head = doc.SelectSingleNode("mame");
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 gameNodeList = dirNode.SelectNodes("game");
if (gameNodeList != null)
{
for (int i = 0; i < gameNodeList.Count; i++)
{
LoadGameFromDat(ref tDir, gameNodeList[i], thisFileType);
}
}
}
private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode, FileType thisFileType)
{
if (gameNode.Attributes == null)
return;
RvDir parent = tDat;
RvDir tDir;
int index1 = 0;
string fullname = VarFix.CleanFullFileName(gameNode.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(gameNode.Attributes.GetNamedItem("romof")));
tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));
tDir.Game.AddData(RvGame.GameData.Sourcefile, VarFix.String(gameNode.Attributes.GetNamedItem("sourcefile")));
tDir.Game.AddData(RvGame.GameData.IsBios, VarFix.String(gameNode.Attributes.GetNamedItem("isbios")));
tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
tDir.Game.AddData(RvGame.GameData.SampleOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("sampleof")));
tDir.Game.AddData(RvGame.GameData.Board, VarFix.String(gameNode.Attributes.GetNamedItem("board")));
tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(gameNode.SelectSingleNode("year")));
tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.String(gameNode.SelectSingleNode("manufacturer")));
XmlNode trurip = gameNode.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 = gameNode.SelectNodes("rom");
if (romNodeList != null)
for (int i = 0; i < romNodeList.Count; i++)
LoadRomFromDat(ref tDir, romNodeList[i], thisFileType);
XmlNodeList diskNodeList = gameNode.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);
}
}
}