785 lines
29 KiB
C#
785 lines
29 KiB
C#
/******************************************************
|
|
* ROMVault2 is written by Gordon J. *
|
|
* Contact gordon@romvault.com *
|
|
* Copyright 2013 *
|
|
******************************************************/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Threading;
|
|
using ROMVault2.IO;
|
|
using ROMVault2.DatReaders;
|
|
using ROMVault2.Properties;
|
|
using ROMVault2.RvDB;
|
|
using ROMVault2.Utils;
|
|
|
|
namespace ROMVault2
|
|
{
|
|
public static class DatUpdate
|
|
{
|
|
private static int _datCount;
|
|
private static int _datsProcessed;
|
|
private static BackgroundWorker _bgw;
|
|
|
|
public static void ShowDat(string message, string filename)
|
|
{
|
|
if (_bgw != null)
|
|
_bgw.ReportProgress(0, new bgwShowError(filename, message));
|
|
}
|
|
|
|
public static void SendAndShowDat(string message, string filename)
|
|
{
|
|
ReportError.SendErrorMessageDat(message, filename);
|
|
if (_bgw != null)
|
|
_bgw.ReportProgress(0, new bgwShowError(filename, message));
|
|
}
|
|
|
|
|
|
public static void UpdateDat(object sender, DoWorkEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
_bgw = sender as BackgroundWorker;
|
|
if (_bgw == null) return;
|
|
|
|
Program.SyncCont = e.Argument as SynchronizationContext;
|
|
if (Program.SyncCont == null)
|
|
{
|
|
_bgw = null;
|
|
return;
|
|
}
|
|
|
|
|
|
_bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
|
|
RepairStatus.ReportStatusReset(DB.DirTree);
|
|
|
|
_datCount = 0;
|
|
|
|
_bgw.ReportProgress(0, new bgwText("Finding Dats"));
|
|
RvDir datRoot = new RvDir(FileType.Dir) { Name = "RomVault", DatStatus = DatStatus.InDatCollect };
|
|
|
|
// build a datRoot tree of the DAT's in DatRoot, and count how many dats are found
|
|
if (!RecursiveDatTree(datRoot, out _datCount))
|
|
{
|
|
_bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
|
|
_bgw = null;
|
|
Program.SyncCont = null;
|
|
return;
|
|
}
|
|
|
|
_bgw.ReportProgress(0, new bgwText("Scanning Dats"));
|
|
_datsProcessed = 0;
|
|
|
|
// now compare the database DAT's with datRoot removing any old DAT's
|
|
RemoveOldDats(DB.DirTree.Child(0), datRoot);
|
|
|
|
// next clean up the File status removing any old DAT's
|
|
RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0));
|
|
|
|
_bgw.ReportProgress(0, new bgwSetRange(_datCount - 1));
|
|
|
|
// next add in new DAT and update the files
|
|
UpdateDatList((RvDir)DB.DirTree.Child(0),datRoot);
|
|
|
|
// finally remove any unneeded DIR's from the TreeView
|
|
RemoveOldTree(DB.DirTree.Child(0));
|
|
|
|
_bgw.ReportProgress(0, new bgwText("Updating Cache"));
|
|
DB.Write();
|
|
|
|
_bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
|
|
_bgw = null;
|
|
Program.SyncCont = null;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
ReportError.UnhandledExceptionHandler(exc);
|
|
|
|
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Updating Cache"));
|
|
DB.Write();
|
|
if (_bgw != null) _bgw.ReportProgress(0, new bgwText("Complete"));
|
|
|
|
_bgw = null;
|
|
Program.SyncCont = null;
|
|
}
|
|
}
|
|
|
|
private static bool RecursiveDatTree(RvDir tDir, out int datCount)
|
|
{
|
|
datCount = 0;
|
|
string strPath = tDir.DatFullName;
|
|
|
|
if (!Directory.Exists(strPath))
|
|
{
|
|
ReportError.Show(Resources.DatUpdate_UpdateDatList_Path + strPath + Resources.DatUpdate_UpdateDatList_Not_Found);
|
|
return false;
|
|
}
|
|
|
|
DirectoryInfo oDir = new DirectoryInfo(strPath);
|
|
|
|
FileInfo[] oFilesIn = oDir.GetFiles("*.dat", false);
|
|
datCount += oFilesIn.Length;
|
|
foreach (FileInfo file in oFilesIn)
|
|
{
|
|
RvDat tDat = new RvDat();
|
|
tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
|
|
tDat.TimeStamp = file.LastWriteTime;
|
|
tDir.DirDatAdd(tDat);
|
|
}
|
|
|
|
|
|
oFilesIn = oDir.GetFiles("*.xml", false);
|
|
datCount += oFilesIn.Length;
|
|
foreach (FileInfo file in oFilesIn)
|
|
{
|
|
RvDat tDat = new RvDat();
|
|
tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
|
|
tDat.TimeStamp = file.LastWriteTime;
|
|
tDir.DirDatAdd(tDat);
|
|
}
|
|
|
|
if (tDir.DirDatCount > 1)
|
|
for (int i = 0; i < tDir.DirDatCount; i++)
|
|
tDir.DirDat(i).AutoAddDirectory = true;
|
|
|
|
DirectoryInfo[] oSubDir = oDir.GetDirectories(false);
|
|
|
|
foreach (DirectoryInfo t in oSubDir)
|
|
{
|
|
RvDir cDir = new RvDir(FileType.Dir) { Name = t.Name, DatStatus = DatStatus.InDatCollect };
|
|
int index = tDir.ChildAdd(cDir);
|
|
|
|
int retDatCount;
|
|
|
|
RecursiveDatTree(cDir, out retDatCount);
|
|
datCount += retDatCount;
|
|
|
|
if (retDatCount == 0)
|
|
tDir.ChildRemove(index);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
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 EFile RemoveOldDatsCleanUpFiles(RvBase dbDir)
|
|
{
|
|
|
|
if (dbDir.Dat != null)
|
|
{
|
|
if (dbDir.Dat.Status == DatUpdateStatus.Correct)
|
|
return EFile.Keep;
|
|
|
|
if (dbDir.Dat.Status == DatUpdateStatus.Delete)
|
|
{
|
|
if (dbDir.DatRemove() == EFile.Delete)
|
|
return EFile.Delete; //delete
|
|
}
|
|
}
|
|
|
|
FileType ft = dbDir.FileType;
|
|
// if we are checking a dir or zip recurse into it.
|
|
if (ft != FileType.Zip && ft != FileType.Dir) return EFile.Keep;
|
|
RvDir tDir = dbDir as RvDir;
|
|
|
|
// remove all DATStatus's here they will get set back correctly when adding dats back in below.
|
|
dbDir.DatStatus = DatStatus.NotInDat;
|
|
|
|
for (int i = 0; i < tDir.ChildCount; i++)
|
|
{
|
|
if (RemoveOldDatsCleanUpFiles(tDir.Child(i)) == EFile.Keep) continue;
|
|
tDir.ChildRemove(i);
|
|
i--;
|
|
}
|
|
if (ft == FileType.Zip && dbDir.GotStatus == GotStatus.Corrupt) return EFile.Keep;
|
|
|
|
// if this directory is now empty it should be deleted
|
|
return tDir.ChildCount == 0 ? EFile.Delete : EFile.Keep;
|
|
}
|
|
|
|
|
|
|
|
private static void UpdateDatList(RvDir dbDir, RvDir tmpDir)
|
|
{
|
|
AddNewDats(dbDir, tmpDir);
|
|
UpdateDirs(dbDir, tmpDir);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add the new DAT's into the DAT list
|
|
/// And merge in the new DAT data into the database
|
|
/// </summary>
|
|
/// <param name="dbDir">The Current database dir</param>
|
|
/// <param name="tmpDir">A temp directory containing the DAT found in this directory in DatRoot</param>
|
|
private static void AddNewDats(RvDir dbDir, RvDir tmpDir)
|
|
{
|
|
bool autoAddDirectory = (tmpDir.DirDatCount) > 1;
|
|
|
|
int dbIndex = 0;
|
|
int scanIndex = 0;
|
|
|
|
Debug.WriteLine("");
|
|
Debug.WriteLine("Scanning for Adding new DATS");
|
|
while (dbIndex < dbDir.DirDatCount || scanIndex < tmpDir.DirDatCount)
|
|
{
|
|
RvDat dbDat = null;
|
|
RvDat fileDat = null;
|
|
int res = 0;
|
|
|
|
if (dbIndex < dbDir.DirDatCount && scanIndex < tmpDir.DirDatCount)
|
|
{
|
|
dbDat = dbDir.DirDat(dbIndex);
|
|
fileDat = tmpDir.DirDat(scanIndex);
|
|
res = DBHelper.DatCompare(dbDat, fileDat);
|
|
Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
|
|
}
|
|
else if (scanIndex < tmpDir.DirDatCount)
|
|
{
|
|
fileDat = tmpDir.DirDat(scanIndex);
|
|
res = 1;
|
|
Debug.WriteLine("Checking : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
|
|
}
|
|
else if (dbIndex < dbDir.DirDatCount)
|
|
{
|
|
dbDat = dbDir.DirDat(dbIndex);
|
|
res = -1;
|
|
Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and : " + res);
|
|
}
|
|
|
|
switch (res)
|
|
{
|
|
case 0:
|
|
_datsProcessed++;
|
|
_bgw.ReportProgress(_datsProcessed);
|
|
_bgw.ReportProgress(0, new bgwText("Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));
|
|
|
|
|
|
Debug.WriteLine("Correct");
|
|
// Should already be set as correct above
|
|
dbDat.Status = DatUpdateStatus.Correct;
|
|
dbIndex++;
|
|
scanIndex++;
|
|
break;
|
|
|
|
case 1:
|
|
_datsProcessed++;
|
|
_bgw.ReportProgress(_datsProcessed);
|
|
_bgw.ReportProgress(0, new bgwText("Scanning New Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));
|
|
|
|
|
|
Debug.WriteLine("Adding new DAT");
|
|
if (UpdateDatFile(fileDat, autoAddDirectory, dbDir))
|
|
dbIndex++;
|
|
scanIndex++;
|
|
break;
|
|
|
|
case -1:
|
|
// This should not happen as deleted dat have been removed above
|
|
//dbIndex++;
|
|
ReportError.SendAndShow(Resources.DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted);
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static bool UpdateDatFile(RvDat file, bool autoAddDirectory, RvDir thisDirectory)
|
|
{
|
|
// Read the new Dat File into newDatFile
|
|
RvDir newDatFile = DatReader.ReadInDatFile(file, _bgw);
|
|
|
|
// If we got a valid Dat File back
|
|
if (newDatFile == null || newDatFile.Dat == null)
|
|
{
|
|
ReportError.Show("Error reading Dat " + file.GetData(RvDat.DatData.DatFullName));
|
|
return false;
|
|
}
|
|
|
|
newDatFile.Dat.AutoAddDirectory = autoAddDirectory;
|
|
|
|
if ((autoAddDirectory || !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir))) && newDatFile.Dat.GetData(RvDat.DatData.DirSetup)!= "noautodir")
|
|
{ // if we are auto adding extra directorys then create a new directory.
|
|
|
|
newDatFile.Name = !String.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir)) ?
|
|
newDatFile.Dat.GetData(RvDat.DatData.RootDir) : newDatFile.Dat.GetData(RvDat.DatData.DatName);
|
|
|
|
newDatFile.DatStatus = DatStatus.InDatCollect;
|
|
newDatFile.Tree = new RvTreeRow();
|
|
|
|
RvDir newDirectory = new RvDir(FileType.Dir) { Dat = newDatFile.Dat };
|
|
|
|
// add the DAT into this directory
|
|
newDirectory.ChildAdd(newDatFile);
|
|
newDatFile = newDirectory;
|
|
}
|
|
|
|
if (thisDirectory.Tree == null)
|
|
thisDirectory.Tree = new RvTreeRow();
|
|
|
|
RvDat conflictDat;
|
|
if (MergeInDat(thisDirectory, newDatFile, out conflictDat, true))
|
|
{
|
|
ReportError.Show("Dat Merge conflict occured Cache contains " + conflictDat.GetData(RvDat.DatData.DatFullName) + " new dat " + newDatFile.Dat.GetData(RvDat.DatData.DatFullName) + " is trying to use the same dirctory and so will be ignored.");
|
|
return false;
|
|
}
|
|
|
|
//SetInDat(thisDirectory);
|
|
|
|
// Add the new Dat
|
|
thisDirectory.DirDatAdd(newDatFile.Dat);
|
|
|
|
// Merge the files/directories in the Dat
|
|
MergeInDat(thisDirectory, newDatFile, out conflictDat, false);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
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 static void SetMissingStatus(RvBase dbChild)
|
|
{
|
|
if (dbChild.FileRemove() == EFile.Delete)
|
|
{
|
|
ReportError.SendAndShow("Error is Set Mssing Status in DatUpdate");
|
|
return;
|
|
}
|
|
|
|
|
|
FileType ft = dbChild.FileType;
|
|
if (ft == FileType.Zip || ft == FileType.Dir)
|
|
{
|
|
RvDir dbDir = (RvDir)dbChild;
|
|
for (int i = 0; i < dbDir.ChildCount; i++)
|
|
SetMissingStatus(dbDir.Child(i));
|
|
}
|
|
|
|
}
|
|
|
|
private static bool FullCompare(RvBase var1, RvBase var2)
|
|
{
|
|
int retv = DBHelper.CompareName(var1, var2);
|
|
if (retv != 0) return false;
|
|
|
|
FileType v1 = var1.FileType;
|
|
FileType v2 = var2.FileType;
|
|
retv = Math.Sign(v1.CompareTo(v2));
|
|
if (retv != 0) return false;
|
|
|
|
// filetypes are now know to be the same
|
|
|
|
// Dir's and Zip's are not deep scanned so matching here is done
|
|
if ((v1 == FileType.Dir) || (v1 == FileType.Zip))
|
|
return true;
|
|
|
|
RvFile f1 = (RvFile)var1;
|
|
RvFile f2 = (RvFile)var2;
|
|
|
|
if (f1.Size != null && f2.Size != null)
|
|
{
|
|
retv = ULong.iCompare(f1.Size, f2.Size);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
if (f1.CRC != null && f2.CRC != null)
|
|
{
|
|
retv = ArrByte.iCompare(f1.CRC, f2.CRC);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
if (f1.SHA1 != null && f2.SHA1 != null)
|
|
{
|
|
retv = ArrByte.iCompare(f1.SHA1, f2.SHA1);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
if (f1.MD5 != null && f2.MD5 != null)
|
|
{
|
|
retv = ArrByte.iCompare(f1.MD5, f2.MD5);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
if (f1.SHA1CHD != null && f2.SHA1CHD != null)
|
|
{
|
|
retv = ArrByte.iCompare(f1.SHA1CHD, f2.SHA1CHD);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
if (f1.MD5CHD != null && f2.MD5CHD != null)
|
|
{
|
|
retv = ArrByte.iCompare(f1.MD5CHD, f2.MD5CHD);
|
|
if (retv != 0) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
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 RemoveOldTree(RvBase dbBase)
|
|
{
|
|
RvDir dbDir = dbBase as RvDir;
|
|
if (dbDir == null) return;
|
|
|
|
if (dbDir.DatStatus == DatStatus.NotInDat && dbDir.Tree != null)
|
|
dbDir.Tree = null;
|
|
|
|
for (int i = 0; i < dbDir.ChildCount; i++)
|
|
RemoveOldTree(dbDir.Child(i));
|
|
}
|
|
}
|
|
}
|