2016-11-04 11:57:32 -07:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Web;
|
|
|
|
|
|
|
|
|
|
|
|
using SabreTools.Helper.Data;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SabreTools.Helper.Dats
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class DatFile
|
|
|
|
|
|
{
|
|
|
|
|
|
#region Instance Methods
|
|
|
|
|
|
|
|
|
|
|
|
#region Bucketing [MODULAR DONE]
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take the arbitrarily sorted Files Dictionary and convert to one sorted by CRC
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
public void BucketByCRC(bool mergeroms, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we already have the right sorting, trust it
|
|
|
|
|
|
if (_sortedBy == SortedBy.CRC)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the sorted type
|
|
|
|
|
|
_sortedBy = SortedBy.CRC;
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms by CRC");
|
|
|
|
|
|
|
|
|
|
|
|
// Process each all of the roms
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<string> keys = Keys.ToList();
|
2016-11-04 11:57:32 -07:00
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<DatItem> roms = this[key];
|
2016-11-04 11:57:32 -07:00
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
roms = DatItem.Merge(roms, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in roms)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (rom.Type == ItemType.Rom ? ((Rom)rom).CRC : Constants.CRCZero);
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now go through and sort all of the lists
|
|
|
|
|
|
keys = sortable.Keys.ToList();
|
|
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> sortedlist = sortable[key];
|
|
|
|
|
|
DatItem.Sort(ref sortedlist, false);
|
|
|
|
|
|
sortable[key] = sortedlist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Output the count if told to
|
|
|
|
|
|
if (output)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("A total of " + count + " file hashes will be written out to file");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now assign the dictionary back
|
2016-11-08 15:50:27 -08:00
|
|
|
|
_files = sortable;
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take the arbitrarily sorted Files Dictionary and convert to one sorted by Game
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
/// <param name="lower">True if the game should be lowercased (default), false otherwise</param>
|
|
|
|
|
|
public void BucketByGame(bool mergeroms, bool norename, Logger logger, bool output = true, bool lower = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we already have the right sorting, trust it
|
|
|
|
|
|
if (_sortedBy == SortedBy.Game)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the sorted type
|
|
|
|
|
|
_sortedBy = SortedBy.Game;
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms by game");
|
|
|
|
|
|
|
|
|
|
|
|
// Process each all of the roms
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<string> keys = Keys.ToList();
|
2016-11-04 11:57:32 -07:00
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<DatItem> roms = this[key];
|
2016-11-04 11:57:32 -07:00
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
roms = DatItem.Merge(roms, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in roms)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (norename ? ""
|
|
|
|
|
|
: rom.SystemID.ToString().PadLeft(10, '0')
|
|
|
|
|
|
+ "-"
|
|
|
|
|
|
+ rom.SourceID.ToString().PadLeft(10, '0') + "-")
|
|
|
|
|
|
+ (String.IsNullOrEmpty(rom.Machine.Name)
|
|
|
|
|
|
? "Default"
|
|
|
|
|
|
: rom.Machine.Name);
|
|
|
|
|
|
if (lower)
|
|
|
|
|
|
{
|
|
|
|
|
|
newkey = newkey.ToLowerInvariant();
|
|
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
2016-11-04 11:57:32 -07:00
|
|
|
|
newkey = HttpUtility.HtmlEncode(newkey);
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now go through and sort all of the lists
|
|
|
|
|
|
keys = sortable.Keys.ToList();
|
|
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> sortedlist = sortable[key];
|
|
|
|
|
|
DatItem.Sort(ref sortedlist, norename);
|
|
|
|
|
|
sortable[key] = sortedlist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Output the count if told to
|
|
|
|
|
|
if (output)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("A total of " + count + " file hashes will be written out to file");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now assign the dictionary back
|
2016-11-08 15:50:27 -08:00
|
|
|
|
_files = sortable;
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take the arbitrarily sorted Files Dictionary and convert to one sorted by MD5
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
public void BucketByMD5(bool mergeroms, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we already have the right sorting, trust it
|
|
|
|
|
|
if (_sortedBy == SortedBy.MD5)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the sorted type
|
|
|
|
|
|
_sortedBy = SortedBy.MD5;
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms by MD5");
|
|
|
|
|
|
|
|
|
|
|
|
// Process each all of the roms
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<string> keys = Keys.ToList();
|
2016-11-04 11:57:32 -07:00
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<DatItem> roms = this[key];
|
2016-11-04 11:57:32 -07:00
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
roms = DatItem.Merge(roms, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in roms)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (rom.Type == ItemType.Rom
|
|
|
|
|
|
? ((Rom)rom).MD5
|
|
|
|
|
|
: (rom.Type == ItemType.Disk
|
|
|
|
|
|
? ((Disk)rom).MD5
|
|
|
|
|
|
: Constants.MD5Zero));
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now go through and sort all of the lists
|
|
|
|
|
|
keys = sortable.Keys.ToList();
|
|
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> sortedlist = sortable[key];
|
|
|
|
|
|
DatItem.Sort(ref sortedlist, false);
|
|
|
|
|
|
sortable[key] = sortedlist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Output the count if told to
|
|
|
|
|
|
if (output)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("A total of " + count + " file hashes will be written out to file");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now assign the dictionary back
|
2016-11-08 15:50:27 -08:00
|
|
|
|
_files = sortable;
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take the arbitrarily sorted Files Dictionary and convert to one sorted by SHA1
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
public void BucketBySHA1(bool mergeroms, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we already have the right sorting, trust it
|
|
|
|
|
|
if (_sortedBy == SortedBy.SHA1)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the sorted type
|
|
|
|
|
|
_sortedBy = SortedBy.SHA1;
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms by SHA-1");
|
|
|
|
|
|
|
|
|
|
|
|
// Process each all of the roms
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<string> keys = Keys.ToList();
|
2016-11-04 11:57:32 -07:00
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<DatItem> roms = this[key];
|
2016-11-04 11:57:32 -07:00
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
roms = DatItem.Merge(roms, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in roms)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (rom.Type == ItemType.Rom
|
|
|
|
|
|
? ((Rom)rom).SHA1
|
|
|
|
|
|
: (rom.Type == ItemType.Disk
|
|
|
|
|
|
? ((Disk)rom).SHA1
|
|
|
|
|
|
: Constants.MD5Zero));
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now go through and sort all of the lists
|
|
|
|
|
|
keys = sortable.Keys.ToList();
|
|
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> sortedlist = sortable[key];
|
|
|
|
|
|
DatItem.Sort(ref sortedlist, false);
|
|
|
|
|
|
sortable[key] = sortedlist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Output the count if told to
|
|
|
|
|
|
if (output)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("A total of " + count + " file hashes will be written out to file");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now assign the dictionary back
|
2016-11-08 15:50:27 -08:00
|
|
|
|
_files = sortable;
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take the arbitrarily sorted Files Dictionary and convert to one sorted by Size
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
public void BucketBySize(bool mergeroms, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we already have the right sorting, trust it
|
|
|
|
|
|
if (_sortedBy == SortedBy.Size)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the sorted type
|
|
|
|
|
|
_sortedBy = SortedBy.Size;
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms by size");
|
|
|
|
|
|
|
|
|
|
|
|
// Process each all of the roms
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<string> keys = Keys.ToList();
|
2016-11-04 11:57:32 -07:00
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
2016-11-08 15:50:27 -08:00
|
|
|
|
List<DatItem> roms = this[key];
|
2016-11-04 11:57:32 -07:00
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
roms = DatItem.Merge(roms, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in roms)
|
|
|
|
|
|
{
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (rom.Type == ItemType.Rom ? ((Rom)rom).Size.ToString() : "-1");
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now go through and sort all of the lists
|
|
|
|
|
|
keys = sortable.Keys.ToList();
|
|
|
|
|
|
foreach (string key in keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> sortedlist = sortable[key];
|
|
|
|
|
|
DatItem.Sort(ref sortedlist, false);
|
|
|
|
|
|
sortable[key] = sortedlist;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Output the count if told to
|
|
|
|
|
|
if (output)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("A total of " + count + " file hashes will be written out to file");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now assign the dictionary back
|
2016-11-08 15:50:27 -08:00
|
|
|
|
_files = sortable;
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
/// <summary>
|
2017-01-09 15:43:53 -08:00
|
|
|
|
/// Use cloneof tags to create non-merged sets and remove the tags plus using the device_ref tags to get full sets
|
2017-01-09 11:04:06 -08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
2017-01-09 15:43:53 -08:00
|
|
|
|
public void CreateFullyNonMergedSets(bool mergeroms, Logger logger, bool output = true)
|
2017-01-09 11:04:06 -08:00
|
|
|
|
{
|
|
|
|
|
|
// For sake of ease, the first thing we want to do is sort by game
|
2017-01-09 14:37:41 -08:00
|
|
|
|
BucketByGame(mergeroms, true, logger, output);
|
|
|
|
|
|
_sortedBy = SortedBy.Default;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
|
|
|
|
|
|
// Now we want to loop through all of the games and set the correct information
|
|
|
|
|
|
List<string> games = Keys.ToList();
|
|
|
|
|
|
foreach (string game in games)
|
|
|
|
|
|
{
|
2017-01-09 15:58:29 -08:00
|
|
|
|
// Determine if the game has any devices or not
|
|
|
|
|
|
if (this[game][0].Machine.Devices.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<string> devices = this[game][0].Machine.Devices;
|
|
|
|
|
|
foreach (string device in devices)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If the device doesn't exist then we continue
|
|
|
|
|
|
if (this[device].Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, copy the items from the device to the current game
|
|
|
|
|
|
Machine musheen = this[game][0].Machine;
|
|
|
|
|
|
List<DatItem> devItems = this[device];
|
|
|
|
|
|
foreach (DatItem item in devItems)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Figure out the type of the item and add it accordingly
|
|
|
|
|
|
switch (item.Type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ItemType.Archive:
|
|
|
|
|
|
Archive archive = ((Archive)item).Clone() as Archive;
|
|
|
|
|
|
archive.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(archive))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(archive);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.BiosSet:
|
|
|
|
|
|
BiosSet biosSet = ((BiosSet)item).Clone() as BiosSet;
|
|
|
|
|
|
biosSet.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(biosSet))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(biosSet);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Disk:
|
|
|
|
|
|
Disk disk = ((Disk)item).Clone() as Disk;
|
|
|
|
|
|
disk.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(disk))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(disk);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Release:
|
|
|
|
|
|
Release release = ((Release)item).Clone() as Release;
|
|
|
|
|
|
release.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(release))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(release);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Rom:
|
|
|
|
|
|
Rom rom = ((Rom)item).Clone() as Rom;
|
|
|
|
|
|
rom.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(rom))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(rom);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Sample:
|
|
|
|
|
|
Sample sample = ((Sample)item).Clone() as Sample;
|
|
|
|
|
|
sample.Machine = musheen;
|
|
|
|
|
|
if (!this[game].Contains(sample))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(sample);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Then, remove the romof and cloneof tags so it's not picked up by the manager
|
|
|
|
|
|
devItems = this[game];
|
|
|
|
|
|
foreach (DatItem item in devItems)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Machine.CloneOf = null;
|
|
|
|
|
|
item.Machine.RomOf = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
// Determine if the game has a parent or not
|
|
|
|
|
|
string parent = null;
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (!String.IsNullOrEmpty(this[game][0].Machine.CloneOf))
|
2017-01-09 11:04:06 -08:00
|
|
|
|
{
|
|
|
|
|
|
parent = this[game][0].Machine.CloneOf;
|
|
|
|
|
|
}
|
2017-01-09 15:43:53 -08:00
|
|
|
|
else if (!String.IsNullOrEmpty(this[game][0].Machine.RomOf))
|
|
|
|
|
|
{
|
|
|
|
|
|
parent = this[game][0].Machine.RomOf;
|
|
|
|
|
|
}
|
2017-01-09 11:04:06 -08:00
|
|
|
|
|
|
|
|
|
|
// If there is no parent, then we continue
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (String.IsNullOrEmpty(parent))
|
2017-01-09 11:04:06 -08:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 15:43:53 -08:00
|
|
|
|
// If the parent doesn't exist, then we continue and remove
|
|
|
|
|
|
if (this[parent].Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<DatItem> curitems = this[game];
|
|
|
|
|
|
foreach (DatItem item in curitems)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Machine.CloneOf = null;
|
|
|
|
|
|
item.Machine.RomOf = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, copy the items from the parent to the current game
|
|
|
|
|
|
Machine currentMachine = this[game][0].Machine;
|
|
|
|
|
|
List<DatItem> items = this[parent];
|
2017-01-09 11:04:06 -08:00
|
|
|
|
foreach (DatItem item in items)
|
|
|
|
|
|
{
|
2017-01-09 15:43:53 -08:00
|
|
|
|
// Figure out the type of the item and add it accordingly
|
|
|
|
|
|
switch (item.Type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ItemType.Archive:
|
|
|
|
|
|
Archive archive = ((Archive)item).Clone() as Archive;
|
|
|
|
|
|
archive.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(archive))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(archive);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.BiosSet:
|
|
|
|
|
|
BiosSet biosSet = ((BiosSet)item).Clone() as BiosSet;
|
|
|
|
|
|
biosSet.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(biosSet))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(biosSet);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Disk:
|
|
|
|
|
|
Disk disk = ((Disk)item).Clone() as Disk;
|
|
|
|
|
|
disk.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(disk))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(disk);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Release:
|
|
|
|
|
|
Release release = ((Release)item).Clone() as Release;
|
|
|
|
|
|
release.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(release))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(release);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Rom:
|
|
|
|
|
|
Rom rom = ((Rom)item).Clone() as Rom;
|
|
|
|
|
|
rom.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(rom))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(rom);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Sample:
|
|
|
|
|
|
Sample sample = ((Sample)item).Clone() as Sample;
|
|
|
|
|
|
sample.Machine = currentMachine;
|
|
|
|
|
|
if (!this[game].Contains(sample))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(sample);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-01-09 11:04:06 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 15:58:29 -08:00
|
|
|
|
// Then, remove the romof and cloneof tags so it's not picked up by the manager
|
2017-01-09 15:43:53 -08:00
|
|
|
|
items = this[game];
|
|
|
|
|
|
foreach (DatItem item in items)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Machine.CloneOf = null;
|
|
|
|
|
|
item.Machine.RomOf = null;
|
|
|
|
|
|
}
|
2017-01-09 11:04:06 -08:00
|
|
|
|
}
|
2017-01-09 15:58:29 -08:00
|
|
|
|
|
|
|
|
|
|
// Finally, we want to remove all games that have the BIOS or Device tags
|
|
|
|
|
|
games = Keys.ToList();
|
|
|
|
|
|
foreach (string game in games)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (this[game][0].Machine.MachineType == MachineType.Bios || this[game][0].Machine.MachineType == MachineType.Device)
|
|
|
|
|
|
{
|
|
|
|
|
|
Remove(game);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-01-09 11:04:06 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 09:56:47 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Use cloneof tags to create merged sets and remove the tags
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
public void CreateMergedSets(bool mergeroms, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// For sake of ease, the first thing we want to do is sort by game
|
2017-01-09 14:37:41 -08:00
|
|
|
|
BucketByGame(mergeroms, true, logger, output);
|
|
|
|
|
|
_sortedBy = SortedBy.Default;
|
2017-01-09 09:56:47 -08:00
|
|
|
|
|
|
|
|
|
|
// Now we want to loop through all of the games and set the correct information
|
|
|
|
|
|
List<string> games = Keys.ToList();
|
|
|
|
|
|
foreach (string game in games)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Determine if the game has a parent or not
|
|
|
|
|
|
string parent = null;
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (!String.IsNullOrEmpty(this[game][0].Machine.CloneOf))
|
2017-01-09 09:56:47 -08:00
|
|
|
|
{
|
|
|
|
|
|
parent = this[game][0].Machine.CloneOf;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If there is no parent, then we continue
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (String.IsNullOrEmpty(parent))
|
2017-01-09 09:56:47 -08:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, move the items from the current game to a subfolder of the parent game
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Machine parentMachine = this[parent].Count == 0 ? new Machine { Name = parent, Description = parent } : this[parent][0].Machine;
|
2017-01-09 09:56:47 -08:00
|
|
|
|
List<DatItem> items = this[game];
|
|
|
|
|
|
foreach (DatItem item in items)
|
|
|
|
|
|
{
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[parent].Contains(item))
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Name = item.Machine.Name + "\\" + item.Name;
|
|
|
|
|
|
item.Machine = parentMachine;
|
|
|
|
|
|
this[parent].Add(item);
|
|
|
|
|
|
}
|
2017-01-09 09:56:47 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, remove the old game so it's not picked up by the writer
|
|
|
|
|
|
Remove(game);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2017-01-09 14:37:41 -08:00
|
|
|
|
/// Use cloneof tags to create non-merged sets and remove the tags
|
2017-01-09 09:56:47 -08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
2017-01-09 14:37:41 -08:00
|
|
|
|
public void CreateNonMergedSets(bool mergeroms, Logger logger, bool output = true)
|
2017-01-09 09:56:47 -08:00
|
|
|
|
{
|
|
|
|
|
|
// For sake of ease, the first thing we want to do is sort by game
|
2017-01-09 14:37:41 -08:00
|
|
|
|
BucketByGame(mergeroms, true, logger, output);
|
|
|
|
|
|
_sortedBy = SortedBy.Default;
|
2017-01-09 09:56:47 -08:00
|
|
|
|
|
|
|
|
|
|
// Now we want to loop through all of the games and set the correct information
|
|
|
|
|
|
List<string> games = Keys.ToList();
|
|
|
|
|
|
foreach (string game in games)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Determine if the game has a parent or not
|
|
|
|
|
|
string parent = null;
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (!String.IsNullOrEmpty(this[game][0].Machine.CloneOf))
|
2017-01-09 09:56:47 -08:00
|
|
|
|
{
|
|
|
|
|
|
parent = this[game][0].Machine.CloneOf;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If there is no parent, then we continue
|
2017-01-09 14:37:41 -08:00
|
|
|
|
if (String.IsNullOrEmpty(parent))
|
2017-01-09 09:56:47 -08:00
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 12:34:35 -08:00
|
|
|
|
// If the parent doesn't exist, then we continue and remove
|
2017-01-09 09:56:47 -08:00
|
|
|
|
if (this[parent].Count == 0)
|
|
|
|
|
|
{
|
2017-01-09 12:34:35 -08:00
|
|
|
|
List<DatItem> curitems = this[game];
|
|
|
|
|
|
foreach (DatItem item in curitems)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Machine.CloneOf = null;
|
|
|
|
|
|
item.Machine.RomOf = null;
|
|
|
|
|
|
}
|
2017-01-09 14:37:41 -08:00
|
|
|
|
|
2017-01-09 09:56:47 -08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, copy the items from the parent to the current game
|
2017-01-09 11:04:06 -08:00
|
|
|
|
Machine currentMachine = this[game][0].Machine;
|
2017-01-09 09:56:47 -08:00
|
|
|
|
List<DatItem> items = this[parent];
|
|
|
|
|
|
foreach (DatItem item in items)
|
|
|
|
|
|
{
|
2017-01-09 11:04:06 -08:00
|
|
|
|
// Figure out the type of the item and add it accordingly
|
|
|
|
|
|
switch (item.Type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ItemType.Archive:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Archive archive = ((Archive)item).Clone() as Archive;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
archive.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(archive))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(archive);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.BiosSet:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
BiosSet biosSet = ((BiosSet)item).Clone() as BiosSet;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
biosSet.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(biosSet))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(biosSet);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Disk:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Disk disk = ((Disk)item).Clone() as Disk;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
disk.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(disk))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(disk);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Release:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Release release = ((Release)item).Clone() as Release;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
release.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(release))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(release);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Rom:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Rom rom = ((Rom)item).Clone() as Rom;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
rom.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(rom))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(rom);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
case ItemType.Sample:
|
2017-01-09 14:37:41 -08:00
|
|
|
|
Sample sample = ((Sample)item).Clone() as Sample;
|
2017-01-09 11:04:06 -08:00
|
|
|
|
sample.Machine = currentMachine;
|
2017-01-09 15:43:53 -08:00
|
|
|
|
if (!this[game].Contains(sample))
|
|
|
|
|
|
{
|
|
|
|
|
|
this[game].Add(sample);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-09 11:04:06 -08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Finally, remove the romof and cloneof tags so it's not picked up by the manager
|
|
|
|
|
|
items = this[game];
|
|
|
|
|
|
foreach (DatItem item in items)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.Machine.CloneOf = null;
|
|
|
|
|
|
item.Machine.RomOf = null;
|
2017-01-09 09:56:47 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-04 11:57:32 -07:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#endregion // Instance Methods
|
|
|
|
|
|
|
|
|
|
|
|
#region Static Methods
|
|
|
|
|
|
|
|
|
|
|
|
#region Bucketing [MODULAR DONE]
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Take an arbitrarily ordered List and return a Dictionary sorted by Game
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="list">Input unsorted list</param>
|
|
|
|
|
|
/// <param name="mergeroms">True if roms should be deduped, false otherwise</param>
|
|
|
|
|
|
/// <param name="norename">True if games should only be compared on game and file name, false if system and source are counted</param>
|
|
|
|
|
|
/// <param name="logger">Logger object for file and console output</param>
|
|
|
|
|
|
/// <param name="output">True if the number of hashes counted is to be output (default), false otherwise</param>
|
|
|
|
|
|
/// <returns>SortedDictionary bucketed by game name</returns>
|
|
|
|
|
|
public static SortedDictionary<string, List<DatItem>> BucketListByGame(List<DatItem> list, bool mergeroms, bool norename, Logger logger, bool output = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.User("Organizing " + (mergeroms ? "and merging " : "") + "roms for output");
|
|
|
|
|
|
|
|
|
|
|
|
SortedDictionary<string, List<DatItem>> sortable = new SortedDictionary<string, List<DatItem>>();
|
|
|
|
|
|
long count = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// If we have a null dict or an empty one, output a new dictionary
|
|
|
|
|
|
if (list == null || list.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return sortable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If we're merging the roms, do so
|
|
|
|
|
|
if (mergeroms)
|
|
|
|
|
|
{
|
|
|
|
|
|
list = DatItem.Merge(list, logger);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add each of the roms to their respective games
|
|
|
|
|
|
foreach (DatItem rom in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (rom == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
string newkey = (norename ? ""
|
|
|
|
|
|
: rom.SystemID.ToString().PadLeft(10, '0')
|
|
|
|
|
|
+ "-"
|
|
|
|
|
|
+ rom.SourceID.ToString().PadLeft(10, '0') + "-")
|
|
|
|
|
|
+ (rom.Machine == null || String.IsNullOrEmpty(rom.Machine.Name)
|
|
|
|
|
|
? "Default"
|
|
|
|
|
|
: rom.Machine.Name.ToLowerInvariant());
|
|
|
|
|
|
newkey = HttpUtility.HtmlEncode(newkey);
|
2016-11-08 15:29:52 -08:00
|
|
|
|
|
|
|
|
|
|
if (!sortable.ContainsKey(newkey))
|
2016-11-04 11:57:32 -07:00
|
|
|
|
{
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable.Add(newkey, new List<DatItem>());
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
2016-11-08 15:29:52 -08:00
|
|
|
|
sortable[newkey].Add(rom);
|
2016-11-04 11:57:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return sortable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#endregion // Static Methods
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|