private static void ProcessDir(RvDir dir, int depth = 1) { string d = new string(' ', 4 * depth); for (int i = 0; i < dir.ChildCount; i++) { RvDir game = dir.Child(i) as RvDir; if (game != null && game.FileType == FileType.Zip) { WriteLine(d + "<game name=\"" + clean(game.Name) + "\">"); WriteLine(d + " <description>" + clean(game.Name) + "</description>"); for (int j = 0; j < game.ChildCount; j++) { RvFile file = game.Child(j) as RvFile; if (file != null) { WriteLine(d + " <rom name=\"" + clean(file.Name) + "\" size=\"" + file.Size + "\" crc=\"" + Utils.ArrByte.ToString(file.CRC) + "\" md5=\"" + Utils.ArrByte.ToString(file.MD5) + "\" sha1=\"" + Utils.ArrByte.ToString(file.SHA1) + "\"/>"); } } WriteLine(d + "</game>"); } if (game != null && game.FileType == FileType.Dir) { WriteLine(d + "<dir name=\"" + clean(game.Name) + "\">"); ProcessDir(game, depth + 1); WriteLine(d + "</dir>"); } } }
private void SetupTree(RvDir pTree, string pTreeBranches) { int nodeDepth = pTreeBranches.Length - 1; pTree.Tree.TreeBranches = pTreeBranches; pTree.Tree.RTree = new Rectangle(0, _yPos - 8, 1 + nodeDepth * 18, 16); pTree.Tree.RExpand = new Rectangle(5 + nodeDepth * 18, _yPos + 4, 9, 9); pTree.Tree.RChecked = new Rectangle(20 + nodeDepth * 18, _yPos + 2, 13, 13); pTree.Tree.RIcon = new Rectangle(35 + nodeDepth * 18, _yPos, 16, 16); pTree.Tree.RText = new Rectangle(51 + nodeDepth * 18, _yPos, 500, 16); pTreeBranches = pTreeBranches.Replace("├", "│"); pTreeBranches = pTreeBranches.Replace("└", " "); _yPos = _yPos + 16; bool found = false; int last = 0; for (int i = 0; i < pTree.ChildCount; i++) { RvBase t = pTree.Child(i); if (t is RvDir) if (((RvDir)t).Tree != null) { found = true; if (pTree.Tree.TreeExpanded) last = i; } } if (!found) pTree.Tree.RExpand = new Rectangle(0, 0, 0, 0); for (int i = 0; i < pTree.ChildCount; i++) { RvBase t = pTree.Child(i); if (t is RvDir) if (((RvDir)t).Tree != null) { if (pTree.Tree.TreeExpanded) { if (i != last) SetupTree((RvDir)pTree.Child(i), pTreeBranches + "├"); else SetupTree((RvDir)pTree.Child(i), pTreeBranches + "└"); } } } }
private static void GetSelectedDirList(ref List<RvDir> lstDir, RvDir thisDir) { for (int i = 0; i < thisDir.ChildCount; i++) { if (thisDir.DatStatus != DatStatus.InDatCollect) continue; RvDir tDir = thisDir.Child(i) as RvDir; if (tDir == null) continue; if (tDir.Tree == null) continue; if (tDir.Tree.Checked == RvTreeRow.TreeSelect.Selected) lstDir.Add(tDir); GetSelectedDirList(ref lstDir, tDir); } }
private static int CountFixDir(RvDir dir, bool lastSelected) { int count = 0; bool thisSelected = lastSelected; if (dir.Tree != null) thisSelected = dir.Tree.Checked == RvTreeRow.TreeSelect.Selected; for (int j = 0; j < dir.ChildCount; j++) { RvBase child = dir.Child(j); switch (child.FileType) { case FileType.Zip: if (!thisSelected) continue; RvDir tZip = (RvDir)child; count += tZip.DirStatus.CountCanBeFixed(); break; case FileType.Dir: count += CountFixDir((RvDir)child, thisSelected); break; case FileType.File: if (!thisSelected) continue; if (child.RepStatus == RepStatus.CanBeFixed) count++; break; } } return count; }
private static bool IsDeepScanned(RvDir tZip) { for (int i = 0; i < tZip.ChildCount; i++) { RvFile zFile = tZip.Child(i) as RvFile; if (zFile != null && zFile.GotStatus == GotStatus.Got && (!zFile.FileStatusIs(FileStatus.SizeVerified) || !zFile.FileStatusIs(FileStatus.CRCVerified) || !zFile.FileStatusIs(FileStatus.SHA1Verified) || !zFile.FileStatusIs(FileStatus.MD5Verified))) return false; } return true; }
private void UpdateGameGrid(RvDir tDir) { lblDITName.Text = tDir.Name; if (tDir.Dat != null) { RvDat tDat = tDir.Dat; lblDITDescription.Text = tDat.GetData(RvDat.DatData.Description); lblDITCategory.Text = tDat.GetData(RvDat.DatData.Category); lblDITVersion.Text = tDat.GetData(RvDat.DatData.Version); lblDITAuthor.Text = tDat.GetData(RvDat.DatData.Author); lblDITDate.Text = tDat.GetData(RvDat.DatData.Date); } else if (tDir.DirDatCount == 1) { RvDat tDat = tDir.DirDat(0); lblDITDescription.Text = tDat.GetData(RvDat.DatData.Description); lblDITCategory.Text = tDat.GetData(RvDat.DatData.Category); lblDITVersion.Text = tDat.GetData(RvDat.DatData.Version); lblDITAuthor.Text = tDat.GetData(RvDat.DatData.Author); lblDITDate.Text = tDat.GetData(RvDat.DatData.Date); } else { lblDITDescription.Text = ""; lblDITCategory.Text = ""; lblDITVersion.Text = ""; lblDITAuthor.Text = ""; lblDITDate.Text = ""; } lblDITPath.Text = tDir.FullName; lblDITRomsGot.Text = tDir.DirStatus.CountCorrect().ToString(CultureInfo.InvariantCulture); lblDITRomsMissing.Text = tDir.DirStatus.CountMissing().ToString(CultureInfo.InvariantCulture); lblDITRomsFixable.Text = tDir.DirStatus.CountFixesNeeded().ToString(CultureInfo.InvariantCulture); lblDITRomsUnknown.Text = (tDir.DirStatus.CountUnknown() + tDir.DirStatus.CountInToSort()).ToString(CultureInfo.InvariantCulture); _updatingGameGrid = true; if (Settings.IsMono) { if (GameGrid.RowCount > 0) GameGrid.CurrentCell = GameGrid[0,0]; if (RomGrid.RowCount > 0) RomGrid.CurrentCell = RomGrid[0,0]; } GameGrid.Rows.Clear(); RomGrid.Rows.Clear(); // clear sorting GameGrid.Columns[_gameGridSortColumnIndex].HeaderCell.SortGlyphDirection = SortOrder.None; _gameGridSortColumnIndex = 0; _gameGridSortOrder = SortOrder.Descending; ReportStatus tDirStat; _gameGridColumnXPositions = new int[(int)RepStatus.EndValue]; int rowCount = 0; for (int j = 0; j < tDir.ChildCount; j++) { RvDir tChildDir = tDir.Child(j) as RvDir; if (tChildDir == null) continue; tDirStat = tChildDir.DirStatus; bool gCorrect = tDirStat.HasCorrect(); bool gMissing = tDirStat.HasMissing(); bool gUnknown = tDirStat.HasUnknown(); bool gInToSort = tDirStat.HasInToSort(); bool gFixes = tDirStat.HasFixesNeeded(); bool show = (chkBoxShowCorrect.Checked && gCorrect && !gMissing && !gFixes); show = show || (chkBoxShowMissing.Checked && gMissing); show = show || (chkBoxShowFixed.Checked && gFixes); show = show || (gUnknown); show = show || (gInToSort); show = show || (tChildDir.GotStatus == GotStatus.Corrupt); show = show || !(gCorrect || gMissing || gUnknown || gInToSort || gFixes); if (!show) continue; rowCount++; int columnIndex = 0; for (int l = 0; l < RepairStatus.DisplayOrder.Length; l++) { if (l >= 13) columnIndex = l; if (tDirStat.Get(RepairStatus.DisplayOrder[l]) <= 0) continue; int len = DigitLength(tDirStat.Get(RepairStatus.DisplayOrder[l])) * 7 + 26; if (len > _gameGridColumnXPositions[columnIndex]) _gameGridColumnXPositions[columnIndex] = len; columnIndex++; } } GameGrid.RowCount = rowCount; int t = 0; for (int l = 0; l < (int)RepStatus.EndValue; l++) { int colWidth = _gameGridColumnXPositions[l]; _gameGridColumnXPositions[l] = t; t += colWidth; } int row = 0; for (int j = 0; j < tDir.ChildCount; j++) { RvDir tChildDir = tDir.Child(j) as RvDir; if (tChildDir == null) continue; tDirStat = tChildDir.DirStatus; bool gCorrect = tDirStat.HasCorrect(); bool gMissing = tDirStat.HasMissing(); bool gUnknown = tDirStat.HasUnknown(); bool gFixes = tDirStat.HasFixesNeeded(); bool gInToSort = tDirStat.HasInToSort(); bool show = (chkBoxShowCorrect.Checked && gCorrect && !gMissing && !gFixes); show = show || (chkBoxShowMissing.Checked && gMissing); show = show || (chkBoxShowFixed.Checked && gFixes); show = show || (gUnknown); show = show || (gInToSort); show = show || (tChildDir.GotStatus == GotStatus.Corrupt); show = show || !(gCorrect || gMissing || gUnknown || gInToSort || gFixes); if (!show) continue; GameGrid.Rows[row].Selected = false; GameGrid.Rows[row].Tag = tChildDir; row++; } _updatingGameGrid = false; UpdateRomGrid(tDir); }
private static void UpdateDirs(RvDir dbDir, RvDir fileDir) { int dbIndex = 0; int scanIndex = 0; dbDir.DatStatus=DatStatus.InDatCollect; if (dbDir.Tree == null) { Debug.WriteLine("Adding Tree View to " + dbDir.Name); dbDir.Tree = new RvTreeRow(); } Debug.WriteLine(""); Debug.WriteLine("Now scanning dirs"); while (dbIndex < dbDir.ChildCount || scanIndex < fileDir.ChildCount) { RvBase dbChild = null; RvBase fileChild = null; int res = 0; if (dbIndex < dbDir.ChildCount && scanIndex < fileDir.ChildCount) { dbChild = dbDir.Child(dbIndex); fileChild = fileDir.Child(scanIndex); res = DBHelper.CompareName(dbChild, fileChild); Debug.WriteLine("Checking " + dbChild.Name + " : and " + fileChild.Name + " : " + res); } else if (scanIndex < fileDir.ChildCount) { fileChild = fileDir.Child(scanIndex); res = 1; Debug.WriteLine("Checking : and " + fileChild.Name + " : " + res); } else if (dbIndex < dbDir.ChildCount) { dbChild = dbDir.Child(dbIndex); res = -1; } switch (res) { case 0: // found a matching directory in DATRoot So recurse back into it if (dbChild.GotStatus == GotStatus.Got) { if (dbChild.Name != fileChild.Name) // check if the case of the Item in the DB is different from the Dat Root Actual filename { if (!string.IsNullOrEmpty(dbChild.FileName)) // if we do not already have a different case name stored { dbChild.FileName = dbChild.Name; // copy the DB filename to the FileName } else // We already have a different case filename found in ROMRoot { if (dbChild.FileName == fileChild.Name) // check if the DATRoot name does now match the name in the DB Filename { dbChild.FileName = null; // if it does undo the BadCase Flag } } dbChild.Name = fileChild.Name; // Set the db Name to match the DATRoot Name. } } else dbChild.Name = fileChild.Name; UpdateDatList((RvDir)dbChild,(RvDir)fileChild); dbIndex++; scanIndex++; break; case 1: // found a new directory in Dat RvDir tDir = new RvDir(FileType.Dir) { Name = fileChild.Name, Tree = new RvTreeRow(), DatStatus = DatStatus.InDatCollect, }; dbDir.ChildAdd(tDir, dbIndex); Debug.WriteLine("Adding new Dir and Calling back in to check this DIR " + tDir.Name); UpdateDatList(tDir,(RvDir)fileChild); dbIndex++; scanIndex++; break; case -1: // all files dbIndex++; break; } } }
/* private static void SetInDat(RvDir tDir) { tDir.DatStatus = DatStatus.InDatCollect; if (tDir.Parent != null) SetInDat(tDir.Parent); } */ private static Boolean MergeInDat(RvDir dbDat, RvDir newDat, out RvDat conflict, bool checkOnly) { conflict = null; int dbIndex = 0; int newIndex = 0; while (dbIndex < dbDat.ChildCount || newIndex < newDat.ChildCount) { RvBase dbChild = null; RvBase newDatChild = null; int res = 0; if (dbIndex < dbDat.ChildCount && newIndex < newDat.ChildCount) { dbChild = dbDat.Child(dbIndex); // are files newDatChild = newDat.Child(newIndex); // is from a dat item res = DBHelper.CompareName(dbChild, newDatChild); } else if (newIndex < newDat.ChildCount) { newDatChild = newDat.Child(newIndex); res = 1; } else if (dbIndex < dbDat.ChildCount) { dbChild = dbDat.Child(dbIndex); res = -1; } if (res == 0) { if (dbChild == null || newDatChild == null) { SendAndShowDat(Resources.DatUpdate_MergeInDat_Error_in_Logic, dbDat.FullName); break; } List<RvBase> dbDats = new List<RvBase>(); List<RvBase> newDats = new List<RvBase>(); int dbDatsCount = 1; int newDatsCount = 1; dbDats.Add(dbChild); newDats.Add(newDatChild); while (dbIndex + dbDatsCount < dbDat.ChildCount && DBHelper.CompareName(dbChild, dbDat.Child(dbIndex + dbDatsCount)) == 0) { dbDats.Add(dbDat.Child(dbIndex + dbDatsCount)); dbDatsCount += 1; } while (newIndex + newDatsCount < newDat.ChildCount && DBHelper.CompareName(newDatChild, newDat.Child(newIndex + newDatsCount)) == 0) { newDats.Add(newDat.Child(newIndex + newDatsCount)); newDatsCount += 1; } if (dbDatsCount > 1 || newDatsCount > 1) { ReportError.SendAndShow("Double Name Found"); } for (int indexdb = 0; indexdb < dbDatsCount; indexdb++) { if (dbDats[indexdb].DatStatus == DatStatus.NotInDat) continue; if (checkOnly) { conflict = dbChild.Dat; return true; } SendAndShowDat(Resources.DatUpdate_MergeInDat_Unkown_Update_Dat_Status + dbChild.DatStatus, dbDat.FullName); break; } if (!checkOnly) { for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) { if (newDats[indexNewDats].SearchFound) continue; for (int indexDbDats = 0; indexDbDats < dbDatsCount; indexDbDats++) { if (dbDats[indexDbDats].SearchFound) continue; bool matched = FullCompare(dbDats[indexDbDats], newDats[indexNewDats]); if (!matched) continue; dbDats[indexDbDats].DatAdd(newDats[indexNewDats]); FileType ft = dbChild.FileType; if (ft == FileType.Zip || ft == FileType.Dir) { RvDir dChild = (RvDir)dbChild; RvDir dNewChild = (RvDir)newDatChild; MergeInDat(dChild, dNewChild, out conflict, checkOnly); } dbDats[indexDbDats].SearchFound = true; newDats[indexNewDats].SearchFound = true; } } for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) { if (newDats[indexNewDats].SearchFound) continue; dbDat.ChildAdd(newDats[indexNewDats], dbIndex); dbChild = dbDat.Child(dbIndex); SetMissingStatus(dbChild); dbIndex++; } } dbIndex += dbDatsCount; newIndex += newDatsCount; } if (res == 1) { if (!checkOnly) { dbDat.ChildAdd(newDatChild, dbIndex); dbChild = dbDat.Child(dbIndex); SetMissingStatus(dbChild); dbIndex++; } newIndex++; } if (res == -1) { dbIndex++; } } return false; }
private bool CheckMouseDown(RvDir pTree, int x, int y, MouseEventArgs mevent) { if (pTree.Tree.RChecked.Contains(x, y)) { if (pTree.Tree.Checked == RvTreeRow.TreeSelect.Disabled) return true; _mousehit = true; SetChecked(pTree, pTree.Tree.Checked == RvTreeRow.TreeSelect.Selected ? RvTreeRow.TreeSelect.UnSelected : RvTreeRow.TreeSelect.Selected); return true; } if (pTree.Tree.RExpand.Contains(x, y)) { _mousehit = true; SetExpanded(pTree, mevent.Button == MouseButtons.Right); return true; } if (pTree.Tree.RText.Contains(x, y)) { _mousehit = true; if (RvSelected != null) RvSelected(pTree, mevent); _lSelected = pTree; return true; } if (pTree.Tree.TreeExpanded) for (int i = 0; i < pTree.ChildCount; i++) { RvBase rBase = pTree.Child(i); if (rBase is RvDir) { RvDir rDir = (RvDir)rBase; if (rDir.Tree != null) if (CheckMouseDown(rDir, x, y, mevent)) return true; } } return false; }
private static void SetExpanded(RvDir pTree, bool rightClick) { if (!rightClick) { pTree.Tree.TreeExpanded = !pTree.Tree.TreeExpanded; return; } // Find the value of the first child node. for (int i = 0; i < pTree.ChildCount; i++) { RvBase b = pTree.Child(i); if (b is RvDir) { RvDir d = (RvDir)b; if (d.Tree != null) { //Recusivly Set All Child Nodes to this value SetExpandedRecurse(pTree, !d.Tree.TreeExpanded); break; } } } }
private static void DatSetRenameAndRemoveDups(RvDir tDat) { for (int g = 0; g < tDat.ChildCount; g++) { RvDir tDir = (RvDir)tDat.Child(g); if (tDir.Game == null) { DatSetRenameAndRemoveDups(tDir); } else { for (int r = 0; r < tDir.ChildCount - 1; r++) { RvFile f0 = (RvFile)tDir.Child(r); RvFile f1 = (RvFile)tDir.Child(r + 1); if (f0.Name != f1.Name) continue; if (f0.Size != f1.Size || !ArrByte.bCompare(f0.CRC, f1.CRC)) { tDir.ChildRemove(r + 1); // remove F1 f1.Name = f1.Name + "_" + ArrByte.ToString(f1.CRC); // rename F1; int pos = tDir.ChildAdd(f1); if (pos < r) r = pos; // if this rename moved the File back up the list, start checking again from that file. } else { tDir.ChildRemove(r + 1); } r--; } } } }
private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode) { if (romNode.Attributes == null) return; XmlNode name = romNode.Attributes.GetNamedItem("name"); string loadflag = VarFix.String(romNode.Attributes.GetNamedItem("loadflag")); if (name != null) { RvFile tRom = new RvFile(FileType.ZipFile) { Name = VarFix.CleanFullFileName(name), Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")), Dat = tGame.Dat }; if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); _indexContinue = tGame.ChildAdd(tRom); } else if (loadflag.ToLower() == "continue") { RvFile tZippedFile = (RvFile)tGame.Child(_indexContinue); tZippedFile.Size += VarFix.ULong(romNode.Attributes.GetNamedItem("size")); } }
private static void ReportMissingFindSizes(RvDir dir, RvDat dat, ReportType rt) { for (int i = 0; i < dir.ChildCount; i++) { RvBase b = dir.Child(i); if (b.Dat != null && b.Dat != dat) continue; RvFile f = b as RvFile; if (f != null) { if ( (rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) || (rt == ReportType.Fixing && Fixing.Contains(f.RepStatus)) ) { int fileNameLength = f.FileNameInsideGame().Length; int fileSizeLength = f.Size.ToString().Length; int repStatusLength = f.RepStatus.ToString().Length; if (fileNameLength > _fileNameLength) _fileNameLength = fileNameLength; if (fileSizeLength > _fileSizeLength) _fileSizeLength = fileSizeLength; if (repStatusLength > _repStatusLength) _repStatusLength = repStatusLength; } } RvDir d = b as RvDir; if (d != null) ReportMissingFindSizes(d, dat, rt); } }
private static void ReportMissing(RvDir dir, RvDat dat, ReportType rt) { for (int i = 0; i < dir.ChildCount; i++) { RvBase b = dir.Child(i); if (b.Dat != null && b.Dat != dat) continue; RvFile f = b as RvFile; if (f != null) { if ( (rt == ReportType.PartialMissing && Partial.Contains(f.RepStatus)) || (rt == ReportType.Fixing && Fixing.Contains(f.RepStatus)) ) { string filename = f.FileNameInsideGame(); string crc = ArrByte.ToString(f.CRC); _ts.WriteLine("| " + filename + new string(' ', _fileNameLength + 1 - filename.Length) + "| " + f.Size + new string(' ', _fileSizeLength + 1 - f.Size.ToString().Length) + "| " + crc + new string(' ', 9 - crc.Length) + "| " + f.RepStatus + new string(' ', _repStatusLength + 1 - f.RepStatus.ToString().Length) + "|"); } } RvDir d = b as RvDir; if (d != null) ReportMissing(d, dat, rt); } }
private static ReturnCode FixZip(RvDir fixZip) { //Check for error status if (fixZip.DirStatus.HasUnknown()) return ReturnCode.FindFixes; // Error bool needsTrrntzipped = fixZip.ZipStatus != ZipStatus.TrrntZip && fixZip.GotStatus == GotStatus.Got && fixZip.DatStatus == DatStatus.InDatCollect && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3); // file corrupt and not in tosort // if file cannot be fully fixed copy to corrupt // process zipfile if (fixZip.GotStatus == GotStatus.Corrupt && fixZip.DatStatus != DatStatus.InToSort) { ReturnCode movReturnCode = MoveZiptoCorrupt(fixZip); if (movReturnCode != ReturnCode.Good) return movReturnCode; } // has fixable // process zipfile else if (fixZip.DirStatus.HasFixable()) { // do nothing here but continue on to process zip. } // need trrntzipped // process zipfile else if (needsTrrntzipped) { // do nothing here but continue on to process zip. } // got empty zip that should be deleted // process zipfile else if (fixZip.GotStatus == GotStatus.Got && fixZip.GotStatus != GotStatus.Corrupt && !fixZip.DirStatus.HasAnyFiles()) { // do nothing here but continue on to process zip. } // else // skip this zipfile else { // nothing can be done to return return ReturnCode.Good; } string fixZipFullName = fixZip.TreeFullName; if (!fixZip.DirStatus.HasFixable() && needsTrrntzipped) ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), "", 0, "TrrntZipping", "", "", "")); CheckCreateParent(fixZip.Parent); ReportError.LogOut(""); ReportError.LogOut(fixZipFullName + " : " + fixZip.RepStatus); ReportError.LogOut("------------------------------------------------------------"); Debug.WriteLine(fixZipFullName + " : " + fixZip.RepStatus); ReportError.LogOut("Zip File Status Before Fix:"); for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) ReportError.LogOut((RvFile)fixZip.Child(intLoop)); ReportError.LogOut(""); ZipFile tempZipOut = null; ZipFile toSortCorruptOut = null; ZipFile toSortZipOut = null; RvDir toSortGame = null; RvDir toSortCorruptGame = null; ReturnCode returnCode; List<RvFile> fixZipTemp = new List<RvFile>(); for (int iRom = 0; iRom < fixZip.ChildCount; iRom++) { RvFile zipFileFixing = new RvFile(FileType.ZipFile); fixZip.Child(iRom).CopyTo(zipFileFixing); if (iRom == fixZipTemp.Count) fixZipTemp.Add(zipFileFixing); else fixZipTemp[iRom] = zipFileFixing; ReportError.LogOut(zipFileFixing.RepStatus + " : " + fixZip.Child(iRom).FullName); switch (zipFileFixing.RepStatus) { #region Nothing to copy // any file we do not have or do not want in the destination zip case RepStatus.Missing: case RepStatus.NotCollected: case RepStatus.Rename: case RepStatus.Delete: if (! ( // got the file in the original zip but will be deleting it (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Corrupt) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) || // do not have this file and cannot fix it here (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.NotGot) || (zipFileFixing.DatStatus == DatStatus.InDatBad && zipFileFixing.GotStatus == GotStatus.NotGot) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.NotGot) ) ) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); if (zipFileFixing.RepStatus == RepStatus.Delete) { returnCode = DoubleCheckDelete(zipFileFixing); if (returnCode != ReturnCode.Good) goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; break; #endregion #region Copy from Original to Destination // any files we are just moving from the original zip to the destination zip case RepStatus.Correct: case RepStatus.InToSort: case RepStatus.NeededForFix: case RepStatus.Corrupt: { if (! ( (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) ) ) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); RvFile foundFile; bool rawcopy = (zipFileFixing.RepStatus == RepStatus.InToSort) || (zipFileFixing.RepStatus == RepStatus.Corrupt); // Correct rawcopy=false // NeededForFix rawcopy=false // InToSort rawcopy=true // Corrupt rawcopy=true RepStatus originalStatus = zipFileFixing.RepStatus; returnCode = FixFileCopy.CopyFile( (RvFile)fixZip.Child(iRom), ref tempZipOut, Path.Combine(fixZip.Parent.FullName, "__RomVault.tmp"), zipFileFixing, rawcopy, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; if (originalStatus == RepStatus.NeededForFix) zipFileFixing.RepStatus = RepStatus.NeededForFix; break; case ReturnCode.SourceCRCCheckSumError: { RvFile tFile = (RvFile)fixZip.Child(iRom); tFile.GotStatus = GotStatus.Corrupt; ReCheckFile(tFile); //decrease index so this file gets reprocessed iRom--; continue; } case ReturnCode.SourceCheckSumError: { // Set the file in the zip that we thought we correctly had as missing RvFile tFile = (RvFile)fixZip.Child(iRom); if (tFile.FileRemove() == EFile.Delete) { _error = "Should not mark for delete as it is in a DAT"; return ReturnCode.LogicError; } // Add in at the current location the incorrect file. (This file will be reprocessed and then at some point deleted.) fixZip.ChildAdd(foundFile, iRom); AddFoundFile(foundFile); ReCheckFile(tFile); //decrease index so this file gets reprocessed iRom--; continue; } // not needed as source and destination are the same // case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } } break; #endregion #region Case.CanBeFixed case RepStatus.CanBeFixed: case RepStatus.CorruptCanBeFixed: { if (!(zipFileFixing.DatStatus == DatStatus.InDatCollect && (zipFileFixing.GotStatus == GotStatus.NotGot || zipFileFixing.GotStatus == GotStatus.Corrupt))) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Fixing File:"); ReportError.LogOut(zipFileFixing); string strPath = fixZip.Parent.FullName; string tempZipFilename = Path.Combine(strPath, "__RomVault.tmp"); if (DBHelper.IsZeroLengthFile(zipFileFixing)) { RvFile fileIn = new RvFile(FileType.ZipFile) { Size = 0 }; RvFile foundFile; returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } break; } #if NEWFINDFIX List<RvFile> lstFixRomTable = new List<RvFile>(); List<RvFile> family = zipFileFixing.MyFamily.Family; for (int iFind = 0; iFind < family.Count; iFind++) { if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(zipFileFixing, family[iFind])) lstFixRomTable.Add(family[iFind]); } #else List<RvFile> lstFixRomTable; DBHelper.RomSearchFindFixes(zipFileFixing, _lstRomTableSortedCRCSize, out lstFixRomTable); #endif ReportError.LogOut("Found Files To use for Fixes:"); foreach (RvFile t in lstFixRomTable) ReportError.LogOut(t); if (lstFixRomTable.Count > 0) { string ts = lstFixRomTable[0].Parent.FullName; string sourceDir; string sourceFile; if (lstFixRomTable[0].FileType == FileType.ZipFile) { sourceDir = Path.GetDirectoryName(ts); sourceFile = Path.GetFileName(ts); } else { sourceDir = ts; sourceFile = ""; } ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "<--", sourceDir, sourceFile, lstFixRomTable[0].Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile(lstFixRomTable[0], ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply so continue; break; case ReturnCode.SourceCRCCheckSumError: { ReportProgress(new bgwShowFixError("CRC Error")); // the file we used for fix turns out to be corrupt RvFile tFile = (RvFile)fixZip.Child(iRom); // mark the source file as Corrupt lstFixRomTable[0].GotStatus = GotStatus.Corrupt; // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. if (!_processList.Contains(lstFixRomTable[0].Parent)) _processList.Add(lstFixRomTable[0].Parent); // and go back one and try again. iRom--; continue; } case ReturnCode.SourceCheckSumError: { ReportProgress(new bgwShowFixError("Failed")); // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1 // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled) RvFile tFile = (RvFile)fixZip.Child(iRom); // remove the file we thought we correctly had (The file that we where trying to use for the fix) if (lstFixRomTable[0].FileRemove() == EFile.Delete) { _error = "Should not mark for delete as it is in a DAT"; return ReturnCode.LogicError; } // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine // instead of restarting. // add in the actual file we found lstFixRomTable[0].Parent.ChildAdd(foundFile); AddFoundFile(foundFile); // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. if (!_processList.Contains(lstFixRomTable[0].Parent)) _processList.Add(lstFixRomTable[0].Parent); // and go back one and try again. iRom--; continue; } case ReturnCode.DestinationCheckSumError: { ReportProgress(new bgwShowFixError("Failed")); // the file we used for fix turns out not to have the correct MD5/SHA1 RvFile tFile = (RvFile)fixZip.Child(iRom); // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. // The need for this is that the file being pulled in from inside this zip will be marked as Rename // and so would then automatically be deleted, in the case this exception happens, this source file instead // should be set to move to tosort. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // and go back one and try again. iRom--; continue; } default: //_error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + Environment.NewLine + _error; goto ZipOpenFailed; } //Check to see if the files used for fix, can now be set to delete CheckReprocessClearList(); foreach (RvFile tFixRom in lstFixRomTable) { if (tFixRom.RepStatus == RepStatus.NeededForFix) { tFixRom.RepStatus = RepStatus.Delete; ReportError.LogOut("Setting File Status to Delete:"); ReportError.LogOut(tFixRom); CheckReprocess(tFixRom, true); } } CheckReprocessFinalCheck(); _fixed++; } else // thought we could fix it, turns out we cannot zipFileFixing.GotStatus = GotStatus.NotGot; } break; #endregion #region Case.MoveToSort case RepStatus.MoveToSort: { if (!(zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got)) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Moving File out to ToSort:"); ReportError.LogOut(zipFileFixing); // move the rom out to the To Sort Directory if (toSortGame == null) { string toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + ".zip"); string toSortFileName = fixZip.Name; int fileC = 0; while (File.Exists(toSortFullName)) { fileC++; toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + fileC + ".zip"); toSortFileName = fixZip.Name + fileC; } toSortGame = new RvDir(FileType.Zip) { Name = toSortFileName, DatStatus = DatStatus.InToSort, GotStatus = GotStatus.Got }; } RvFile toSortRom = new RvFile(FileType.ZipFile) { Name = zipFileFixing.Name, Size = zipFileFixing.Size, CRC = zipFileFixing.CRC, SHA1 = zipFileFixing.SHA1, MD5 = zipFileFixing.MD5 }; toSortRom.SetStatus(DatStatus.InToSort, GotStatus.Got); toSortRom.FileStatusSet( FileStatus.SizeFromHeader | FileStatus.SizeVerified | FileStatus.CRCFromHeader | FileStatus.CRCVerified | FileStatus.SHA1FromHeader | FileStatus.SHA1Verified | FileStatus.MD5FromHeader | FileStatus.MD5Verified , zipFileFixing); toSortGame.ChildAdd(toSortRom); string destination = Path.Combine(Settings.ToSort(), toSortGame.Name + ".zip"); ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "ToSort", Path.GetFileName(destination), toSortRom.Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortZipOut, destination, toSortRom, true, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; //raw copying so Checksums are not checked //case ReturnCode.SourceCRCCheckSumError: //case ReturnCode.SourceCheckSumError: //case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; // Changes RepStatus to Deleted } break; #endregion #region Case.MoveToCorrupt case RepStatus.MoveToCorrupt: { if (!((zipFileFixing.DatStatus == DatStatus.InDatCollect || zipFileFixing.DatStatus == DatStatus.NotInDat) && zipFileFixing.GotStatus == GotStatus.Corrupt)) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Moving File to Corrupt"); ReportError.LogOut(zipFileFixing); string toSortFullName; if (toSortCorruptGame == null) { string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); if (!Directory.Exists(corruptDir)) { Directory.CreateDirectory(corruptDir); } toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip"); string toSortFileName = fixZip.Name; int fileC = 0; while (File.Exists(toSortFullName)) { fileC++; toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip"); toSortFileName = fixZip.Name + fileC; } toSortCorruptGame = new RvDir(FileType.Zip) { Name = toSortFileName, DatStatus = DatStatus.InToSort, GotStatus = GotStatus.Got }; } else { string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); toSortFullName = Path.Combine(corruptDir, toSortCorruptGame.Name + ".zip"); } RvFile toSortCorruptRom = new RvFile(FileType.ZipFile) { Name = zipFileFixing.Name, Size = zipFileFixing.Size, CRC = zipFileFixing.CRC }; toSortCorruptRom.SetStatus(DatStatus.InToSort, GotStatus.Corrupt); toSortCorruptGame.ChildAdd(toSortCorruptRom); ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "Corrupt", Path.GetFileName(toSortFullName), zipFileFixing.Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortCorruptOut, toSortFullName, toSortCorruptRom, true, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; // doing a raw copy so not needed // case ReturnCode.SourceCRCCheckSumError: // case ReturnCode.SourceCheckSumError: // case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; } break; #endregion default: ReportError.UnhandledExceptionHandler("Unknown file status found " + zipFileFixing.RepStatus + " while fixing file " + fixZip.Name + " Dat Status = " + zipFileFixing.DatStatus + " GotStatus " + zipFileFixing.GotStatus); break; } } #region if ToSort Zip Made then close the zip and add this new zip to the Database if (toSortGame != null) { toSortZipOut.ZipFileClose(); toSortGame.TimeStamp = toSortZipOut.TimeStamp; toSortGame.DatStatus = DatStatus.InToSort; toSortGame.GotStatus = GotStatus.Got; toSortGame.ZipStatus = toSortZipOut.ZipStatus; RvDir toSort = (RvDir)DB.DirTree.Child(1); toSort.ChildAdd(toSortGame); } #endregion #region if Corrupt Zip Made then close the zip and add this new zip to the Database if (toSortCorruptGame != null) { toSortCorruptOut.ZipFileClose(); toSortCorruptGame.TimeStamp = toSortCorruptOut.TimeStamp; toSortCorruptGame.DatStatus = DatStatus.InToSort; toSortCorruptGame.GotStatus = GotStatus.Got; RvDir toSort = (RvDir)DB.DirTree.Child(1); int indexcorrupt; RvDir corruptDir = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort }; int found = toSort.ChildNameSearch(corruptDir, out indexcorrupt); if (found != 0) { corruptDir.GotStatus = GotStatus.Got; indexcorrupt = toSort.ChildAdd(corruptDir); } ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame); } #endregion #region Process original Zip string filename = fixZip.FullName; if (File.Exists(filename)) { if (!File.SetAttributes(filename, FileAttributes.Normal)) { int error = Error.GetLastError(); ReportProgress(new bgwShowError(filename, "Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error)); } try { File.Delete(filename); } catch (Exception) { int error = Error.GetLastError(); _error = "Error While trying to delete file " + filename + ". Code " + error; if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) tempZipOut.ZipFileClose(); return ReturnCode.RescanNeeded; } } #endregion bool checkDelete = false; #region process the temp Zip rename it to the original Zip if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) { string tempFilename = tempZipOut.ZipFilename; tempZipOut.ZipFileClose(); if (tempZipOut.LocalFilesCount() > 0) { // now rename the temp fix file to the correct filename File.Move(tempFilename, filename); FileInfo nFile = new FileInfo(filename); RvDir tmpZip = new RvDir(FileType.Zip) { Name = Path.GetFileNameWithoutExtension(filename), TimeStamp = nFile.LastWriteTime }; tmpZip.SetStatus(fixZip.DatStatus, GotStatus.Got); fixZip.FileAdd(tmpZip); fixZip.ZipStatus = tempZipOut.ZipStatus; } else { File.Delete(tempFilename); checkDelete = true; } } else checkDelete = true; #endregion #region Now put the New Game Status information into the Database. int intLoopFix = 0; foreach (RvFile tmpZip in fixZipTemp) { tmpZip.CopyTo(fixZip.Child(intLoopFix)); if (fixZip.Child(intLoopFix).RepStatus == RepStatus.Deleted) if (fixZip.Child(intLoopFix).FileRemove() == EFile.Delete) { fixZip.ChildRemove(intLoopFix); continue; } intLoopFix++; } #endregion if (checkDelete) CheckDeleteObject(fixZip); ReportError.LogOut(""); ReportError.LogOut("Zip File Status After Fix:"); for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) ReportError.LogOut((RvFile)fixZip.Child(intLoop)); ReportError.LogOut(""); return ReturnCode.Good; ZipOpenFailed: if (tempZipOut != null) tempZipOut.ZipFileCloseFailed(); if (toSortZipOut != null) toSortZipOut.ZipFileCloseFailed(); if (toSortCorruptOut != null) toSortCorruptOut.ZipFileCloseFailed(); return returnCode; }
private static ReturnCode FixDir(RvDir dir, bool lastSelected) { Debug.WriteLine(dir.FullName); bool thisSelected = lastSelected; if (dir.Tree != null) thisSelected = dir.Tree.Checked == RvTreeRow.TreeSelect.Selected; List<RvBase> lstToProcess = new List<RvBase>(); for (int j = 0; j < dir.ChildCount; j++) lstToProcess.Add(dir.Child(j)); foreach (RvBase child in lstToProcess) { ReturnCode returnCode = FixBase(child, thisSelected); if (returnCode != ReturnCode.Good) return returnCode; while (_processList.Count > 0) { returnCode = FixBase(_processList[0], true); if (returnCode != ReturnCode.Good) return returnCode; _processList.RemoveAt(0); } if (_fixed != _reportedFixed) { ReportProgress(new bgwProgress(_fixed)); _reportedFixed = _fixed; } if (_bgw.CancellationPending) break; } // here we check to see if the directory we just scanned should be deleted CheckDeleteObject(dir); return ReturnCode.Good; }
private static void SetChecked(RvDir pTree, RvTreeRow.TreeSelect nSelection) { pTree.Tree.Checked = nSelection; for (int i = 0; i < pTree.ChildCount; i++) { RvBase b = pTree.Child(i); if (b is RvDir) { RvDir d = (RvDir)b; if (d.Tree != null) { SetChecked(d, nSelection); } } } }
private static void DatSetRemoveUnneededDirs(RvDir tDat) { for (int g = 0; g < tDat.ChildCount; g++) { RvDir tGame = (RvDir)tDat.Child(g); if (tGame.Game == null) { DatSetRemoveUnneededDirs(tGame); } else { for (int r = 0; r < tGame.ChildCount - 1; r++) { // first find any directories, zero length with filename ending in a '/' // there are RvFiles that are really directories (probably inside a zip file) RvFile f0 = (RvFile)tGame.Child(r); if (f0.Name.Length == 0) continue; if (f0.Name.Substring(f0.Name.Length - 1, 1) != "/") continue; // if the next file contains that found directory, then the directory file can be deleted RvFile f1 = (RvFile)tGame.Child(r + 1); if (f1.Name.Length <= f0.Name.Length) continue; if (f0.Name != f1.Name.Substring(0, f0.Name.Length)) continue; tGame.ChildRemove(r); r--; } } } }
private static void SetExpandedRecurse(RvDir pTree, bool expanded) { for (int i = 0; i < pTree.ChildCount; i++) { RvBase b = pTree.Child(i); if (b is RvDir) { RvDir d = (RvDir)b; if (d.Tree != null) { d.Tree.TreeExpanded = expanded; SetExpandedRecurse(d, expanded); } } } }
private static void DatSetCheckParentSets(RvDir tDat) { // First we are going to try and fix any missing CRC information by checking for roms with the same names // in Parent and Child sets, and if the same named rom is found and one has a CRC and the other does not // then we will set the missing CRC by using the CRC in the other set. // we keep trying to find fixes until no more fixes are found. // this is need as the first time round a fix could be found in a parent set from one child set. // then the second time around that fixed parent set could fix another of its childs sets. for (int g = 0; g < tDat.ChildCount; g++) { RvDir mGame = (RvDir)tDat.Child(g); if (mGame.Game == null) // this is a directory so recuse into it DatSetCheckParentSets(mGame); } bool fix = true; while (fix) { fix = false; // loop around every ROM Set looking for fixes. for (int g = 0; g < tDat.ChildCount; g++) { // get a list of that ROM Sets parents. RvDir mGame = (RvDir)tDat.Child(g); if (mGame.Game == null) continue; List<RvDir> lstParentGames = new List<RvDir>(); FindParentSet(mGame, tDat, ref lstParentGames); // if this set have parents if (lstParentGames.Count == 0) continue; // now loop every ROM in the current set. for (int r = 0; r < mGame.ChildCount; r++) { // and loop every ROM of every parent set of this current set. // and see if anything can be fixed. bool found = false; // loop the parent sets foreach (RvDir romofGame in lstParentGames) { // loop the ROMs in the parent sets for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { // don't search fixes for files marked as nodump if (((RvFile)mGame.Child(r)).Status == "nodump" || ((RvFile)romofGame.Child(r1)).Status == "nodump") continue; // only find fixes if the Name and the Size of the ROMs are the same if (mGame.Child(r).Name != romofGame.Child(r1).Name || ((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size) continue; // now check if one of the matching roms has missing or incorrect CRC information bool b1 = ((RvFile)mGame.Child(r)).CRC == null; bool b2 = ((RvFile)romofGame.Child(r1)).CRC == null; // if one has correct information and the other does not, fix the missing one if (b1 == b2) continue; if (b1) { ((RvFile)mGame.Child(r)).CRC = ((RvFile)romofGame.Child(r1)).CRC; ((RvFile)mGame.Child(r)).FileStatusSet(FileStatus.CRCFromDAT); ((RvFile)mGame.Child(r)).Status = "(CRCFound)"; } else { ((RvFile)romofGame.Child(r1)).CRC = ((RvFile)mGame.Child(r)).CRC; ((RvFile)romofGame.Child(r1)).FileStatusSet(FileStatus.CRCFromDAT); ((RvFile)romofGame.Child(r1)).Status = "(CRCFound)"; } // flag that a fix was found so that we will go all the way around again. fix = true; found = true; break; } if (found) break; } } } } }
private void PaintTree(RvDir pTree, Graphics g, Rectangle t) { int y = pTree.Tree.RTree.Top - _vScroll; if (pTree.Tree.RTree.IntersectsWith(t)) { Pen p = new Pen(Brushes.Gray, 1) { DashStyle = DashStyle.Dot }; string lTree = pTree.Tree.TreeBranches; for (int j = 0; j < lTree.Length; j++) { int x = j * 18 - _hScroll; string cTree = lTree.Substring(j, 1); switch (cTree) { case "│": g.DrawLine(p, x + 9, y, x + 9, y + 16); break; case "├": case "└": g.DrawLine(p, x + 9, y, x + 9, y + 16); g.DrawLine(p, x + 9, y + 16, x + 27, y + 16); break; } } } if (!pTree.Tree.RExpand.IsEmpty) if (pTree.Tree.RExpand.IntersectsWith(t)) { g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(pTree.Tree.RExpand, _hScroll, _vScroll)); } if (pTree.Tree.RChecked.IntersectsWith(t)) { switch (pTree.Tree.Checked) { case RvTreeRow.TreeSelect.Disabled: g.DrawImage(rvImages.TickBoxDisabled, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); break; case RvTreeRow.TreeSelect.UnSelected: g.DrawImage(rvImages.TickBoxUnTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); break; case RvTreeRow.TreeSelect.Selected: g.DrawImage(rvImages.TickBoxTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll)); break; } } if (pTree.Tree.RIcon.IntersectsWith(t)) { int icon = 2; if (pTree.DirStatus.HasInUnsorted()) { icon = 4; } else if (!pTree.DirStatus.HasCorrect()) { icon = 1; } else if (!pTree.DirStatus.HasMissing()) { icon = 3; } Bitmap bm; if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree bm = rvImages.GetBitmap("DirectoryTree" + icon); else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's bm = rvImages.GetBitmap("Tree" + icon); else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT bm = rvImages.GetBitmap("Tree" + icon); else { ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); bm = null; } if (bm != null) { g.DrawImage(bm, RSub(pTree.Tree.RIcon, _hScroll, _vScroll)); } } Rectangle recBackGround = new Rectangle(pTree.Tree.RText.X, pTree.Tree.RText.Y, Width - pTree.Tree.RText.X + _hScroll, pTree.Tree.RText.Height); if (recBackGround.IntersectsWith(t)) { string thistxt; if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree thistxt = pTree.Name; else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; // pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat else if (pTree.Dat != null && pTree.Dat.AutoAddDirectory && pTree.Parent.DirDatCount > 1) thistxt = pTree.Name + ": " + pTree.Dat.GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT thistxt = pTree.Name + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; else { ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); thistxt = ""; } if (_lSelected != null && pTree.TreeFullName == _lSelected.TreeFullName) { g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll)); g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.White, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll); } else { g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.Black, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll); } } if (pTree.Tree.TreeExpanded) for (int i = 0; i < pTree.ChildCount; i++) { RvBase tBase = pTree.Child(i); if (tBase is RvDir) { RvDir tDir = (RvDir)tBase; if (tDir.Tree != null) PaintTree(tDir, g, t); } } }
private static void DatSetMergeSets(RvDir tDat) { for (int g = tDat.ChildCount - 1; g >= 0; g--) { RvDir mGame = (RvDir)tDat.Child(g); if (mGame.Game == null) { DatSetMergeSets(mGame); continue; } List<RvDir> lstParentGames = new List<RvDir>(); FindParentSet(mGame, tDat, ref lstParentGames); while (lstParentGames.Count > 0 && lstParentGames[lstParentGames.Count - 1].Game.GetData(RvGame.GameData.IsBios).ToLower() == "yes") lstParentGames.RemoveAt(lstParentGames.Count - 1); if (lstParentGames.Count <= 0) continue; RvDir romofGame = lstParentGames[lstParentGames.Count - 1]; bool founderror = false; for (int r = 0; r < mGame.ChildCount; r++) { string name = mGame.Child(r).Name; string mergename = ((RvFile)mGame.Child(r)).Merge; for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) && (ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) != 0 || ((RvFile)mGame.Child(r)).Size != ((RvFile)romofGame.Child(r1)).Size)) founderror = true; } } if (founderror) { mGame.Game.DeleteData(RvGame.GameData.RomOf); continue; } for (int r = 0; r < mGame.ChildCount; r++) { string name = mGame.Child(r).Name; string mergename = ((RvFile)mGame.Child(r)).Merge; bool found = false; for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { if ((name == romofGame.Child(r1).Name || mergename == romofGame.Child(r1).Name) && (ArrByte.iCompare(((RvFile)mGame.Child(r)).CRC, ((RvFile)romofGame.Child(r1)).CRC) == 0 && ((RvFile)mGame.Child(r)).Size == ((RvFile)romofGame.Child(r1)).Size)) { found = true; break; } } if (!found) romofGame.ChildAdd(mGame.Child(r)); } tDat.ChildRemove(g); } }
private static void RemoveOldDats(RvBase dbDir, RvDir tmpDir) { // now compare the old and new dats removing any old dats // in the current directory RvDir lDir = dbDir as RvDir; if (lDir == null) return; int dbIndex = 0; int scanIndex = 0; while (dbIndex < lDir.DirDatCount || scanIndex < tmpDir.DirDatCount) { RvDat dbDat = null; RvDat fileDat = null; int res = 0; if (dbIndex < lDir.DirDatCount && scanIndex < tmpDir.DirDatCount) { dbDat = lDir.DirDat(dbIndex); fileDat = tmpDir.DirDat(scanIndex); res = DBHelper.DatCompare(dbDat, fileDat); } else if (scanIndex < tmpDir.DirDatCount) { //this is a new dat that we have now found at the end of the list //fileDat = tmpDir.DirDat(scanIndex); res = 1; } else if (dbIndex < lDir.DirDatCount) { dbDat = lDir.DirDat(dbIndex); res = -1; } switch (res) { case 0: dbDat.Status = DatUpdateStatus.Correct; dbIndex++; scanIndex++; break; case 1: // this is a new dat that we will add next time around scanIndex++; break; case -1: dbDat.Status = DatUpdateStatus.Delete; lDir.DirDatRemove(dbIndex); break; } } // now scan the child directory structure of this directory dbIndex = 0; scanIndex = 0; while (dbIndex < lDir.ChildCount || scanIndex < tmpDir.ChildCount) { RvBase dbChild = null; RvBase fileChild = null; int res = 0; if (dbIndex < lDir.ChildCount && scanIndex < tmpDir.ChildCount) { dbChild = lDir.Child(dbIndex); fileChild = tmpDir.Child(scanIndex); res = DBHelper.CompareName(dbChild, fileChild); } else if (scanIndex < tmpDir.ChildCount) { //found a new directory on the end of the list //fileChild = tmpDir.Child(scanIndex); res = 1; } else if (dbIndex < lDir.ChildCount) { dbChild = lDir.Child(dbIndex); res = -1; } switch (res) { case 0: // found a matching directory in DATRoot So recurse back into it RemoveOldDats(dbChild, (RvDir)fileChild); dbIndex++; scanIndex++; break; case 1: // found a new directory will be added later scanIndex++; break; case -1: if (dbChild.FileType == FileType.Dir && dbChild.Dat == null) RemoveOldDats(dbChild, new RvDir(FileType.Dir)); dbIndex++; break; } } }
private static void DatSetCheckCollect(RvDir tDat) { // now look for merged roms. // check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.ChildCount; g++) { RvDir mGame = (RvDir)tDat.Child(g); if (mGame.Game == null) DatSetCheckCollect(mGame); else { List<RvDir> lstParentGames = new List<RvDir>(); FindParentSet(mGame, tDat, ref lstParentGames); if (lstParentGames.Count == 0) { for (int r = 0; r < mGame.ChildCount; r++) RomCheckCollect((RvFile)mGame.Child(r), false); } else { for (int r = 0; r < mGame.ChildCount; r++) { bool found = false; foreach (RvDir romofGame in lstParentGames) { for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { if (mGame.Child(r).Name != romofGame.Child(r1).Name) continue; ulong? Size0 = ((RvFile)mGame.Child(r)).Size; ulong? Size1 = ((RvFile)romofGame.Child(r1)).Size; if (Size0 != null && Size1 != null && Size0 != Size1) continue; byte[] CRC0 = ((RvFile)mGame.Child(r)).CRC; byte[] CRC1 = ((RvFile)romofGame.Child(r1)).CRC; if (CRC0 != null && CRC1 != null && !ArrByte.bCompare(CRC0, CRC1)) continue; byte[] SHA0 = ((RvFile)mGame.Child(r)).SHA1; byte[] SHA1 = ((RvFile)romofGame.Child(r1)).SHA1; if (SHA0 != null && SHA1 != null && !ArrByte.bCompare(SHA0, SHA1)) continue; byte[] MD50 = ((RvFile)mGame.Child(r)).MD5; byte[] MD51 = ((RvFile)romofGame.Child(r1)).MD5; if (MD50 != null && MD51 != null && !ArrByte.bCompare(MD50, MD51)) continue; byte[] chdSHA0 = ((RvFile)mGame.Child(r)).SHA1CHD; byte[] chdSHA1 = ((RvFile)romofGame.Child(r1)).SHA1CHD; if (chdSHA0 != null && chdSHA1 != null && !ArrByte.bCompare(chdSHA0, chdSHA1)) continue; byte[] chdMD50 = ((RvFile)mGame.Child(r)).MD5CHD; byte[] chdMD51 = ((RvFile)romofGame.Child(r1)).MD5CHD; if (chdMD50 != null && chdMD51 != null && !ArrByte.bCompare(chdMD50, chdMD51)) continue; // don't merge if only one of the ROM is nodump if ((((RvFile)romofGame.Child(r1)).Status == "nodump") != (((RvFile)mGame.Child(r)).Status == "nodump")) continue; found = true; break; } if (found) break; } RomCheckCollect((RvFile)mGame.Child(r), found); } } } } }
private void AddDir(RvDir tGame, string pathAdd) { for (int l = 0; l < tGame.ChildCount; l++) { RvBase tBase = tGame.Child(l); RvFile tFile = tBase as RvFile; if (tFile != null) AddRom((RvFile)tBase, pathAdd); if (tGame.Dat == null) continue; RvDir tDir = tBase as RvDir; if (tDir == null) continue; if (tDir.Game == null) AddDir(tDir, pathAdd + tGame.Name + "/"); } }
private static void FindParentSet(RvDir searchGame, RvDir parentDir, ref List<RvDir> lstParentGames) { if (searchGame.Game == null) return; string parentName = searchGame.Game.GetData(RvGame.GameData.RomOf); if (String.IsNullOrEmpty(parentName) || parentName == searchGame.Name) parentName = searchGame.Game.GetData(RvGame.GameData.CloneOf); if (String.IsNullOrEmpty(parentName) || parentName == searchGame.Name) return; int intIndex; int intResult = parentDir.ChildNameSearch(new RvDir(searchGame.FileType) { Name = parentName }, out intIndex); if (intResult == 0) { RvDir parentGame = (RvDir)parentDir.Child(intIndex); lstParentGames.Add(parentGame); FindParentSet(parentGame, parentDir, ref lstParentGames); } }
public static void Compare(RvDir dbDir, RvDir fileDir, bool report, bool enableCancel) { string fullDir = dbDir.FullName; FileType ft = dbDir.FileType; // now we scan down the dbDir and the scanDir, comparing them. // if we find a match we mark dbDir as found. // if we are missing a file in scanDir we mark that file in dbDir as missing. // if we find extra files in scanDir we add it to dbDir and mark it as unknown. // we also recurse into any sub directories. int dbIndex = 0; int fileIndex = 0; while (dbIndex < dbDir.ChildCount || fileIndex < fileDir.ChildCount) { RvBase dbChild = null; RvBase fileChild = null; int res = 0; if (dbIndex < dbDir.ChildCount && fileIndex < fileDir.ChildCount) { dbChild = dbDir.Child(dbIndex); fileChild = fileDir.Child(fileIndex); res = DBHelper.CompareName(dbChild, fileChild); } else if (fileIndex < fileDir.ChildCount) { //Get any remaining filedir's fileChild = fileDir.Child(fileIndex); res = 1; } else if (dbIndex < dbDir.ChildCount) { //Get any remaining dbDir's dbChild = dbDir.Child(dbIndex); res = -1; } if (report) { if (fileChild != null) { long timenow = DateTime.Now.Ticks; if ((timenow - _lastUpdateTime) > (TimeSpan.TicksPerSecond / 10)) { _lastUpdateTime = timenow; _bgw.ReportProgress(0, new bgwValue2(fileIndex)); _bgw.ReportProgress(0, new bgwText2(Path.Combine(fullDir, fileChild.Name))); } } } // if this file was found in the DB switch (res) { case 0: if (dbChild == null || fileChild == null) { ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code); break; } //Complete MultiName Compare List<RvBase> dbs = new List<RvBase>(); List<RvBase> files = new List<RvBase>(); int dbsCount = 1; int filesCount = 1; dbs.Add(dbChild); files.Add(fileChild); while (dbIndex + dbsCount < dbDir.ChildCount && DBHelper.CompareName(dbChild, dbDir.Child(dbIndex + dbsCount)) == 0) { dbs.Add(dbDir.Child(dbIndex + dbsCount)); dbsCount += 1; } while (fileIndex + filesCount < fileDir.ChildCount && DBHelper.CompareName(fileChild, fileDir.Child(fileIndex + filesCount)) == 0) { files.Add(fileDir.Child(fileIndex + filesCount)); filesCount += 1; } for (int indexfile = 0; indexfile < filesCount; indexfile++) { if (files[indexfile].SearchFound) continue; for (int indexdb = 0; indexdb < dbsCount; indexdb++) { if (dbs[indexdb].SearchFound) continue; bool matched = FullCompare(dbs[indexdb], files[indexfile], false, fullDir, EScanLevel); if (!matched) continue; MatchFound(dbs[indexdb], files[indexfile]); dbs[indexdb].SearchFound = true; files[indexfile].SearchFound = true; } if (files[indexfile].SearchFound) continue; for (int indexdb = 0; indexdb < dbsCount; indexdb++) { if (dbs[indexdb].SearchFound) continue; bool matched = FullCompare(dbs[indexdb], files[indexfile], true, fullDir, EScanLevel); if (!matched) continue; MatchFound(dbs[indexdb], files[indexfile]); dbs[indexdb].SearchFound = true; files[indexfile].SearchFound = true; } } for (int indexdb = 0; indexdb < dbsCount; indexdb++) { if (dbs[indexdb].SearchFound) { dbIndex++; continue; } DBFileNotFound(dbs[indexdb], dbDir, ref dbIndex); } for (int indexfile = 0; indexfile < filesCount; indexfile++) { if (files[indexfile].SearchFound) continue; NewFileFound(files[indexfile], dbDir, dbIndex); dbIndex++; } fileIndex += filesCount; break; case 1: NewFileFound(fileChild, dbDir, dbIndex); dbIndex++; fileIndex++; break; case -1: DBFileNotFound(dbChild, dbDir, ref dbIndex); break; } if (_fileErrorAbort) return; if (enableCancel && !DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending) return; } }
private static void DatSetCreateSubDirs(RvDir tDat) { for (int g = 0; g < tDat.ChildCount; g++) { if (tDat.Child(g).FileType == FileType.Zip) continue; RvDir datGame = (RvDir)tDat.Child(g); // first do a quick check to see if anything needs done. bool fixNeeded = false; for (int r = 0; r < datGame.ChildCount; r++) { fixNeeded = datGame.Child(r).Name.Contains("/"); if (fixNeeded) break; } // if nothing needs done skip to next game if (!fixNeeded) continue; RvDir fixedGame = new RvDir(FileType.Dir); while (datGame.ChildCount > 0) { RvBase nextChild = datGame.Child(0); datGame.ChildRemove(0); if (nextChild.GetType() == typeof(RvFile)) { RvFile tFile = (RvFile)nextChild; if (tFile.Name.Contains("/")) { RvDir tBase = fixedGame; Debug.WriteLine("tFile " + tFile.TreeFullName); while (tFile.Name.Contains("/")) { int dirIndex = tFile.Name.IndexOf("/", StringComparison.Ordinal); string dirName = tFile.Name.Substring(0, dirIndex); RvDir tDir = new RvDir(FileType.Dir) { Name = dirName, DatStatus = DatStatus.InDatCollect, Dat = datGame.Dat }; int index; if (tBase.ChildNameSearch(tDir, out index) != 0) tBase.ChildAdd(tDir, index); tBase = (RvDir)tBase.Child(index); tFile.Name = tFile.Name.Substring(tFile.Name.IndexOf("/", StringComparison.Ordinal) + 1); } tBase.ChildAdd(tFile); } else fixedGame.ChildAdd(nextChild); } else fixedGame.ChildAdd(nextChild); } for (int r = 0; r < fixedGame.ChildCount; r++) datGame.ChildAdd(fixedGame.Child(r), r); } }
private static void MarkAsMissing(RvDir dbDir) { for (int i = 0; i < dbDir.ChildCount; i++) { RvBase dbChild = dbDir.Child(i); if (dbChild.FileRemove() == EFile.Delete) { dbDir.ChildRemove(i); i--; } else { switch (dbChild.FileType) { case FileType.Zip: MarkAsMissing((RvDir)dbChild); break; case FileType.Dir: RvDir tDir = (RvDir)dbChild; if (tDir.Tree == null) MarkAsMissing(tDir); break; } } } }
private static void DatSetRemoveGameDir(RvDir newDir) { if (newDir.ChildCount != 1) return; RvDir child = newDir.Child(0) as RvDir; if (child.FileType != FileType.Dir) return; if (child.Game == null) return; newDir.ChildRemove(0); newDir.Game = child.Game; for (int i = 0; i < child.ChildCount; i++) newDir.ChildAdd(child.Child(i), i); }