mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Add Game diffing
This commit is contained in:
@@ -326,6 +326,14 @@ namespace SabreTools.Library.DatFiles
|
|||||||
DiffAgainst(inputFileNames, outDir, inplace);
|
DiffAgainst(inputFileNames, outDir, inplace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are in game diffing mode
|
||||||
|
else if (updateMode.HasFlag(UpdateMode.DiffGame))
|
||||||
|
{
|
||||||
|
// Populate the combined data
|
||||||
|
PopulateUserData(baseFileNames, filter);
|
||||||
|
DiffGame(inputFileNames, outDir, inplace, filter);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have one of the base replacement modes
|
// If we have one of the base replacement modes
|
||||||
else if (updateMode.HasFlag(UpdateMode.BaseReplace)
|
else if (updateMode.HasFlag(UpdateMode.BaseReplace)
|
||||||
|| updateMode.HasFlag(UpdateMode.ReverseBaseReplace))
|
|| updateMode.HasFlag(UpdateMode.ReverseBaseReplace))
|
||||||
@@ -406,6 +414,19 @@ namespace SabreTools.Library.DatFiles
|
|||||||
DiffNoCascade(paths, outDir, diff);
|
DiffNoCascade(paths, outDir, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Output games that contain different items (by name)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputs">Names of the input files</param>
|
||||||
|
/// <param name="outDir">Optional param for output directory</param>
|
||||||
|
/// <param name="inplace">True if the output files should overwrite their inputs, false otherwise</param>
|
||||||
|
/// <param name="filter">Filter object to be passed to the DatItem level</param>
|
||||||
|
public void DiffGame(List<string> inputs, string outDir, bool inplace, Filter filter)
|
||||||
|
{
|
||||||
|
List<ParentablePath> paths = inputs.Select(i => new ParentablePath(i)).ToList();
|
||||||
|
DiffGame(paths, outDir, inplace, filter);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output user defined merge
|
/// Output user defined merge
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1226,6 +1247,70 @@ namespace SabreTools.Library.DatFiles
|
|||||||
watch.Stop();
|
watch.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replace item values from the base set represented by the current DAT
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inputs">Names of the input files</param>
|
||||||
|
/// <param name="outDir">Optional param for output directory</param>
|
||||||
|
/// <param name="inplace">True if the output files should overwrite their inputs, false otherwise</param>
|
||||||
|
/// <param name="filter">Filter object to be passed to the DatItem level</param>
|
||||||
|
/// <remarks>TODO: Can this be wrapped into DiffAgainst?</remarks>
|
||||||
|
internal void DiffGame(List<ParentablePath> inputs, string outDir, bool inplace, Filter filter)
|
||||||
|
{
|
||||||
|
// Order the current DAT by game first
|
||||||
|
Items.BucketBy(BucketedBy.Game, DedupeType.None);
|
||||||
|
|
||||||
|
// We want to try to replace each item in each input DAT from the base
|
||||||
|
foreach (ParentablePath path in inputs)
|
||||||
|
{
|
||||||
|
Globals.Logger.User($"Comparing items in '{path.CurrentPath}' to the base DAT");
|
||||||
|
|
||||||
|
// First we parse in the DAT internally
|
||||||
|
DatFile intDat = Create(Header.CloneFiltering());
|
||||||
|
intDat.Parse(path, 1, keep: true);
|
||||||
|
filter.FilterDatFile(intDat, false /* useTags */);
|
||||||
|
intDat.Items.BucketBy(BucketedBy.Game, DedupeType.None);
|
||||||
|
|
||||||
|
// TODO: Do we need to include items in base NOT in compare?
|
||||||
|
List<string> games = intDat.Items.Keys.ToList();
|
||||||
|
foreach (string game in games)
|
||||||
|
{
|
||||||
|
// If the base DAT doesn't contain the key, keep it
|
||||||
|
if (!Items.ContainsKey(game))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the number of items is different, then keep it
|
||||||
|
if (Items[game].Count != intDat.Items[game].Count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Otherwise, compare by name and hash the remaining files
|
||||||
|
bool exactMatch = true;
|
||||||
|
foreach (DatItem item in intDat.Items[game])
|
||||||
|
{
|
||||||
|
// TODO: Make this granular to name as well
|
||||||
|
if (!Items[game].Contains(item))
|
||||||
|
{
|
||||||
|
exactMatch = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an exact match, remove the game
|
||||||
|
if (exactMatch)
|
||||||
|
intDat.Items.Remove(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the output path for the DAT
|
||||||
|
string interOutDir = path.GetOutputPath(outDir, inplace);
|
||||||
|
|
||||||
|
// Once we're done, try writing out
|
||||||
|
intDat.Write(interOutDir, overwrite: inplace);
|
||||||
|
|
||||||
|
// Due to possible memory requirements, we force a garbage collection
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output user defined merge
|
/// Output user defined merge
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -257,11 +257,12 @@ namespace SabreTools.Library.Data
|
|||||||
|
|
||||||
// Base diffs
|
// Base diffs
|
||||||
DiffAgainst = 1 << 5,
|
DiffAgainst = 1 << 5,
|
||||||
|
DiffGame = 1 << 6,
|
||||||
|
|
||||||
// Special update modes
|
// Special update modes
|
||||||
Merge = 1 << 6,
|
Merge = 1 << 7,
|
||||||
BaseReplace = 1 << 7,
|
BaseReplace = 1 << 8,
|
||||||
ReverseBaseReplace = 1 << 8,
|
ReverseBaseReplace = 1 << 9,
|
||||||
|
|
||||||
// Combinations
|
// Combinations
|
||||||
AllDiffs = DiffDupesOnly | DiffNoDupesOnly | DiffIndividualsOnly,
|
AllDiffs = DiffDupesOnly | DiffNoDupesOnly | DiffIndividualsOnly,
|
||||||
|
|||||||
@@ -1205,6 +1205,16 @@ Options:
|
|||||||
Add a DAT or folder of DATs to the base set to be used for all
|
Add a DAT or folder of DATs to the base set to be used for all
|
||||||
operations. Multiple instances of this flag are allowed.
|
operations. Multiple instances of this flag are allowed.
|
||||||
|
|
||||||
|
-dga, --diff-game Diff all inputs by game against a set of base DATs
|
||||||
|
This flag will enable a special type of diffing in which a set of base
|
||||||
|
DATs are used as a comparison point for each of the input DATs by game.
|
||||||
|
This allows users to get a slightly different output to cascaded
|
||||||
|
diffing, which may be more useful in some cases.
|
||||||
|
|
||||||
|
-bd=, --base-dat= Add a base DAT for processing
|
||||||
|
Add a DAT or folder of DATs to the base set to be used for all
|
||||||
|
operations. Multiple instances of this flag are allowed.
|
||||||
|
|
||||||
-br, --base-replace Replace from base DATs in order
|
-br, --base-replace Replace from base DATs in order
|
||||||
By default, no item names are changed except when there is a merge
|
By default, no item names are changed except when there is a merge
|
||||||
occurring. This flag enables users to define a DAT or set of base
|
occurring. This flag enables users to define a DAT or set of base
|
||||||
|
|||||||
@@ -336,6 +336,20 @@ namespace SabreTools.Features
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const string DiffGameValue = "diff-game";
|
||||||
|
internal static Feature DiffGameFlag
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new Feature(
|
||||||
|
DiffAgainstValue,
|
||||||
|
new List<string>() { "-dga", "--diff-game" },
|
||||||
|
"Diff all inputs by game against a set of base DATs",
|
||||||
|
FeatureType.Flag,
|
||||||
|
"This flag will enable a special type of diffing in which a set of base DATs are used as a comparison point for each of the input DATs by game. This allows users to get a slightly different output to cascaded diffing, which may be more useful in some cases.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal const string DiffIndividualsValue = "diff-individuals";
|
internal const string DiffIndividualsValue = "diff-individuals";
|
||||||
internal static Feature DiffIndividualsFlag
|
internal static Feature DiffIndividualsFlag
|
||||||
{
|
{
|
||||||
@@ -2489,6 +2503,9 @@ Some special strings that can be used:
|
|||||||
if (GetBoolean(features, DiffDuplicatesValue))
|
if (GetBoolean(features, DiffDuplicatesValue))
|
||||||
updateMode |= UpdateMode.DiffDupesOnly;
|
updateMode |= UpdateMode.DiffDupesOnly;
|
||||||
|
|
||||||
|
if (GetBoolean(features, DiffGameValue))
|
||||||
|
updateMode |= UpdateMode.DiffGame;
|
||||||
|
|
||||||
if (GetBoolean(features, DiffIndividualsValue))
|
if (GetBoolean(features, DiffIndividualsValue))
|
||||||
updateMode |= UpdateMode.DiffIndividualsOnly;
|
updateMode |= UpdateMode.DiffIndividualsOnly;
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ namespace SabreTools.Features
|
|||||||
this[DiffNoDuplicatesFlag].AddFeature(NoAutomaticDateFlag);
|
this[DiffNoDuplicatesFlag].AddFeature(NoAutomaticDateFlag);
|
||||||
AddFeature(DiffAgainstFlag);
|
AddFeature(DiffAgainstFlag);
|
||||||
this[DiffAgainstFlag].AddFeature(BaseDatListInput);
|
this[DiffAgainstFlag].AddFeature(BaseDatListInput);
|
||||||
|
AddFeature(DiffGameFlag);
|
||||||
|
this[DiffGameFlag].AddFeature(BaseDatListInput);
|
||||||
AddFeature(BaseReplaceFlag);
|
AddFeature(BaseReplaceFlag);
|
||||||
this[BaseReplaceFlag].AddFeature(BaseDatListInput);
|
this[BaseReplaceFlag].AddFeature(BaseDatListInput);
|
||||||
this[BaseReplaceFlag].AddFeature(UpdateFieldListInput);
|
this[BaseReplaceFlag].AddFeature(UpdateFieldListInput);
|
||||||
|
|||||||
Reference in New Issue
Block a user