2016-10-19 10:47:23 -07:00
|
|
|
|
using Mono.Data.Sqlite;
|
|
|
|
|
|
using System;
|
2016-08-30 15:02:48 -07:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using SabreTools.Helper;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SabreTools
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Entry class for the RombaSharp application
|
|
|
|
|
|
/// </summary>
|
2016-09-02 13:59:25 -07:00
|
|
|
|
public partial class RombaSharp
|
2016-08-30 15:02:48 -07:00
|
|
|
|
{
|
|
|
|
|
|
// General settings
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static int _workers; //Number of parallel threads
|
|
|
|
|
|
private static string _logdir; //Log folder location
|
2016-10-19 10:47:23 -07:00
|
|
|
|
private static string _tmpdir; //Temp folder location
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static string _webdir; // Web frontend location
|
|
|
|
|
|
private static string _baddir; // Fail-to-unpack file folder location
|
|
|
|
|
|
private static int _verbosity; // Verbosity of the output
|
|
|
|
|
|
private static int _cores; // Forced CPU cores
|
2016-08-30 15:02:48 -07:00
|
|
|
|
|
|
|
|
|
|
// DatRoot settings
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static string _dats; // DatRoot folder location
|
|
|
|
|
|
private static string _db; // Database name
|
2016-08-30 15:02:48 -07:00
|
|
|
|
|
|
|
|
|
|
// Depot settings
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static Dictionary<string, Tuple<long, bool>> _depots; // Folder location, Max size
|
2016-08-30 15:02:48 -07:00
|
|
|
|
|
|
|
|
|
|
// Server settings
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static int _port; // Web server port
|
2016-08-30 15:02:48 -07:00
|
|
|
|
|
|
|
|
|
|
// Other private variables
|
2016-09-02 13:59:25 -07:00
|
|
|
|
private static string _config = "config.xml";
|
|
|
|
|
|
private static string _dbSchema = "rombasharp";
|
|
|
|
|
|
private static string _connectionString;
|
|
|
|
|
|
private static Logger _logger;
|
2016-08-30 15:02:48 -07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2016-09-02 13:59:25 -07:00
|
|
|
|
/// Entry class for the RombaSharp application
|
2016-08-30 15:02:48 -07:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void Main(string[] args)
|
|
|
|
|
|
{
|
2016-09-02 13:42:18 -07:00
|
|
|
|
// Perform initial setup and verification
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger = new Logger(true, "romba.log");
|
|
|
|
|
|
InitializeConfiguration();
|
2016-09-22 21:04:41 -07:00
|
|
|
|
DatabaseTools.EnsureDatabase(_dbSchema, _db, _connectionString);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
|
|
|
|
|
|
// If output is being redirected, don't allow clear screens
|
|
|
|
|
|
if (!Console.IsOutputRedirected)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Credits take precidence over all
|
|
|
|
|
|
if ((new List<string>(args)).Contains("--credits"))
|
|
|
|
|
|
{
|
|
|
|
|
|
Build.Credits();
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If there's no arguments, show help
|
|
|
|
|
|
if (args.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Build.Help();
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set all default values
|
|
|
|
|
|
bool help = false,
|
|
|
|
|
|
archive = false,
|
|
|
|
|
|
build = false,
|
2016-10-12 15:40:06 -07:00
|
|
|
|
copy = false,
|
2016-09-02 13:42:18 -07:00
|
|
|
|
dbstats = false,
|
2016-10-17 11:27:50 -07:00
|
|
|
|
depotRescan = false,
|
2016-09-02 13:42:18 -07:00
|
|
|
|
diffdat = false,
|
|
|
|
|
|
dir2dat = false,
|
2016-10-12 16:51:42 -07:00
|
|
|
|
export = false,
|
2016-09-02 13:42:18 -07:00
|
|
|
|
fixdat = false,
|
|
|
|
|
|
lookup = false,
|
|
|
|
|
|
memstats = false,
|
|
|
|
|
|
miss = false,
|
|
|
|
|
|
onlyNeeded = false,
|
|
|
|
|
|
progress = false,
|
|
|
|
|
|
purgeBackup = false,
|
|
|
|
|
|
purgeDelete = false,
|
|
|
|
|
|
refreshDats = false,
|
|
|
|
|
|
shutdown = false;
|
|
|
|
|
|
string newdat ="",
|
|
|
|
|
|
outdat = "";
|
|
|
|
|
|
List<string> inputs = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
// Determine which switches are enabled (with values if necessary)
|
|
|
|
|
|
foreach (string arg in args)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (arg)
|
|
|
|
|
|
{
|
|
|
|
|
|
case "-?":
|
|
|
|
|
|
case "-h":
|
|
|
|
|
|
case "--help":
|
|
|
|
|
|
help = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "archive":
|
|
|
|
|
|
archive = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "build":
|
|
|
|
|
|
build = true;
|
|
|
|
|
|
break;
|
2016-10-12 15:40:06 -07:00
|
|
|
|
case "-copy":
|
|
|
|
|
|
copy = true;
|
|
|
|
|
|
break;
|
2016-09-02 13:42:18 -07:00
|
|
|
|
case "dbstats":
|
|
|
|
|
|
dbstats = true;
|
|
|
|
|
|
break;
|
2016-10-17 11:27:50 -07:00
|
|
|
|
case "depot-rescan":
|
|
|
|
|
|
depotRescan = true;
|
|
|
|
|
|
break;
|
2016-09-02 13:42:18 -07:00
|
|
|
|
case "diffdat":
|
|
|
|
|
|
diffdat = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "dir2dat":
|
|
|
|
|
|
dir2dat = true;
|
|
|
|
|
|
break;
|
2016-10-12 16:51:42 -07:00
|
|
|
|
case "export":
|
|
|
|
|
|
export = true;
|
|
|
|
|
|
break;
|
2016-09-02 13:42:18 -07:00
|
|
|
|
case "fixdat":
|
|
|
|
|
|
fixdat = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "lookup":
|
|
|
|
|
|
lookup = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "memstats":
|
|
|
|
|
|
memstats = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "miss":
|
|
|
|
|
|
miss = true;
|
|
|
|
|
|
break;
|
2016-09-02 14:41:36 -07:00
|
|
|
|
case "-only-needed":
|
|
|
|
|
|
case "--only-needed":
|
|
|
|
|
|
onlyNeeded = true;
|
|
|
|
|
|
break;
|
2016-09-02 13:42:18 -07:00
|
|
|
|
case "purge-backup":
|
|
|
|
|
|
purgeBackup = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "purge-delete":
|
|
|
|
|
|
purgeDelete = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "progress":
|
|
|
|
|
|
progress = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "refresh-dats":
|
|
|
|
|
|
refreshDats = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "shutdown":
|
|
|
|
|
|
shutdown = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
string temparg = arg.Replace("\"", "").Replace("file://", "");
|
|
|
|
|
|
|
|
|
|
|
|
if (temparg.StartsWith("-new=") || temparg.StartsWith("--new="))
|
|
|
|
|
|
{
|
|
|
|
|
|
newdat = temparg.Split('=')[1];
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (temparg.StartsWith("-out=") || temparg.StartsWith("--out="))
|
|
|
|
|
|
{
|
|
|
|
|
|
outdat = temparg.Split('=')[1];
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2016-10-12 14:40:21 -07:00
|
|
|
|
inputs.Add(temparg);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If help is set, show the help screen
|
|
|
|
|
|
if (help)
|
|
|
|
|
|
{
|
|
|
|
|
|
Build.Help();
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If more than one switch is enabled, show the help screen
|
2016-10-17 11:27:50 -07:00
|
|
|
|
if (!(archive ^ build ^ dbstats ^ depotRescan ^ diffdat ^ dir2dat ^ export ^ fixdat ^ lookup ^
|
|
|
|
|
|
memstats ^ miss ^ progress ^ purgeBackup ^ purgeDelete ^ refreshDats ^ shutdown))
|
2016-09-02 13:42:18 -07:00
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Error("Only one feature switch is allowed at a time");
|
2016-09-02 13:42:18 -07:00
|
|
|
|
Build.Help();
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If a switch that requires a filename is set and no file is, show the help screen
|
2016-10-17 11:27:50 -07:00
|
|
|
|
if (inputs.Count == 0 && (archive || build || depotRescan || dir2dat || fixdat || lookup || miss))
|
2016-09-02 13:42:18 -07:00
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Error("This feature requires at least one input");
|
2016-09-02 13:42:18 -07:00
|
|
|
|
Build.Help();
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now take care of each mode in succesion
|
|
|
|
|
|
|
|
|
|
|
|
// Adds ROM files from the specified directories to the ROM archive
|
|
|
|
|
|
if (archive)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitArchive(inputs, onlyNeeded);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// For each specified DAT file it creates the torrentzip files
|
|
|
|
|
|
else if (build)
|
|
|
|
|
|
{
|
2016-10-12 15:40:06 -07:00
|
|
|
|
InitBuild(inputs, copy);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Prints db stats
|
|
|
|
|
|
else if (dbstats)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
DisplayDBStats();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-17 11:27:50 -07:00
|
|
|
|
// Rescan a specific depot
|
|
|
|
|
|
else if (depotRescan)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (string input in inputs)
|
|
|
|
|
|
{
|
|
|
|
|
|
Rescan(input);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-02 13:42:18 -07:00
|
|
|
|
// Creates a DAT file with those entries that are in new DAT
|
|
|
|
|
|
else if (diffdat)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitDiffDat(newdat);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Creates a DAT file for the specified input directory
|
|
|
|
|
|
else if (dir2dat)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitDir2Dat(inputs);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-12 16:51:42 -07:00
|
|
|
|
// Export the database to file
|
|
|
|
|
|
else if (export)
|
|
|
|
|
|
{
|
|
|
|
|
|
ExportDatabase();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-02 13:42:18 -07:00
|
|
|
|
// For each specified DAT file it creates a fix DAT
|
|
|
|
|
|
else if (fixdat)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitFixdat(inputs);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// For each specified hash it looks up any available information
|
|
|
|
|
|
else if (lookup)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitLookup(inputs);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Prints memory stats
|
|
|
|
|
|
else if (memstats)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
DisplayMemoryStats();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// For each specified DAT file it creates a miss file and a have file
|
|
|
|
|
|
else if (miss)
|
|
|
|
|
|
{
|
2016-09-02 13:59:25 -07:00
|
|
|
|
InitMiss(inputs);
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Shows progress of the currently running command
|
|
|
|
|
|
else if (progress)
|
|
|
|
|
|
{
|
2016-09-02 14:08:34 -07:00
|
|
|
|
_logger.User("This feature is not used in RombaSharp: progress");
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Moves DAT index entries for orphaned DATs
|
|
|
|
|
|
else if (purgeBackup)
|
|
|
|
|
|
{
|
2016-09-02 14:08:34 -07:00
|
|
|
|
PurgeBackup();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Deletes DAT index entries for orphaned DATs
|
|
|
|
|
|
else if (purgeDelete)
|
|
|
|
|
|
{
|
2016-09-02 14:08:34 -07:00
|
|
|
|
PurgeDelete();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Refreshes the DAT index from the files in the DAT master directory tree
|
|
|
|
|
|
else if (refreshDats)
|
|
|
|
|
|
{
|
|
|
|
|
|
RefreshDatabase();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Gracefully shuts down server
|
|
|
|
|
|
else if (shutdown)
|
|
|
|
|
|
{
|
2016-09-02 14:08:34 -07:00
|
|
|
|
_logger.User("This feature is not used in RombaSharp: shutdown");
|
2016-09-02 13:42:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If nothing is set, show the help
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Build.Help();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-02 13:59:25 -07:00
|
|
|
|
_logger.Close();
|
2016-09-02 13:42:18 -07:00
|
|
|
|
return;
|
2016-08-30 15:02:48 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|